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:
parent
35a9565808
commit
4eb2926a47
335
fix_grub_bls_cmdline.patch
Normal file
335
fix_grub_bls_cmdline.patch
Normal 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;
|
@ -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>
|
||||
|
||||
|
@ -32,6 +32,8 @@ Patch0: fix_efi_measure_and_shim.patch
|
||||
Patch1: fix_loader_conf.patch
|
||||
# PATCH-FIX-UPSTREAM fix_grub_bls_entry.patch gh#okirch/pcr-oracle!52
|
||||
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: tpm2-0-tss-devel >= 2.4.0
|
||||
Requires: libtss2-tcti-device0
|
||||
|
Loading…
Reference in New Issue
Block a user