Accepting request 1161555 from home:aplanas:branches:Base:System

- Add fix_grub_bls_cmdline.patch to include the measurements of the
  cmdline and the linux and initrd grub commands

OBS-URL: https://build.opensuse.org/request/show/1161555
OBS-URL: https://build.opensuse.org/package/show/Base:System/pcr-oracle?expand=0&rev=30
This commit is contained in:
Alberto Planas 2024-03-25 20:42:46 +00:00 committed by Git OBS Bridge
parent 35a9565808
commit 4eb2926a47
3 changed files with 343 additions and 0 deletions

335
fix_grub_bls_cmdline.patch Normal file
View File

@ -0,0 +1,335 @@
From fca4a51b9aac712b3adc5b6b187cc31a8391bcf6 Mon Sep 17 00:00:00 2001
From: Alberto Planas <aplanas@suse.com>
Date: Fri, 22 Mar 2024 22:44:41 +0100
Subject: [PATCH] GRUB: predict cmdline, linux and initrd lines
Signed-off-by: Alberto Planas <aplanas@suse.com>
---
src/eventlog.c | 195 ++++++++++++++++++++++++++++++++++++++-----------
src/eventlog.h | 26 ++++---
2 files changed, 169 insertions(+), 52 deletions(-)
diff --git a/src/eventlog.c b/src/eventlog.c
index db18f41..727f6a9 100644
--- a/src/eventlog.c
+++ b/src/eventlog.c
@@ -549,14 +549,66 @@ tpm_event_decode_uuid(const unsigned char *data)
return uuid;
}
+/*
+ * For files residing on the EFI partition, grub usually formats these as
+ * (hdX,gptY)/EFI/BOOT/some.file
+ * Once it has determined the final root device, the device part will be
+ * omitted (eg for kernel and initrd).
+ */
+static bool
+__grub_file_parse(grub_file_t *grub_file, const char *value)
+{
+ if (value[0] == '/') {
+ grub_file->device = NULL;
+ grub_file->path = strdup(value);
+ } else if (value[0] == '(') {
+ char *copy = strdup(value);
+ char *path;
+
+ if ((path = strchr(copy, ')')) == NULL) {
+ free(copy);
+ return false;
+ }
+
+ *path++ = '\0';
+
+ grub_file->device = strdup(copy + 1);
+ grub_file->path = strdup(path);
+ free(copy);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static const char *
+__grub_file_join(grub_file_t grub_file)
+{
+ static char path[PATH_MAX];
+
+ if (grub_file.device == NULL)
+ snprintf(path, sizeof(path), "%s", grub_file.path);
+ else
+ snprintf(path, sizeof(path), "(%s)%s", grub_file.device, grub_file.path);
+
+ return path;
+}
+
+static void
+__grub_file_destroy(grub_file_t *grub_file)
+{
+ drop_string(&grub_file->device);
+ drop_string(&grub_file->path);
+}
+
/*
* Handle IPL events, which grub2 and sd-boot uses to hide its stuff in
*/
static void
__tpm_event_grub_file_destroy(tpm_parsed_event_t *parsed)
{
- drop_string(&parsed->grub_file.device);
- drop_string(&parsed->grub_file.path);
+ __grub_file_destroy(&parsed->grub_file);
}
const char *
@@ -564,10 +616,7 @@ __tpm_event_grub_file_describe(const tpm_parsed_event_t *parsed)
{
static char buffer[1024];
- if (parsed->grub_file.device == NULL)
- snprintf(buffer, sizeof(buffer), "grub2 file load from %s", parsed->grub_file.path);
- else
- snprintf(buffer, sizeof(buffer), "grub2 file load from (%s)%s", parsed->grub_file.device, parsed->grub_file.path);
+ snprintf(buffer, sizeof(buffer), "grub2 file load from %s", __grub_file_join(parsed->grub_file));
return buffer;
}
@@ -575,7 +624,7 @@ __tpm_event_grub_file_describe(const tpm_parsed_event_t *parsed)
static const tpm_evdigest_t *
__tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx)
{
- const struct grub_file_event *evspec = &parsed->grub_file;
+ const grub_file_event *evspec = &parsed->grub_file;
const tpm_evdigest_t *md = NULL;
debug(" re-hashing %s\n", __tpm_event_grub_file_describe(parsed));
@@ -606,35 +655,11 @@ __tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pa
return md;
}
-/*
- * For files residing on the EFI partition, grub usually formats these as
- * (hdX,gptY)/EFI/BOOT/some.file
- * Once it has determined the final root device, the device part will be
- * omitted (eg for kernel and initrd).
- */
static bool
__tpm_event_grub_file_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed, const char *value)
{
- if (value[0] == '/') {
- parsed->grub_file.device = NULL;
- parsed->grub_file.path = strdup(value);
- } else if (value[0] == '(') {
- char *copy = strdup(value);
- char *path;
-
- if ((path = strchr(copy, ')')) == NULL) {
- free(copy);
- return false;
- }
-
- *path++ = '\0';
-
- parsed->grub_file.device = strdup(copy + 1);
- parsed->grub_file.path = strdup(path);
- free(copy);
- } else {
+ if (!__grub_file_parse(&parsed->grub_file, value))
return false;
- }
parsed->event_subtype = GRUB_EVENT_FILE;
parsed->destroy = __tpm_event_grub_file_destroy;
@@ -658,21 +683,87 @@ static const char *
__tpm_event_grub_command_describe(const tpm_parsed_event_t *parsed)
{
static char buffer[128];
+ static char *topic = NULL;
+
+ switch (parsed->event_subtype) {
+ case GRUB_EVENT_COMMAND:
+ topic = "grub2 command";
+ break;
+ case GRUB_EVENT_COMMAND_LINUX:
+ topic = "grub2 linux command";
+ break;
+ case GRUB_EVENT_COMMAND_INITRD:
+ topic = "grub2 initrd command";
+ break;
+ case GRUB_EVENT_KERNEL_CMDLINE:
+ topic = "grub2 kernel cmdline";
+ break;
+ }
+
+ snprintf(buffer, sizeof(buffer), "%s \"%s\"", topic, parsed->grub_command.string);
- if (parsed->event_subtype == GRUB_EVENT_COMMAND)
- snprintf(buffer, sizeof(buffer), "grub2 command \"%s\"", parsed->grub_command.string);
- else
- snprintf(buffer, sizeof(buffer), "grub2 kernel cmdline \"%s\"", parsed->grub_command.string);
return buffer;
}
static const tpm_evdigest_t *
__tpm_event_grub_command_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx)
{
- if (parsed->grub_command.string == NULL)
- return NULL;
+ char *str = NULL;
+ size_t sz = 0;
+ const tpm_evdigest_t *digest = NULL;
+ grub_file_t file;
+
+ switch (parsed->event_subtype) {
+ case GRUB_EVENT_COMMAND:
+ str = strdup(parsed->grub_command.string);
+ break;
+ case GRUB_EVENT_COMMAND_LINUX:
+ if (ctx->boot_entry && parsed->grub_command.file.path) {
+ file = (grub_file_t) {
+ .device = parsed->grub_command.file.device,
+ .path = ctx->boot_entry->image_path,
+ };
+ sz = snprintf(NULL, 0, "linux %s %s", __grub_file_join(file), ctx->boot_entry->options);
+ str = malloc(sz + 1);
+ snprintf(str, sz + 1, "linux %s %s", __grub_file_join(file), ctx->boot_entry->options);
+ debug("Hashed linux command: %s\n", str);
+ } else
+ str = strdup(parsed->grub_command.string);
+ break;
+ case GRUB_EVENT_COMMAND_INITRD:
+ if (ctx->boot_entry && parsed->grub_command.file.path) {
+ file = (grub_file_t) {
+ .device = parsed->grub_command.file.device,
+ .path = ctx->boot_entry->initrd_path,
+ };
+ sz = snprintf(NULL, 0, "initrd %s", __grub_file_join(file));
+ str = malloc(sz + 1);
+ snprintf(str, sz + 1, "initrd %s", __grub_file_join(file));
+ debug("Hashed initrd command: %s\n", str);
+ } else
+ str = strdup(parsed->grub_command.string);
+ break;
+ case GRUB_EVENT_KERNEL_CMDLINE:
+ if (ctx->boot_entry && parsed->grub_command.file.path) {
+ file = (grub_file_t) {
+ .device = parsed->grub_command.file.device,
+ .path = ctx->boot_entry->image_path,
+ };
+ sz = snprintf(NULL, 0, "%s %s", __grub_file_join(file), ctx->boot_entry->options);
+ str = malloc(sz + 1);
+ snprintf(str, sz + 1, "%s %s", __grub_file_join(file), ctx->boot_entry->options);
+ debug("Hashed kernel cmdline: %s\n", str);
+ } else
+ str = strdup(parsed->grub_command.string);
+ break;
+ }
+
+ if (str) {
+ digest = digest_compute(ctx->algo, str, strlen(str));
+ free(str);
+ }
- return digest_compute(ctx->algo, parsed->grub_command.string, strlen(parsed->grub_command.string));
+ return digest;
}
/*
@@ -703,15 +794,29 @@ __tpm_event_grub_command_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed
keyword = copy;
arg = copy + wordlen;
+ if (!strcmp(keyword, "grub_cmd") && !strncmp(arg, "linux", strlen("linux"))) {
+ for (wordlen = 0; (cc = arg[wordlen]) && (cc != ' '); ++wordlen)
+ ;
+ if (arg[wordlen] == ' ' && !__grub_file_parse(&parsed->grub_command.file, arg + wordlen + 1))
+ goto failed;
+ parsed->event_subtype = GRUB_EVENT_COMMAND_LINUX;
+ } else
+ if (!strcmp(keyword, "grub_cmd") && !strncmp(arg, "initrd", strlen("initrd"))) {
+ for (wordlen = 0; (cc = arg[wordlen]) && (cc != ' '); ++wordlen)
+ ;
+ if (arg[wordlen] == ' ' && !__grub_file_parse(&parsed->grub_command.file, arg + wordlen + 1))
+ goto failed;
+ parsed->event_subtype = GRUB_EVENT_COMMAND_INITRD;
+ } else
if (!strcmp(keyword, "grub_cmd")) {
parsed->event_subtype = GRUB_EVENT_COMMAND;
} else
if (!strcmp(keyword, "kernel_cmdline")) {
+ if (!__grub_file_parse(&parsed->grub_command.file, arg))
+ goto failed;
parsed->event_subtype = GRUB_EVENT_KERNEL_CMDLINE;
- } else {
- free(copy);
- return false;
- }
+ } else
+ goto failed;
parsed->grub_command.string = strdup(arg);
for (argc = 0, s = strtok(arg, " \t"); s && argc < GRUB_COMMAND_ARGV_MAX - 1; s = strtok(NULL, " \t")) {
@@ -725,6 +830,10 @@ __tpm_event_grub_command_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed
free(copy);
return true;
+
+failed:
+ free(copy);
+ return false;
}
static void
diff --git a/src/eventlog.h b/src/eventlog.h
index d142744..6a8c3a4 100644
--- a/src/eventlog.h
+++ b/src/eventlog.h
@@ -89,10 +89,12 @@ enum {
enum {
/* IPL subtypes for grub */
GRUB_EVENT_COMMAND = 0x0001,
- GRUB_EVENT_FILE = 0x0002,
- GRUB_EVENT_KERNEL_CMDLINE = 0x0003,
- SHIM_EVENT_VARIABLE = 0x0004,
- SYSTEMD_EVENT_VARIABLE = 0x0005,
+ GRUB_EVENT_COMMAND_LINUX = 0x0002,
+ GRUB_EVENT_COMMAND_INITRD = 0x0003,
+ GRUB_EVENT_FILE = 0x0004,
+ GRUB_EVENT_KERNEL_CMDLINE = 0x0005,
+ SHIM_EVENT_VARIABLE = 0x0006,
+ SYSTEMD_EVENT_VARIABLE = 0x0007,
};
enum {
@@ -208,6 +210,13 @@ typedef struct tpm_event_log_rehash_ctx {
#define GRUB_COMMAND_ARGV_MAX 32
+typedef struct grub_file {
+ char * device;
+ char * path;
+} grub_file_t;
+
+typedef grub_file_t grub_file_event;
+
/*
* Parsed event types
*/
@@ -247,13 +256,12 @@ typedef struct tpm_parsed_event {
/* for GRUB_COMMAND, GRUB_KERNEL_CMDLINE */
struct grub_command_event {
char * string;
- char * argv[GRUB_COMMAND_ARGV_MAX];
+ char * argv[GRUB_COMMAND_ARGV_MAX];
+ grub_file_t file;
} grub_command;
- struct grub_file_event {
- char * device;
- char * path;
- } grub_file;
+ /* for GRUB_FILE */
+ grub_file_event grub_file;
struct shim_event {
char * string;

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Mon Mar 25 20:16:53 UTC 2024 - Alberto Planas Dominguez <aplanas@suse.com>
- Add fix_grub_bls_cmdline.patch to include the measurements of the
cmdline and the linux and initrd grub commands
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Mar 14 10:33:23 UTC 2024 - Alberto Planas Dominguez <aplanas@suse.com> Thu Mar 14 10:33:23 UTC 2024 - Alberto Planas Dominguez <aplanas@suse.com>

View File

@ -32,6 +32,8 @@ Patch0: fix_efi_measure_and_shim.patch
Patch1: fix_loader_conf.patch Patch1: fix_loader_conf.patch
# PATCH-FIX-UPSTREAM fix_grub_bls_entry.patch gh#okirch/pcr-oracle!52 # PATCH-FIX-UPSTREAM fix_grub_bls_entry.patch gh#okirch/pcr-oracle!52
Patch2: fix_grub_bls_entry.patch Patch2: fix_grub_bls_entry.patch
# PATCH-FIX-UPSTREAM fix_grub_bls_cmdline.patch gh#okirch/pcr-oracle!52 (cont)
Patch3: fix_grub_bls_cmdline.patch
BuildRequires: libopenssl-devel >= 0.9.8 BuildRequires: libopenssl-devel >= 0.9.8
BuildRequires: tpm2-0-tss-devel >= 2.4.0 BuildRequires: tpm2-0-tss-devel >= 2.4.0
Requires: libtss2-tcti-device0 Requires: libtss2-tcti-device0