]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pcrlock: be more careful when preparing credential name for pcrlock policy 34298/head
authorLennart Poettering <lennart@poettering.net>
Fri, 6 Sep 2024 16:32:17 +0000 (18:32 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 6 Sep 2024 16:55:32 +0000 (18:55 +0200)
The .cred suffix is stripped from a credential as it is imported from
the ESP, hence it should not be included in the credential name embedded
in the credential.

Fixes: #33497
src/pcrlock/pcrlock.c
test/units/TEST-70-TPM2.pcrlock.sh

index 8acddf8a06cd317cb1de6985c1c47e8099b50468..21d83801d98f75fb8224d49954fcd3fd968f1d5b 100644 (file)
@@ -4291,21 +4291,22 @@ static int remove_policy_file(const char *path) {
         return 1;
 }
 
-static int determine_boot_policy_file(char **ret) {
-        _cleanup_free_ char *path = NULL, *fn = NULL, *joined = NULL;
-        sd_id128_t machine_id;
+static int determine_boot_policy_file(char **ret_path, char **ret_credential_name) {
         int r;
 
-        assert(ret);
-
+        _cleanup_free_ char *path = NULL;
         r = get_global_boot_credentials_path(&path);
         if (r < 0)
                 return r;
         if (r == 0) {
-                *ret = NULL;
+                if (ret_path)
+                        *ret_path = NULL;
+                if (ret_credential_name)
+                        *ret_credential_name = NULL;
                 return 0; /* not found! */
         }
 
+        sd_id128_t machine_id;
         r = sd_id128_get_machine(&machine_id);
         if (r < 0)
                 return log_error_errno(r, "Failed to read machine ID: %m");
@@ -4320,28 +4321,48 @@ static int determine_boot_policy_file(char **ret) {
         if (r < 0)
                 return r;
 
-        fn = strjoin("pcrlock.", arg_entry_token, ".cred");
+        _cleanup_free_ char *fn = strjoin("pcrlock.", arg_entry_token, ".cred");
         if (!fn)
                 return log_oom();
 
         if (!filename_is_valid(fn))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name '%s' would not be a valid file name, refusing.", fn);
 
-        joined = path_join(path, fn);
-        if (!joined)
-                return log_oom();
+        _cleanup_free_ char *joined = NULL;
+        if (ret_path) {
+                joined = path_join(path, fn);
+                if (!joined)
+                        return log_oom();
+        }
+
+        _cleanup_free_ char *cn = NULL;
+        if (ret_credential_name) {
+                /* The .cred suffix of the file is stripped when PID 1 imports the credential, hence exclude it from
+                 * the embedded credential name. */
+                cn = strjoin("pcrlock.", arg_entry_token);
+                if (!cn)
+                        return log_oom();
+
+                ascii_strlower(cn); /* lowercase this file, no matter what, since stored on VFAT, and we don't want
+                                     * to run into case change incompatibilities */
+        }
+
+        if (ret_path)
+                *ret_path = TAKE_PTR(joined);
+
+        if (ret_credential_name)
+                *ret_credential_name = TAKE_PTR(cn);
 
-        *ret = TAKE_PTR(joined);
         return 1; /* found! */
 }
 
 static int write_boot_policy_file(const char *json_text) {
-        _cleanup_free_ char *boot_policy_file = NULL;
+        _cleanup_free_ char *boot_policy_file = NULL, *credential_name = NULL;
         int r;
 
         assert(json_text);
 
-        r = determine_boot_policy_file(&boot_policy_file);
+        r = determine_boot_policy_file(&boot_policy_file, &credential_name);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -4349,18 +4370,10 @@ static int write_boot_policy_file(const char *json_text) {
                 return 0;
         }
 
-        _cleanup_free_ char *c = NULL;
-        r = path_extract_filename(boot_policy_file, &c);
-        if (r < 0)
-                return log_error_errno(r, "Failed to extract file name from %s: %m", boot_policy_file);
-
-        ascii_strlower(c); /* lowercase this file, no matter what, since stored on VFAT, and we don't want to
-                            * run into case change incompatibilities */
-
         _cleanup_(iovec_done) struct iovec encoded = {};
         r = encrypt_credential_and_warn(
                         CRED_AES256_GCM_BY_NULL,
-                        c,
+                        credential_name,
                         now(CLOCK_REALTIME),
                         /* not_after= */ USEC_INFINITY,
                         /* tpm2_device= */ NULL,
@@ -4887,7 +4900,7 @@ static int remove_policy(void) {
         }
 
         _cleanup_free_ char *boot_policy_file = NULL;
-        r = determine_boot_policy_file(&boot_policy_file);
+        r = determine_boot_policy_file(&boot_policy_file, /* ret_credential_name= */ NULL);
         if (r == 0)
                 log_info("Did not find XBOOTLDR/ESP partition, not removing boot policy file.");
         else if (r > 0) {
index 72b95897dab007825bd3c4d1f9a24e98ef950658..0bf32e2eac4819038f0edee83d0c444b56d84092 100755 (executable)
@@ -146,7 +146,18 @@ mkdir /tmp/fakexbootldr
 SYSTEMD_XBOOTLDR_PATH=/tmp/fakexbootldr SYSTEMD_RELAX_XBOOTLDR_CHECKS=1 "$SD_PCRLOCK" make-policy --pcr="$PCRS" --force
 mv /var/lib/systemd/pcrlock.json /var/lib/systemd/pcrlock.json.gone
 
-systemd-creds decrypt /tmp/fakexbootldr/loader/credentials/pcrlock.*.cred
+ls -al /tmp/fakexbootldr/loader/credentials
+
+CREDENTIAL_FILE="$(echo /tmp/fakexbootldr/loader/credentials/pcrlock.*.cred)"
+test -f "$CREDENTIAL_FILE"
+
+# Strip dir and .cred suffix from file name.
+CREDENTIAL_NAME=${CREDENTIAL_FILE#/tmp/fakexbootldr/loader/credentials/}
+CREDENTIAL_NAME=${CREDENTIAL_NAME%.cred}
+
+systemd-creds decrypt --name="$CREDENTIAL_NAME" "$CREDENTIAL_FILE"
+ln -s "$CREDENTIAL_FILE" /tmp/fakexbootldr/loader/credentials/"$CREDENTIAL_NAME"
+test -f /tmp/fakexbootldr/loader/credentials/"$CREDENTIAL_NAME"
 
 SYSTEMD_ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY=/tmp/fakexbootldr/loader/credentials systemd-cryptsetup attach pcrlock "$img" - tpm2-device=auto,headless
 systemd-cryptsetup detach pcrlock