mirror of
https://github.com/systemd/systemd.git
synced 2025-02-25 21:57:32 +03:00
pcrlock: be more careful when preparing credential name for pcrlock policy
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
This commit is contained in:
parent
456cd065bf
commit
fc8ddae76b
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user