pcrextend: pass iovecs through the extend helpers

extend_pcr_now(), extend_nvpcr_now() and escape_and_truncate_data() took
a (void *data, size_t) pair, even though both the dispatch layer and
tpm2_{pcr,nvpcr}_extend_bytes() already speak struct iovec. Drop the
pointless deconstruct/reassemble and pass the iovec through directly.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
This commit is contained in:
Paul Meyer
2026-07-28 08:38:22 +02:00
parent f0f3687700
commit 1472ccebe7
+16 -17
View File
@@ -233,21 +233,22 @@ static int determine_banks(Tpm2Context *c, uint32_t target_pcr_mask) {
return 0;
}
static int escape_and_truncate_data(const void *data, size_t size, char **ret) {
static int escape_and_truncate_data(const struct iovec *data, char **ret) {
_cleanup_free_ char *safe = NULL;
assert(data || size == 0);
assert(data);
assert(iovec_is_valid(data));
assert(ret);
if (size > EXTENSION_STRING_SAFE_LIMIT) {
safe = cescape_length(data, EXTENSION_STRING_SAFE_LIMIT);
if (data->iov_len > EXTENSION_STRING_SAFE_LIMIT) {
safe = cescape_length(data->iov_base, EXTENSION_STRING_SAFE_LIMIT);
if (!safe)
return -ENOMEM;
if (!strextend(&safe, "..."))
return -ENOMEM;
} else {
safe = cescape_length(data, size);
safe = cescape_length(data->iov_base, data->iov_len);
if (!safe)
return -ENOMEM;
}
@@ -300,8 +301,7 @@ static int tpm2_context_new_for_measurement(Tpm2Context **ret) {
static int extend_pcr_now(
uint32_t pcr_mask,
const void *data,
size_t size,
const struct iovec *data,
Tpm2UserspaceEventType event) {
_cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
@@ -325,13 +325,13 @@ static int extend_pcr_now(
return log_oom();
_cleanup_free_ char *safe = NULL;
if (escape_and_truncate_data(data, size, &safe) < 0)
if (escape_and_truncate_data(data, &safe) < 0)
return log_oom();
BIT_FOREACH(pcr, pcr_mask) {
log_debug("Measuring '%s' into PCR index %i, banks %s.", safe, pcr, joined_banks);
r = tpm2_pcr_extend_bytes(c, arg_banks, pcr, &IOVEC_MAKE(data, size), /* secret= */ NULL, event, safe);
r = tpm2_pcr_extend_bytes(c, arg_banks, pcr, data, /* secret= */ NULL, event, safe);
if (r < 0)
return log_error_errno(r, "Could not extend PCR: %m");
@@ -348,8 +348,7 @@ static int extend_pcr_now(
static int extend_nvpcr_now(
const char *name,
const void *data,
size_t size,
const struct iovec *data,
Tpm2UserspaceEventType event) {
_cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
@@ -362,7 +361,7 @@ static int extend_nvpcr_now(
return r;
_cleanup_free_ char *safe = NULL;
if (escape_and_truncate_data(data, size, &safe) < 0)
if (escape_and_truncate_data(data, &safe) < 0)
return log_oom();
log_debug("Measuring '%s' into NvPCR index '%s'.", safe, name);
@@ -371,7 +370,7 @@ static int extend_nvpcr_now(
c,
/* session= */ NULL,
name,
&IOVEC_MAKE(data, size),
data,
/* secret= */ NULL,
event,
safe);
@@ -457,13 +456,13 @@ static int vl_method_extend(sd_varlink *link, sd_json_variant *parameters, sd_va
return sd_varlink_error_invalid_parameter_name(link, p.text ? "text" : "data");
if (p.nvpcr) {
r = extend_nvpcr_now(p.nvpcr, extend_iovec->iov_base, extend_iovec->iov_len, p.event_type);
r = extend_nvpcr_now(p.nvpcr, extend_iovec, 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);
r = extend_pcr_now(INDEX_TO_MASK(uint32_t, p.pcr), extend_iovec, p.event_type);
if (r < 0)
return r;
@@ -594,9 +593,9 @@ static int run(int argc, char *argv[]) {
}
if (arg_nvpcr_name)
r = extend_nvpcr_now(arg_nvpcr_name, word, strlen(word), event);
r = extend_nvpcr_now(arg_nvpcr_name, &IOVEC_MAKE(word, strlen(word)), event);
else
r = extend_pcr_now(arg_pcr_mask, word, strlen(word), event);
r = extend_pcr_now(arg_pcr_mask, &IOVEC_MAKE(word, strlen(word)), event);
/* Both extend paths report "TPM cannot be used for this measurement" (no PCR bank, missing crypto,
* no TPM device — see tpm2_context_new_for_measurement()) as -EOPNOTSUPP. Under --graceful we skip
* those rather than fail and block boot. Genuine faults keep their own errno and are never