diff --git a/man/systemd-pcrlock.xml b/man/systemd-pcrlock.xml index 0a80d2488b..dbb59f2e12 100644 --- a/man/systemd-pcrlock.xml +++ b/man/systemd-pcrlock.xml @@ -601,6 +601,15 @@ + + + + Takes a boolean. Defaults to false. Honoured by make-policy and predict. If + true all specified PCRs must be included in the policy otherwise the command returns failure. + + + + diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index f86ae6458d..8ca570a3a3 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -91,6 +91,7 @@ static RecoveryPinMode arg_recovery_pin = RECOVERY_PIN_HIDE; static char *arg_policy_path = NULL; static bool arg_force = false; static BootEntryTokenType arg_entry_token_type = BOOT_ENTRY_TOKEN_AUTO; +static bool arg_strict = false; static char *arg_entry_token = NULL; static bool arg_varlink = false; static bool arg_quiet = false; @@ -3068,6 +3069,7 @@ static int unlink_pcrlock(const char *default_pcrlock_path) { static int event_log_reduce_to_safe_pcrs(EventLog *el, uint32_t *pcrs) { _cleanup_free_ char *dropped = NULL, *kept = NULL; + bool dropped_relevant_pcr = false; assert(el); assert(pcrs); @@ -3110,6 +3112,9 @@ static int event_log_reduce_to_safe_pcrs(EventLog *el, uint32_t *pcrs) { continue; drop: + if (arg_strict) + dropped_relevant_pcr = true; + *pcrs &= ~(UINT32_C(1) << pcr); if (strextendf_with_separator(&dropped, ", ", "%" PRIu32 " (%s)", pcr, tpm2_pcr_index_to_string(pcr)) < 0) @@ -3117,7 +3122,7 @@ static int event_log_reduce_to_safe_pcrs(EventLog *el, uint32_t *pcrs) { } if (dropped) - log_notice("PCRs dropped from protection mask: %s", dropped); + log_full(dropped_relevant_pcr ? LOG_ERR : LOG_NOTICE, "PCRs dropped from protection mask: %s", dropped); else log_debug("No PCRs dropped from protection mask."); @@ -3126,7 +3131,7 @@ static int event_log_reduce_to_safe_pcrs(EventLog *el, uint32_t *pcrs) { else log_notice("No PCRs kept in protection mask."); - return 0; + return dropped_relevant_pcr ? -ENOEXEC : 0; } static int pcr_prediction_add_result( @@ -5503,6 +5508,13 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) { return r; break; + OPTION_LONG("strict", "BOOL", + "Require all PCRs configured via --pcr= included in policy"): + r = parse_boolean_argument("--strict", opts.arg, &arg_strict); + if (r < 0) + return r; + break; + OPTION('q', "quiet", NULL, "Suppress unnecessary output"): arg_quiet = true; break;