From 3083803b5a8a445bf93d74e908b7d8568d092cf3 Mon Sep 17 00:00:00 2001 From: Alberto Planas Date: Wed, 13 Mar 2024 22:57:17 +0100 Subject: [PATCH] GRUB with BLS measure boot entries Signed-off-by: Alberto Planas --- src/eventlog.c | 11 +++++++++-- src/eventlog.h | 2 ++ src/oracle.c | 9 ++++++--- src/sd-boot.c | 9 +++++++++ src/sd-boot.h | 1 + src/uapi.h | 3 ++- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/eventlog.c b/src/eventlog.c index 3574a4d..b7b4205 100644 --- a/src/eventlog.c +++ b/src/eventlog.c @@ -33,6 +33,7 @@ #include "digest.h" #include "util.h" #include "uapi.h" +#include "sd-boot.h" #define TPM_EVENT_LOG_MAX_ALGOS 64 @@ -582,8 +583,14 @@ __tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pa debug(" assuming the file resides on system partition\n"); md = runtime_digest_rootfs_file(ctx->algo, evspec->path); } else { - debug(" assuming the file resides on EFI boot partition\n"); - md = runtime_digest_efi_file(ctx->algo, evspec->path); + if (sdb_is_boot_entry(evspec->path) && ctx->boot_entry) { + debug(" getting different boot entry file from EFI boot partition: %s\n", + ctx->boot_entry_path); + md = runtime_digest_rootfs_file(ctx->algo, ctx->boot_entry_path); + } else { + debug(" assuming the file resides on EFI boot partition\n"); + md = runtime_digest_efi_file(ctx->algo, evspec->path); + } } return md; diff --git a/src/eventlog.h b/src/eventlog.h index 8af5eb0..b471031 100644 --- a/src/eventlog.h +++ b/src/eventlog.h @@ -21,6 +21,7 @@ #ifndef EVENTLOG_H #define EVENTLOG_H +#include #include "types.h" typedef struct tpm_event { @@ -202,6 +203,7 @@ typedef struct tpm_event_log_rehash_ctx { const pecoff_image_info_t *next_stage_img; /* This get set when the user specifies --next-kernel */ + char boot_entry_path[PATH_MAX]; uapi_boot_entry_t * boot_entry; } tpm_event_log_rehash_ctx_t; diff --git a/src/oracle.c b/src/oracle.c index 0afd910..155ec59 100644 --- a/src/oracle.c +++ b/src/oracle.c @@ -663,9 +663,12 @@ predictor_update_eventlog(struct predictor *pred) * systemd ID of the next kernel entry to be booted. * FIXME: we should probably hide this behind a target_platform function. */ - if (pred->boot_entry_id != NULL - && !(rehash_ctx.boot_entry = sdb_identify_boot_entry(pred->boot_entry_id))) - fatal("unable to identify next kernel \"%s\"\n", pred->boot_entry_id); + if (pred->boot_entry_id != NULL) { + snprintf(rehash_ctx.boot_entry_path, sizeof(rehash_ctx.boot_entry_path), + "%s/%s", UAPI_BOOT_DIRECTORY, pred->boot_entry_id); + if (!(rehash_ctx.boot_entry = sdb_identify_boot_entry(pred->boot_entry_id))) + fatal("unable to identify next kernel \"%s\"\n", pred->boot_entry_id); + } for (ev = pred->event_log; ev; ev = ev->next) { tpm_evdigest_t *pcr; diff --git a/src/sd-boot.c b/src/sd-boot.c index ede2569..4c3a692 100644 --- a/src/sd-boot.c +++ b/src/sd-boot.c @@ -160,6 +160,15 @@ sdb_is_kernel(const char *application) return (found == 3); } +bool +sdb_is_boot_entry(const char *application) +{ + if (!application) + return false; + + return !strncmp(application, UAPI_BOOT_DIRECTORY_EFI, sizeof(UAPI_BOOT_DIRECTORY_EFI) - 1); +} + /* * Identify the next kernel and initrd given an ID */ diff --git a/src/sd-boot.h b/src/sd-boot.h index 0472320..ca1be6f 100644 --- a/src/sd-boot.h +++ b/src/sd-boot.h @@ -44,6 +44,7 @@ typedef struct sdb_entry_list { extern uapi_boot_entry_t * sdb_identify_boot_entry(const char *id); extern bool sdb_is_kernel(const char *application); +extern bool sdb_is_boot_entry(const char *application); /* This will have to update the systemd json file, and add a new entry. */ extern bool sdb_policy_file_add_entry(const char *filename, diff --git a/src/uapi.h b/src/uapi.h index 96ca7ed..8bcb94f 100644 --- a/src/uapi.h +++ b/src/uapi.h @@ -41,7 +41,8 @@ typedef struct uapi_kernel_entry_tokens { char * entry_token[UAPI_MAX_ENTRY_TOKENS]; } uapi_kernel_entry_tokens_t; -#define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries" +#define UAPI_BOOT_DIRECTORY_EFI "/loader/entries" +#define UAPI_BOOT_DIRECTORY "/boot/efi" UAPI_BOOT_DIRECTORY_EFI extern uapi_boot_entry_t * uapi_get_boot_entry(const char *id); extern uapi_boot_entry_t * uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id);