From: dongshengyuan <545258830@qq.com> Date: Wed, 24 Jun 2026 11:57:04 +0000 (+0800) Subject: pcrextend,tpm2-util,tpm2-setup: gracefully skip NvPCR when TPM NV space is exhausted X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=be8a7b418a3493ecaa1b7f36abcbd8685aa2931d;p=thirdparty%2Fsystemd.git pcrextend,tpm2-util,tpm2-setup: gracefully skip NvPCR when TPM NV space is exhausted Map TPM2_RC_NV_SPACE to -ENOBUFS in tpm2_define_nvpcr_nv_index() rather than -ENOSPC, giving it a dedicated errno distinct from the -ENOSPC that write_string_file_at() can return when /run is full — a different failure that occurs after the NV index is already allocated on the TPM. In extend_nvpcr_now(), propagate -ENOBUFS as-is so callers can handle it in a nicer fashion. In vl_method_extend(), map it to the new varlink error io.systemd.PCRExtend.NvPCRSpaceExhausted. In run(), handle -ENOBUFS explicitly under --graceful and print an appropriate message. Update tpm2-setup.c accordingly. Fixes #42725 Signed-off-by: dongshengyuan --- diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c index 067cc92ff39..782f8632726 100644 --- a/src/pcrextend/pcrextend.c +++ b/src/pcrextend/pcrextend.c @@ -382,6 +382,8 @@ static int extend_nvpcr_now( return r; r = tpm2_nvpcr_initialize(c, /* session= */ NULL, name, &anchor_secret); + if (r == -ENOBUFS) + return r; /* NV space exhausted; let caller handle gracefully */ if (r < 0) return log_error_errno(r, "Failed to extend NvPCR index '%s' with anchor secret: %m", name); @@ -470,6 +472,8 @@ static int vl_method_extend(sd_varlink *link, sd_json_variant *parameters, sd_va r = extend_nvpcr_now(p.nvpcr, extend_iovec->iov_base, extend_iovec->iov_len, p.event_type); if (IN_SET(r, -ENOENT, -ENODEV)) return sd_varlink_error(link, "io.systemd.PCRExtend.NoSuchNvPCR", NULL); + if (r == -ENOBUFS) + return sd_varlink_error(link, "io.systemd.PCRExtend.NvPCRSpaceExhausted", NULL); } else r = extend_pcr_now(INDEX_TO_MASK(uint32_t, p.pcr), extend_iovec->iov_base, extend_iovec->iov_len, p.event_type); if (r < 0) @@ -609,6 +613,10 @@ static int run(int argc, char *argv[]) { log_notice_errno(r, "TPM2 cannot be used for measurement (no usable PCR bank, missing device, or missing crypto support), skipping gracefully."); return EXIT_SUCCESS; } + if (arg_graceful && r == -ENOBUFS) { + log_notice_errno(r, "TPM NV index space is exhausted, NvPCR '%s' could not be initialized, skipping gracefully.", arg_nvpcr_name); + return EXIT_SUCCESS; + } if (r < 0) return r; diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index f0e86ad3640..3a9fbaa7e47 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -7235,7 +7235,7 @@ static int tpm2_define_nvpcr_nv_index( &public_info, &new_handle->esys_handle); if (rc == TPM2_RC_NV_SPACE) - return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), + return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS), "NV index space on TPM exhausted, cannot allocate NvPCR."); if (rc == TPM2_RC_NV_DEFINED) { log_debug("NV index 0x%" PRIu32 " already registered.", nv_index); diff --git a/src/shared/varlink-io.systemd.PCRExtend.c b/src/shared/varlink-io.systemd.PCRExtend.c index d309330f405..cf42bf96246 100644 --- a/src/shared/varlink-io.systemd.PCRExtend.c +++ b/src/shared/varlink-io.systemd.PCRExtend.c @@ -29,6 +29,7 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_DEFINE_INPUT_BY_TYPE(eventType, EventType, SD_VARLINK_NULLABLE)); static SD_VARLINK_DEFINE_ERROR(NoSuchNvPCR); +static SD_VARLINK_DEFINE_ERROR(NvPCRSpaceExhausted); SD_VARLINK_DEFINE_INTERFACE( io_systemd_PCRExtend, @@ -38,4 +39,6 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_Extend, SD_VARLINK_SYMBOL_COMMENT("Event type to store in event log"), &vl_type_EventType, - &vl_error_NoSuchNvPCR); + &vl_error_NoSuchNvPCR, + SD_VARLINK_SYMBOL_COMMENT("Space for NV indexes/NvPCRs exhausted, cannot measure."), + &vl_error_NvPCRSpaceExhausted); diff --git a/src/tpm2-setup/tpm2-setup.c b/src/tpm2-setup/tpm2-setup.c index bb87cd902f7..86cfdb5d284 100644 --- a/src/tpm2-setup/tpm2-setup.c +++ b/src/tpm2-setup/tpm2-setup.c @@ -423,7 +423,7 @@ static int setup_nvpcr_one( LOG_MESSAGE("The TPM does not correctly support NV indexes in NT_EXTEND mode, unable to allocate NvPCR '%s': %m", name), LOG_MESSAGE_ID(SD_MESSAGE_TPM_NVPCR_UNSUPPORTED_STR)); } - if (r == -ENOSPC) { + if (r == -ENOBUFS) { /* The TPM's NV index space is exhausted. Remember this so we skip the remaining (less * important) NvPCRs, and report it gracefully at the end rather than failing the boot. * Logged at notice level, not error. */ @@ -549,7 +549,7 @@ static int setup_nvpcr(void) { * SuccessExitStatus= in the service unit file. */ if (ret == -EOPNOTSUPP) return EX_UNAVAILABLE; /* e.g. no NvPCR support in TPM */ - if (ret == -ENOSPC) + if (ret == -ENOBUFS) return EX_CANTCREAT; /* NV index space on TPM exhausted */ return ret;