diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2024-10-21 18:55:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-21 18:55:33 +0200 |
commit | e8fb0643c1bea626d5f5e880c3338f32705fd46d (patch) | |
tree | d534e34c6f6262e044d78ee2654cf1ac0a9f0d83 /src | |
parent | machine: rework Operation logic to reuse in varlink interface (diff) | |
parent | Rework TEST-86-MULTI-PROFILE-UKI (diff) | |
download | systemd-e8fb0643c1bea626d5f5e880c3338f32705fd46d.tar.xz systemd-e8fb0643c1bea626d5f5e880c3338f32705fd46d.zip |
Merge pull request #34628 from DaanDeMeyer/measure
Rework TEST-86-MULTI-PROFILE-UKI + associated bugfixes
Diffstat (limited to 'src')
-rw-r--r-- | src/boot/measure.c | 33 | ||||
-rw-r--r-- | src/cryptenroll/cryptenroll-tpm2.c | 2 | ||||
-rw-r--r-- | src/pcrlock/pehash.c | 16 |
3 files changed, 48 insertions, 3 deletions
diff --git a/src/boot/measure.c b/src/boot/measure.c index 36d42147a1..f2d644ff03 100644 --- a/src/boot/measure.c +++ b/src/boot/measure.c @@ -16,6 +16,7 @@ #include "openssl-util.h" #include "parse-argument.h" #include "parse-util.h" +#include "pe-binary.h" #include "pretty-print.h" #include "sha256.h" #include "strv.h" @@ -517,6 +518,38 @@ static int measure_kernel(PcrState *pcr_states, size_t n) { m += sz; } + if (c == UNIFIED_SECTION_LINUX) { + _cleanup_free_ PeHeader *pe_header = NULL; + + r = pe_load_headers(fd, /*ret_dos_header=*/ NULL, &pe_header); + if (r < 0) + log_warning_errno(r, "Failed to parse kernel image file '%s', ignoring: %m", arg_sections[c]); + else if (m < pe_header->optional.SizeOfImage) { + memzero(buffer, BUFFER_SIZE); + + /* Our EFI stub measures VirtualSize bytes of the .linux section into PCR 11. + * Notably, VirtualSize can be larger than the section's size on disk. In + * that case the extra space is initialized with zeros, so the stub ends up + * measuring a bunch of zeros. To accomodate this, we have to measure the + * same number of zeros here. We opt to measure extra zeros here instead of + * modifying the stub to only measure the number of bytes on disk as we want + * newer ukify + systemd-measure to work with older versions of the stub and + * as of 6.12 the kernel image's VirtualSize won't be larger than its size on + * disk anymore (see https://github.com/systemd/systemd/issues/34578#issuecomment-2382459515). + */ + + while (m < pe_header->optional.SizeOfImage) { + uint64_t sz = MIN(BUFFER_SIZE, pe_header->optional.SizeOfImage - m); + + for (size_t i = 0; i < n; i++) + if (EVP_DigestUpdate(mdctx[i], buffer, sz) != 1) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest."); + + m += sz; + } + } + } + fd = safe_close(fd); if (m == 0) /* We skip over empty files, the stub does so too */ diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index d58194fb85..ca163ef3c2 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -78,8 +78,6 @@ static int search_policy_hash( j++; } - assert(j == n_policy_hash); - if (match) /* Found entry with the exact same set of hashes */ return keyslot; } diff --git a/src/pcrlock/pehash.c b/src/pcrlock/pehash.c index 06d1f6afc7..7e9dade1f7 100644 --- a/src/pcrlock/pehash.c +++ b/src/pcrlock/pehash.c @@ -216,10 +216,24 @@ int uki_hash(int fd, if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest."); - r = hash_file(fd, mdctx, section->PointerToRawData, section->VirtualSize); + r = hash_file(fd, mdctx, section->PointerToRawData, MIN(section->VirtualSize, section->SizeOfRawData)); if (r < 0) return r; + if (section->SizeOfRawData < section->VirtualSize) { + uint8_t zeroes[1024] = {}; + size_t remaining = section->VirtualSize - section->SizeOfRawData; + + while (remaining > 0) { + size_t sz = MIN(sizeof(zeroes), remaining); + + if (EVP_DigestUpdate(mdctx, zeroes, sz) != 1) + return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data."); + + remaining -= sz; + } + } + hashes[i] = malloc(hsz); if (!hashes[i]) return log_oom_debug(); |