diff --git a/_service b/_service index 6dac258..839a19f 100644 --- a/_service +++ b/_service @@ -7,7 +7,7 @@ https://github.com/okirch/pcr-oracle.git pcr-oracle @PARENT_TAG@ - refs/tags/0.5.3 + refs/tags/0.5.4 pcr-oracle*.tar diff --git a/boot_entry.patch b/boot_entry.patch deleted file mode 100644 index f7430a1..0000000 --- a/boot_entry.patch +++ /dev/null @@ -1,2093 +0,0 @@ -From 0be3db467f042cc030f9a4a840854ce36a0f8317 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 16:48:28 +0100 -Subject: [PATCH 01/13] Remove obsolete pcr_policy_sign_systemd() - -Signed-off-by: Olaf Kirch ---- - src/pcr-policy.c | 51 ------------------------------------------------ - src/pcr.h | 3 --- - 2 files changed, 54 deletions(-) - -diff --git a/src/pcr-policy.c b/src/pcr-policy.c -index 95a4299..8f2c42c 100644 ---- a/src/pcr-policy.c -+++ b/src/pcr-policy.c -@@ -1539,57 +1539,6 @@ pcr_unseal_secret(const target_platform_t *platform, - return platform->unseal_secret(input_path, output_path, pcr_selection, signed_policy_path, public_key_file); - } - --bool --pcr_policy_sign_systemd(const tpm_pcr_bank_t *bank, -- const stored_key_t *private_key_file, -- const char *output_path) --{ -- bool ok = false; -- FILE *fp = NULL; -- tpm_rsa_key_t *rsa_key = NULL; -- const tpm_evdigest_t *digest; -- ESYS_CONTEXT *esys_context = tss_esys_context(); -- TPM2B_DIGEST *pcr_policy = NULL; -- TPMT_SIGNATURE *signed_policy = NULL; -- -- if (!(fp = fopen(output_path, "w"))) { -- error("Cannot open systemd JSON file %s: %m\n", output_path); -- goto out; -- } -- -- if (!(rsa_key = stored_key_read_rsa_private(private_key_file))) -- goto out; -- digest = tpm_rsa_key_public_digest(rsa_key); -- -- if (!(pcr_policy = __pcr_policy_make(esys_context, bank))) -- goto out; -- -- if (!__pcr_policy_sign(rsa_key, pcr_policy, &signed_policy)) -- goto out; -- -- fprintf(fp, "{\n"); -- fprintf(fp, "\t\"%s\": [\n", bank->algo_name); -- fprintf(fp, "\t\t\{\n"); -- fprintf(fp, "\t\t\t\"pcrs\": [\n"); -- fprintf(fp, "\t\t\t\t%s\n", print_pcr_mask(bank->pcr_mask)); -- fprintf(fp, "\t\t\t],\n"); -- fprintf(fp, "\t\t\t\"pkfp\": \"%s\",\n", print_hex_string(digest->data, digest->size)); -- fprintf(fp, "\t\t\t\"pol\": \"%s\",\n", print_hex_string(pcr_policy->buffer, pcr_policy->size)); -- fprintf(fp, "\t\t\t\"sig\": \"%s\"\n", print_base64_value(signed_policy->signature.rsassa.sig.buffer, signed_policy->signature.rsassa.sig.size)); -- fprintf(fp, "\t\t}\n"); -- fprintf(fp, "\t]\n"); -- fprintf(fp, "}\n"); -- -- ok = true; -- --out: -- if (rsa_key) -- tpm_rsa_key_free(rsa_key); -- -- fclose(fp); -- return ok; --} -- - /* - * Depending on the target platform, sealed data, authorized policies etc are - * written to different types of files. -diff --git a/src/pcr.h b/src/pcr.h -index 1b0f544..4d8f816 100644 ---- a/src/pcr.h -+++ b/src/pcr.h -@@ -65,9 +65,6 @@ extern bool pcr_policy_sign(const target_platform_t *platform, const tpm_pcr_ba - const stored_key_t *private_key_file, - const char *input_path, - const char *output_path, const char *policy_name); --extern bool pcr_policy_sign_systemd(const tpm_pcr_bank_t *bank, -- const stored_key_t *private_key_file, -- const char *output_path); - extern bool pcr_authorized_policy_seal_secret(const target_platform_t *platform, - const char *authorized_policy, const char *input_path, - const char *output_path); - -From 3a66b6e1dc953ac95a715a4b1123e772024fba2c Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 17:18:14 +0100 -Subject: [PATCH 02/13] Introduce read_single_line_file() and use it in - sd-boot.c - -Signed-off-by: Olaf Kirch ---- - src/sd-boot.c | 30 ++---------------------------- - src/util.c | 19 +++++++++++++++++++ - src/util.h | 1 + - 3 files changed, 22 insertions(+), 28 deletions(-) - -diff --git a/src/sd-boot.c b/src/sd-boot.c -index 3eea1a1..bbdb498 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -37,21 +37,8 @@ static const char * - read_entry_token(void) - { - static char id[SDB_LINE_MAX]; -- FILE *fp; -- -- if (!(fp = fopen("/etc/kernel/entry-token", "r"))) { -- debug("Cannot open /etc/kernel/entry-token\n"); -- goto fail; -- } -- -- if (fgets(id, SDB_LINE_MAX, fp)) -- id[strcspn(id, "\n")] = 0; - -- fclose(fp); -- return id; -- --fail: -- return NULL; -+ return read_single_line_file("/etc/kernel/entry-token", id, sizeof(id)); - } - - static const char * -@@ -109,21 +96,8 @@ static const char * - read_machine_id(void) - { - static char id[SDB_LINE_MAX]; -- FILE *fp; -- -- if (!(fp = fopen("/etc/machine-id", "r"))) { -- error("Cannot open /etc/machine_id: %m\n"); -- goto fail; -- } -- -- if (fgets(id, SDB_LINE_MAX, fp)) -- id[strcspn(id, "\n")] = 0; - -- fclose(fp); -- return id; -- --fail: -- return NULL; -+ return read_single_line_file("/etc/machine-id", id, sizeof(id)); - } - - static bool -diff --git a/src/util.c b/src/util.c -index 1f2640f..644d138 100644 ---- a/src/util.c -+++ b/src/util.c -@@ -514,3 +514,22 @@ path_has_file_extension(const char *path, const char *suffix) - - return !strcasecmp(path + n, suffix); - } -+ -+const char * -+read_single_line_file(const char *path, char *buffer, size_t size) -+{ -+ FILE *fp; -+ -+ if (!(fp = fopen(path, "r"))) { -+ debug("Cannot open %s: %m\n", path); -+ return NULL; -+ } -+ -+ if (fgets(buffer, size, fp) != NULL) -+ buffer[strcspn(buffer, "\n")] = 0; -+ else -+ buffer[0] = '\0'; -+ -+ fclose(fp); -+ return buffer; -+} -diff --git a/src/util.h b/src/util.h -index c98017f..e63ef16 100644 ---- a/src/util.h -+++ b/src/util.h -@@ -142,6 +142,7 @@ extern double timing_since(double); - extern const char * path_unix2dos(const char *path); - extern const char * path_dos2unix(const char *path); - extern bool path_has_file_extension(const char *path, const char *suffix); -+extern const char * read_single_line_file(const char *path, char *buffer, size_t size); - - extern int version_string_compare(const char *, const char *); - - -From 32680d9efa0b866bd78d7ad5bd362aca511efc05 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 18:26:36 +0100 -Subject: [PATCH 03/13] tpm_event_get_digest: changed second argument from - algo_name to an algo_info pointer - -Signed-off-by: Olaf Kirch ---- - src/efi-application.c | 2 +- - src/efi-variable.c | 6 +++--- - src/eventlog.c | 6 +----- - src/eventlog.h | 2 +- - src/oracle.c | 2 +- - 5 files changed, 7 insertions(+), 11 deletions(-) - -diff --git a/src/efi-application.c b/src/efi-application.c -index 14a2450..06ac9ff 100644 ---- a/src/efi-application.c -+++ b/src/efi-application.c -@@ -287,7 +287,7 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars - */ - if (!evspec->efi_application) { - debug("Unable to locate boot service application - probably not a file\n"); -- return tpm_event_get_digest(ev, ctx->algo->openssl_name); -+ return tpm_event_get_digest(ev, ctx->algo); - } - - /* The next boot can have a different kernel */ -diff --git a/src/efi-variable.c b/src/efi-variable.c -index 7e9e38b..6c08cde 100644 ---- a/src/efi-variable.c -+++ b/src/efi-variable.c -@@ -141,7 +141,7 @@ __tpm_event_efi_variable_detect_hash_strategy(const tpm_event_t *ev, const tpm_p - { - const tpm_evdigest_t *md, *old_md; - -- old_md = tpm_event_get_digest(ev, algo->openssl_name); -+ old_md = tpm_event_get_digest(ev, algo); - if (old_md == NULL) { - debug("Event does not provide a digest for algorithm %s\n", algo->openssl_name); - return -1; -@@ -199,7 +199,7 @@ __tpm_event_efi_variable_rehash(const tpm_event_t *ev, const tpm_parsed_event_t - * For the time being, just pretend these cannot be changed from - * within the running system. - */ -- md = tpm_event_get_digest(ev, algo->openssl_name); -+ md = tpm_event_get_digest(ev, algo); - goto out; - } - } else { -@@ -214,7 +214,7 @@ __tpm_event_efi_variable_rehash(const tpm_event_t *ev, const tpm_parsed_event_t - /* The content of the variable doesn't exist during the measurement - * and is also not available at runtime. Let's skip this event. - */ -- md = tpm_event_get_digest(ev, algo->openssl_name); -+ md = tpm_event_get_digest(ev, algo); - } - goto out; - } -diff --git a/src/eventlog.c b/src/eventlog.c -index e99a20f..32cc75c 100644 ---- a/src/eventlog.c -+++ b/src/eventlog.c -@@ -406,14 +406,10 @@ tpm_event_type_to_string(unsigned int event_type) - } - - const tpm_evdigest_t * --tpm_event_get_digest(const tpm_event_t *ev, const char *algo_name) -+tpm_event_get_digest(const tpm_event_t *ev, const tpm_algo_info_t *algo_info) - { -- const tpm_algo_info_t *algo_info; - unsigned int i; - -- if ((algo_info = digest_by_name(algo_name)) < 0) -- fatal("Unknown algo name \"%s\"\n", algo_name); -- - for (i = 0; i < ev->pcr_count; ++i) { - const tpm_evdigest_t *md = &ev->pcr_values[i]; - -diff --git a/src/eventlog.h b/src/eventlog.h -index 8951765..bd1106f 100644 ---- a/src/eventlog.h -+++ b/src/eventlog.h -@@ -291,7 +291,7 @@ extern void tpm_event_log_scan_ctx_init(tpm_event_log_scan_ctx_t *); - extern void tpm_event_log_scan_ctx_destroy(tpm_event_log_scan_ctx_t *); - extern tpm_parsed_event_t * tpm_event_parse(tpm_event_t *ev, tpm_event_log_scan_ctx_t *); - extern const char * tpm_event_type_to_string(unsigned int event_type); --extern const tpm_evdigest_t * tpm_event_get_digest(const tpm_event_t *ev, const char *algo_name); -+extern const tpm_evdigest_t * tpm_event_get_digest(const tpm_event_t *ev, const tpm_algo_info_t *algo_info); - extern void tpm_parsed_event_print(tpm_parsed_event_t *parsed, - tpm_event_bit_printer *); - extern const char * tpm_parsed_event_describe(tpm_parsed_event_t *parsed); -diff --git a/src/oracle.c b/src/oracle.c -index 52fe261..c4e4873 100644 ---- a/src/oracle.c -+++ b/src/oracle.c -@@ -670,7 +670,7 @@ predictor_update_eventlog(struct predictor *pred) - debug("\n"); - __tpm_event_print(ev, debug); - -- if (!(old_digest = tpm_event_get_digest(ev, pred->algo))) -+ if (!(old_digest = tpm_event_get_digest(ev, pred->algo_info))) - fatal("Event log lacks a hash for digest algorithm %s\n", pred->algo); - - if (false) { - -From 4d88450e9da882c759a68ba8c15267b22a377cdc Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 18:31:42 +0100 -Subject: [PATCH 04/13] Add uapi_ types and functions for dealing with UAPI - boot entries - -Signed-off-by: Olaf Kirch ---- - Makefile.in | 3 +- - src/types.h | 1 + - src/uapi.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/uapi.h | 43 +++++++ - 4 files changed, 369 insertions(+), 1 deletion(-) - create mode 100644 src/uapi.c - create mode 100644 src/uapi.h - -diff --git a/Makefile.in b/Makefile.in -index a0508e9..02a915b 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -33,7 +33,8 @@ ORACLE_SRCS = oracle.c \ - bufparser.c \ - store.c \ - util.c \ -- sd-boot.c -+ sd-boot.c \ -+ uapi.c - ORACLE_OBJS = $(addprefix build/,$(patsubst %.c,%.o,$(ORACLE_SRCS))) - - all: $(TOOLS) $(MANPAGES) -diff --git a/src/types.h b/src/types.h -index e76903a..5b01079 100644 ---- a/src/types.h -+++ b/src/types.h -@@ -35,6 +35,7 @@ typedef struct pecoff_image_info pecoff_image_info_t; - typedef struct testcase testcase_t; - typedef struct stored_key stored_key_t; - typedef struct target_platform target_platform_t; -+typedef struct uapi_boot_entry uapi_boot_entry_t; - - #endif /* TYPES_H */ - -diff --git a/src/uapi.c b/src/uapi.c -new file mode 100644 -index 0000000..bbcaea9 ---- /dev/null -+++ b/src/uapi.c -@@ -0,0 +1,323 @@ -+/* -+ * Copyright (C) 2022, 2023 SUSE LLC -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * Written by Alberto Planas , Olaf Kirch -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "uapi.h" -+#include "util.h" -+ -+#define UAPI_LINE_MAX 1024 -+ -+ -+static int vercmp(const void *va, const void *vb); -+ -+static uapi_boot_entry_t * -+uapi_boot_entry_new(void) -+{ -+ uapi_boot_entry_t *ube; -+ -+ ube = calloc(1, sizeof(*ube)); -+ return ube; -+} -+ -+static void -+drop_boot_entry(uapi_boot_entry_t **entry_p) -+{ -+ if (*entry_p) { -+ uapi_boot_entry_free(*entry_p); -+ *entry_p = NULL; -+ } -+} -+ -+static uapi_boot_entry_t * -+uapi_boot_entry_load(const char *path) -+{ -+ uapi_boot_entry_t *result = NULL; -+ char line[UAPI_LINE_MAX]; -+ FILE *fp; -+ -+ if (!(fp = fopen(path, "r"))) { -+ error("Unable to open %s: %m\n", path); -+ return NULL; -+ } -+ -+ result = uapi_boot_entry_new(); -+ while (fgets(line, sizeof(line), fp)) { -+ char *key, *value; -+ unsigned int i; -+ -+ if (!isalpha(line[0])) -+ continue; -+ -+ /* strip white space off the end */ -+ i = strlen(line); -+ while (i > 0 && isspace(line[i-1])) -+ line[--i] = '\0'; -+ -+ key = line; -+ for (i = 0; line[i]; ++i) { -+ if (isspace(line[i])) { -+ line[i++] = '\0'; -+ break; -+ } -+ } -+ -+ while (isspace(line[i])) -+ ++i; -+ value = line + i; -+ if (*value == '\0') -+ value = NULL; -+ -+ if (!strcmp("sort-key", key)) -+ assign_string(&result->sort_key, value); -+ else -+ if (!strcmp("machine-id", key)) -+ assign_string(&result->machine_id, value); -+ else -+ if (!strcmp("version", key)) -+ assign_string(&result->version, value); -+ else -+ if (!strcmp("options", key)) -+ assign_string(&result->options, value); -+ else -+ if (!strcmp("linux", key)) -+ assign_string(&result->image_path, value); -+ else -+ if (!strcmp("initrd", key)) -+ assign_string(&result->initrd_path, value); -+ } -+ -+ fclose(fp); -+ return result; -+} -+ -+static bool -+uapi_boot_entry_applies(const uapi_boot_entry_t *entry, const char *machine_id, const char *architecture) -+{ -+ if (entry->machine_id && machine_id && strcmp(entry->machine_id, machine_id)) -+ return false; -+ if (entry->architecture && architecture && strcmp(entry->architecture, architecture)) -+ return false; -+ /* We don't check the efi key because it can only express "entry is EFI only"; it cannot express -+ * "this is a legacy BIOS entry" */ -+ return true; -+} -+ -+/* -+ * Returns true iff entry_a is "more recent" or "better" than entry_b -+ */ -+static bool -+uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_entry_t *entry_b) -+{ -+ int r = 0; -+ -+ /* having a sort key is better than not having one. */ -+ r = strcmp(entry_a->sort_key? : "", entry_b->sort_key? : ""); -+ -+ if (r == 0) -+ r = vercmp(entry_a->version? : "", entry_b->version? : ""); -+ -+ return r > 0; -+} -+ -+/* -+ * We pass in a best_ret pointer in case we need to extend this -+ * to search more than on directory -+ */ -+uapi_boot_entry_t * -+uapi_find_matching_boot_entry(const char *dir_path, -+ const char *entry_id, const char *machine_id, const char *architecture, -+ uapi_boot_entry_t **best_ret) -+{ -+ uapi_boot_entry_t *best = *best_ret; -+ unsigned int entry_id_len = 0; -+ struct dirent *d; -+ DIR *dir; -+ -+ if (!(dir = opendir(dir_path))) { -+ if (errno != ENOENT) -+ error("Cannot open %s for reading: %m\n", dir_path); -+ return NULL; -+ } -+ -+ if (entry_id) -+ entry_id_len = strlen(entry_id); -+ -+ while ((d = readdir(dir)) != NULL) { -+ char config_path[PATH_MAX]; -+ uapi_boot_entry_t *entry; -+ -+ if (d->d_type != DT_REG) -+ continue; -+ -+ if (entry_id && strncmp(d->d_name, entry_id, entry_id_len)) -+ continue; -+ -+ snprintf(config_path, sizeof(config_path), "%s/%s", dir_path, d->d_name); -+ if (!(entry = uapi_boot_entry_load(config_path))) { -+ warning("Unable to process UAPI boot entry file at \"%s\"\n", config_path); -+ continue; -+ } -+ -+ if (uapi_boot_entry_applies(entry, machine_id, architecture)) { -+ if (best == NULL || uapi_boot_entry_more_recent(entry, best)) { -+ /* swap best and entry */ -+ uapi_boot_entry_t *tmp = best; -+ best = entry; -+ entry = tmp; -+ } -+ } -+ -+ drop_boot_entry(&entry); -+ } -+ -+ closedir(dir); -+ -+ *best_ret = best; -+ return best; -+} -+ -+uapi_boot_entry_t * -+uapi_find_boot_entry(const char *id, const char *machine_id) -+{ -+ uapi_boot_entry_t *best = NULL; -+ struct utsname uts; -+ const char *architecture; -+ -+ if (uname(&uts) >= 0) -+ architecture = uts.machine; -+ -+ return uapi_find_matching_boot_entry(UAPI_BOOT_DIRECTORY, -+ id, machine_id, architecture, -+ &best); -+} -+ -+void -+uapi_boot_entry_free(uapi_boot_entry_t *ube) -+{ -+ drop_string(&ube->title); -+ drop_string(&ube->version); -+ drop_string(&ube->machine_id); -+ drop_string(&ube->image_path); -+ drop_string(&ube->initrd_path); -+ drop_string(&ube->options); -+ free(ube); -+} -+ -+/* -+ * Version comparison -+ */ -+static int -+cmp(int a, int b) -+{ -+ return a - b; -+} -+ -+static bool -+isvalid(char a) -+{ -+ return isalnum(a) || a == '~' || a == '-' || a == '^' || a == '.'; -+} -+ -+static int -+natoi(const char *a, unsigned int n) -+{ -+ char line[UAPI_LINE_MAX]; -+ -+ strncpy(line, a, MIN(UAPI_LINE_MAX, n)); -+ return atoi(line); -+} -+ -+static int -+vercmp(const void *va, const void *vb) -+{ -+ /* https://uapi-group.org/specifications/specs/version_format_specification/ */ -+ /* This code is based on strverscmp_improved from systemd */ -+ -+ const char *a = va; -+ const char *b = vb; -+ const char *sep = "~-^."; -+ -+ assert(a != NULL); -+ assert(b != NULL); -+ -+ for(;;) { -+ const char *aa, *bb; -+ int r; -+ -+ while (*a != '\0' && !isvalid(*a)) -+ a++; -+ while (*b != '\0' && !isvalid(*b)) -+ b++; -+ -+ /* The longer string is considered new */ -+ if (*a == '\0' || *b == '\0') -+ return cmp(*a, *b); -+ -+ for (int i = 0; i < strlen(sep); i++) { -+ char s = sep[i]; -+ -+ if (*a == s || *b == s) { -+ r = cmp(*a != s, *b != s); -+ if (r != 0) -+ return r; -+ -+ a++; -+ b++; -+ } -+ } -+ -+ if (isdigit(*a) || isdigit(*b)) { -+ for (aa = a; isdigit(*aa); aa++); -+ for (bb = b; isdigit(*bb); bb++); -+ -+ r = cmp(a != aa, b != bb); -+ if (r != 0) -+ return r; -+ -+ r = cmp(natoi(a, aa - a), natoi(b, bb - b)); -+ if (r != 0) -+ return r; -+ } else { -+ for (aa = a; isalpha(*aa); aa++); -+ for (bb = b; isalpha(*bb); bb++); -+ -+ r = cmp(strncmp(a, b, MIN(aa - a, bb - b)), 0); -+ if (r != 0) -+ return r; -+ -+ r = cmp(aa - a, bb - b); -+ if (r != 0) -+ return r; -+ } -+ -+ a = aa; -+ b = bb; -+ } -+} -+ -diff --git a/src/uapi.h b/src/uapi.h -new file mode 100644 -index 0000000..ba1147e ---- /dev/null -+++ b/src/uapi.h -@@ -0,0 +1,43 @@ -+/* -+ * Copyright (C) 2022, 2023 SUSE LLC -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * Written by Olaf Kirch -+ */ -+ -+#ifndef UAPI_H -+#define UAPI_H -+ -+#include "types.h" -+ -+struct uapi_boot_entry { -+ char * title; -+ bool efi; -+ char * sort_key; -+ char * version; -+ char * machine_id; -+ char * architecture; -+ char * image_path; -+ char * initrd_path; -+ char * options; -+}; -+ -+#define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries" -+ -+extern uapi_boot_entry_t * uapi_find_boot_entry(const char *id, const char *machine_id); -+extern void uapi_boot_entry_free(uapi_boot_entry_t *); -+ -+#endif /* UAPI_H */ - -From a7a4c854c9668900c8eb9ea9c99d51b6e822f376 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 18:33:38 +0100 -Subject: [PATCH 05/13] Add --next-kernel command line option; use uapi to - locate next kernel when given - -Signed-off-by: Olaf Kirch ---- - man/pcr-oracle.8.in | 12 ++++++++++++ - src/eventlog.h | 3 +++ - src/oracle.c | 23 +++++++++++++++++++++-- - src/sd-boot.c | 19 +++++++++++++++++++ - src/sd-boot.h | 3 +++ - 5 files changed, 58 insertions(+), 2 deletions(-) - -diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in -index eda3cfb..4bd60ba 100644 ---- a/man/pcr-oracle.8.in -+++ b/man/pcr-oracle.8.in -@@ -495,6 +495,18 @@ events (tracked in PCR9). In this case, it would be totally sufficient - to stop processing after grub loaded \fPgrub.cfg\fP from the EFI - System Partition. - .TP -+.BI --next-kernel " id -+In a systemd-boot environment, the values of PCR registers also depend on -+the contents of the kernel and initrd image, as well as the kernel command line -+options. After a kernel update or an initrd rebuild, these values will change. -+So when predicting PCR values in this case, \fBpcr-oracle\fP needs to be -+instructed to refer to the future kernel rather than the current one. -+.IP -+This is what the \fB--next-kernel\fP option is for. It takes one argument, which -+is either an ID (in the sense of systemd-boot IDs), or \fBauto\fP. When -+the latter is given, \fBpcr-oracle\fP will make a best guess as to what -+kernel image will be used on next boot. -+.TP - .BI --authorized-policy " path - Specify the location of the authorized policy. In conjunction with - the \fBcreate-authorized-policy\fP action, the newly created policy -diff --git a/src/eventlog.h b/src/eventlog.h -index bd1106f..65e5322 100644 ---- a/src/eventlog.h -+++ b/src/eventlog.h -@@ -200,6 +200,9 @@ typedef struct tpm_event_log_rehash_ctx { - bool use_pesign; /* compute authenticode FP using external pesign application */ - - const pecoff_image_info_t *next_stage_img; -+ -+ /* This get set when the user specifies --next-kernel */ -+ uapi_boot_entry_t * next_kernel; - } tpm_event_log_rehash_ctx_t; - - #define GRUB_COMMAND_ARGV_MAX 32 -diff --git a/src/oracle.c b/src/oracle.c -index c4e4873..2cc53c1 100644 ---- a/src/oracle.c -+++ b/src/oracle.c -@@ -34,6 +34,7 @@ - #include "rsa.h" - #include "store.h" - #include "testcase.h" -+#include "sd-boot.h" - - enum { - ACTION_NONE, -@@ -58,6 +59,7 @@ struct predictor { - const char * initial_source; - - const char * tpm_event_log_path; -+ const char * next_kernel_id; - - const char * algo; - const tpm_algo_info_t * algo_info; -@@ -98,6 +100,7 @@ enum { - OPT_POLICY_NAME, - OPT_POLICY_FORMAT, - OPT_TARGET_PLATFORM, -+ OPT_NEXT_KERNEL, - }; - - static struct option options[] = { -@@ -114,6 +117,7 @@ static struct option options[] = { - { "before", no_argument, 0, OPT_BEFORE }, - { "verify", required_argument, 0, OPT_VERIFY }, - { "use-pesign", no_argument, 0, OPT_USE_PESIGN }, -+ { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL }, - { "create-testcase", required_argument, 0, OPT_CREATE_TESTCASE }, - { "replay-testcase", required_argument, 0, OPT_REPLAY_TESTCASE }, - -@@ -129,6 +133,7 @@ static struct option options[] = { - { "policy-name", required_argument, 0, OPT_POLICY_NAME }, - { "policy-format", required_argument, 0, OPT_POLICY_FORMAT }, - { "target-platform", required_argument, 0, OPT_TARGET_PLATFORM }, -+ { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL }, - - { NULL } - }; -@@ -250,7 +255,8 @@ predictor_load_eventlog(struct predictor *pred) - static struct predictor * - predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source, - const char *tpm_eventlog_path, -- const char *output_format) -+ const char *output_format, -+ const char *next_kernel_id) - { - struct predictor *pred; - -@@ -260,6 +266,7 @@ predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source, - pred = calloc(1, sizeof(*pred)); - pred->pcr_mask = pcr_selection->pcr_mask; - pred->initial_source = source; -+ pred->next_kernel_id = next_kernel_id; - - pred->algo = pcr_selection->algo_info->openssl_name; - pred->algo_info = pcr_selection->algo_info; -@@ -651,6 +658,14 @@ predictor_update_eventlog(struct predictor *pred) - tpm_event_log_rehash_ctx_init(&rehash_ctx, pred->algo_info); - rehash_ctx.use_pesign = opt_use_pesign; - -+ /* The argument given to --next-kernel will be either "auto" or the -+ * systemd ID of the next kernel entry to be booted. -+ * FIXME: we should probably hide this behind a target_platform function. -+ */ -+ if (pred->next_kernel_id != NULL -+ && !(rehash_ctx.next_kernel = sdb_identify_next_kernel(pred->next_kernel_id))) -+ fatal("unable to identify next kernel \"%s\"\n", pred->next_kernel_id); -+ - for (ev = pred->event_log; ev; ev = ev->next) { - tpm_evdigest_t *pcr; - bool stop = false; -@@ -1021,6 +1036,7 @@ main(int argc, char **argv) - char *opt_rsa_bits = NULL; - char *opt_policy_name = NULL; - char *opt_target_platform = NULL; -+ char *opt_next_kernel = NULL; - const target_platform_t *target; - unsigned int action_flags = 0; - unsigned int rsa_bits = 2048; -@@ -1055,6 +1071,9 @@ main(int argc, char **argv) - case OPT_USE_PESIGN: - opt_use_pesign = 1; - break; -+ case OPT_NEXT_KERNEL: -+ opt_next_kernel = optarg; -+ break; - case OPT_STOP_EVENT: - opt_stop_event = optarg; - break; -@@ -1296,7 +1315,7 @@ main(int argc, char **argv) - fatal("BUG: action %u should have parsed a PCR selection argument", action); - - pred = predictor_new(pcr_selection, opt_from, opt_eventlog_path, -- opt_output_format); -+ opt_output_format, opt_next_kernel); - - if (opt_stop_event) - predictor_set_stop_event(pred, opt_stop_event, !opt_stop_before); -diff --git a/src/sd-boot.c b/src/sd-boot.c -index bbdb498..2e7ec61 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -387,6 +387,25 @@ sdb_get_next_kernel(void) - return NULL; - } - -+/* -+ * Identify the next kernel and initrd given an ID -+ */ -+uapi_boot_entry_t * -+sdb_identify_next_kernel(const char *id) -+{ -+ const char *machine_id; -+ -+ if (id == NULL || !strcasecmp(id, "default")) { -+ if (!(id = get_token_id())) -+ return NULL; -+ } -+ -+ if (!(machine_id = read_machine_id())) -+ return NULL; -+ -+ return uapi_find_boot_entry(id, machine_id); -+} -+ - /* - * Update the systemd json file - */ -diff --git a/src/sd-boot.h b/src/sd-boot.h -index ef36ce7..fa56751 100644 ---- a/src/sd-boot.h -+++ b/src/sd-boot.h -@@ -21,6 +21,8 @@ - #define SD_BOOT_H - - #include -+#include "uapi.h" -+#include "types.h" - - #define SDB_MAX_ENTRIES 16 - #define SDB_LINE_MAX 512 -@@ -40,6 +42,7 @@ typedef struct sdb_entry_list { - sdb_entry_data_t entries[SDB_MAX_ENTRIES]; - } sdb_entry_list_t; - -+extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id); - extern bool sdb_get_entry_list(sdb_entry_list_t *result); - extern bool sdb_is_kernel(const char *application); - extern const char * sdb_get_next_kernel(void); - -From dcfc751ac78400d5bca53b560768f6a3603443f7 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 18:41:26 +0100 -Subject: [PATCH 06/13] Adjust EFI BSA and systemd event rehashing to use - rehash_ctx->next_kernel - -Signed-off-by: Olaf Kirch ---- - src/efi-application.c | 4 ++-- - src/eventlog.c | 38 +++++++++++++++++++++----------------- - 2 files changed, 23 insertions(+), 19 deletions(-) - -diff --git a/src/efi-application.c b/src/efi-application.c -index 06ac9ff..9d7e531 100644 ---- a/src/efi-application.c -+++ b/src/efi-application.c -@@ -291,8 +291,8 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars - } - - /* The next boot can have a different kernel */ -- if (sdb_is_kernel(evspec->efi_application)) { -- new_application = sdb_get_next_kernel(); -+ if (sdb_is_kernel(evspec->efi_application) && ctx->next_kernel) { -+ new_application = ctx->next_kernel->image_path; - if (new_application) { - evspec_clone = *evspec; - evspec_clone.efi_application = strdup(new_application); -diff --git a/src/eventlog.c b/src/eventlog.c -index 32cc75c..3498790 100644 ---- a/src/eventlog.c -+++ b/src/eventlog.c -@@ -32,7 +32,7 @@ - #include "runtime.h" - #include "digest.h" - #include "util.h" --#include "sd-boot.h" -+#include "uapi.h" - - #define TPM_EVENT_LOG_MAX_ALGOS 64 - -@@ -789,21 +789,24 @@ __tpm_event_systemd_describe(const tpm_parsed_event_t *parsed) - static const tpm_evdigest_t * - __tpm_event_systemd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) - { -- sdb_entry_list_t entry_list; -+ const uapi_boot_entry_t *next_kernel = ctx->next_kernel; - char initrd[2048]; - char initrd_utf16[4096]; - unsigned int len; - -- memset(&entry_list, 0, sizeof(entry_list)); -- if (!sdb_get_entry_list(&entry_list)) { -- error("Error generating the list of boot entries\n"); -+ /* If no --next-kernel option was given, do not rehash anything */ -+ if (next_kernel == NULL) -+ return tpm_event_get_digest(ev, ctx->algo); -+ -+ if (!next_kernel->image_path) { -+ error("Unable to identify the next kernel\n"); - return NULL; - } - -- debug("Next boot entry expected from: %s\n", entry_list.entries[0].path); -+ debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : ""); - snprintf(initrd, sizeof(initrd), "initrd=%s %s", -- path_unix2dos(entry_list.entries[0].path), -- entry_list.entries[0].options); -+ path_unix2dos(next_kernel->initrd_path), -+ next_kernel->options? : ""); - - len = (strlen(initrd) + 1) << 1; - assert(len <= sizeof(initrd_utf16)); -@@ -860,19 +863,20 @@ __tpm_event_tag_initrd_describe(const tpm_parsed_event_t *parsed) - static const tpm_evdigest_t * - __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) - { -- sdb_entry_list_t entry_list; -- const tpm_evdigest_t *md = NULL; -+ const uapi_boot_entry_t *next_kernel = ctx->next_kernel; -+ -+ /* If no --next-kernel option was given, do not rehash anything */ -+ if (next_kernel == NULL) -+ return tpm_event_get_digest(ev, ctx->algo); - -- memset(&entry_list, 0, sizeof(entry_list)); -- if (!sdb_get_entry_list(&entry_list)) { -- error("Error generating the list of boot entries\n"); -+ if (!next_kernel->initrd_path) { -+ /* Can this happen eg when going from a split kernel to a unified kernel? */ -+ error("Unable to identify the next initrd\n"); - return NULL; - } - -- debug("Next boot entry expected from: %s\n", entry_list.entries[0].path); -- md = runtime_digest_efi_file(ctx->algo, entry_list.entries[0].initrd); -- -- return md; -+ debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : ""); -+ return runtime_digest_efi_file(ctx->algo, next_kernel->initrd_path); - } - - /* - -From 13f67d840ffadccbd0daf4fb133f9471a5b1a439 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Mon, 27 Nov 2023 18:44:05 +0100 -Subject: [PATCH 07/13] Remove old code from sd-boot.* - -Signed-off-by: Olaf Kirch ---- - src/sd-boot.c | 222 +------------------------------------------------- - src/sd-boot.h | 2 - - 2 files changed, 3 insertions(+), 221 deletions(-) - -diff --git a/src/sd-boot.c b/src/sd-boot.c -index 2e7ec61..c878f6c 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -100,163 +100,6 @@ read_machine_id(void) - return read_single_line_file("/etc/machine-id", id, sizeof(id)); - } - --static bool --read_entry(sdb_entry_data_t *result) --{ -- FILE *fp; -- char line[SDB_LINE_MAX]; -- -- if (!(fp = fopen(result->path, "r"))) { -- error("Cannot open %s: %m\n", result->path); -- goto fail; -- } -- -- while (fgets(line, SDB_LINE_MAX, fp)) { -- char *dest = NULL; -- -- if (!strncmp("sort-key", line, strlen("sort-key"))) -- dest = result->sort_key; -- else -- if (!strncmp("machine-id", line, strlen("machine-id"))) -- dest = result->machine_id; -- else -- if (!strncmp("version", line, strlen("version"))) -- dest = result->version; -- else -- if (!strncmp("options", line, strlen("options"))) -- dest = result->options; -- else -- if (!strncmp("linux", line, strlen("linux"))) -- dest = result->image; -- else -- if (!strncmp("initrd", line, strlen("initrd"))) -- dest = result->initrd; -- else -- continue; -- -- /* Position the index on the value section of the line */ -- unsigned int index = 0; -- while (line[++index] != ' '); -- while (line[++index] == ' '); -- strncpy(dest, &line[index], strlen(&line[index]) - 1); -- } -- -- fclose(fp); -- return true; -- --fail: -- return false; --} -- --static int --cmp(int a, int b) --{ -- return a - b; --} -- --static bool --isvalid(char a) --{ -- return isalnum(a) || a == '~' || a == '-' || a == '^' || a == '.'; --} -- --static int --natoi(const char *a, unsigned int n) --{ -- char line[SDB_LINE_MAX]; -- -- strncpy(line, a, MIN(SDB_LINE_MAX, n)); -- return atoi(line); --} -- --static int --vercmp(const void *va, const void *vb) --{ -- /* https://uapi-group.org/specifications/specs/version_format_specification/ */ -- /* This code is based on strverscmp_improved from systemd */ -- -- const char *a = va; -- const char *b = vb; -- const char *sep = "~-^."; -- -- assert(a != NULL); -- assert(b != NULL); -- -- for(;;) { -- const char *aa, *bb; -- int r; -- -- while (*a != '\0' && !isvalid(*a)) -- a++; -- while (*b != '\0' && !isvalid(*b)) -- b++; -- -- /* The longer string is considered new */ -- if (*a == '\0' || *b == '\0') -- return cmp(*a, *b); -- -- for (int i = 0; i < strlen(sep); i++) { -- char s = sep[i]; -- -- if (*a == s || *b == s) { -- r = cmp(*a != s, *b != s); -- if (r != 0) -- return r; -- -- a++; -- b++; -- } -- } -- -- if (isdigit(*a) || isdigit(*b)) { -- for (aa = a; isdigit(*aa); aa++); -- for (bb = b; isdigit(*bb); bb++); -- -- r = cmp(a != aa, b != bb); -- if (r != 0) -- return r; -- -- r = cmp(natoi(a, aa - a), natoi(b, bb - b)); -- if (r != 0) -- return r; -- } else { -- for (aa = a; isalpha(*aa); aa++); -- for (bb = b; isalpha(*bb); bb++); -- -- r = cmp(strncmp(a, b, MIN(aa - a, bb - b)), 0); -- if (r != 0) -- return r; -- -- r = cmp(aa - a, bb - b); -- if (r != 0) -- return r; -- } -- -- a = aa; -- b = bb; -- } --} -- --static int --entrycmp(const void *va, const void *vb) --{ -- /* https://uapi-group.org/specifications/specs/boot_loader_specification/#sorting */ -- int result; -- const sdb_entry_data_t *a = va; -- const sdb_entry_data_t *b = vb; -- -- result = strcmp(a->sort_key, b->sort_key); -- -- if (result == 0) -- result = strcmp(a->machine_id, b->machine_id); -- -- if (result == 0) -- result = vercmp(a->version, b->version); -- -- /* Reverse the order, so new kernels appears first */ -- return -result; --} -- - static bool - exists_efi_dir(const char *path) - { -@@ -302,49 +145,9 @@ get_token_id(void) - return token_id; - } - --bool --sdb_get_entry_list(sdb_entry_list_t *result) --{ -- const char *token_id = NULL; -- DIR *d = NULL; -- struct dirent *dir; -- char *path = "/boot/efi/loader/entries"; -- -- if (!(token_id = get_token_id())) -- goto fail; -- -- if (!(d = opendir(path))) { -- error("Cannot read directory contents from /boot/efi/loader/entries: %m\n"); -- goto fail; -- } -- -- while ((dir = readdir(d)) != NULL) { -- if (result->num_entries >= SDB_MAX_ENTRIES) -- break; -- -- if (strncmp(token_id, dir->d_name, strlen(token_id))) -- continue; -- -- debug("Bootloader entry %s\n", dir->d_name); -- -- snprintf(result->entries[result->num_entries].path, PATH_MAX, "%s/%s", path, dir->d_name); -- if (!read_entry(&result->entries[result->num_entries])) { -- error("Cannot read bootloader entry %s\n", dir->d_name); -- continue; -- } -- -- result->num_entries++; -- } -- -- qsort(result->entries, result->num_entries, sizeof(result->entries[0]), entrycmp); -- -- closedir(d); -- return true; -- --fail: -- return false; --} -- -+/* -+ * This should probably use UAPI boot entry logic as well -+ */ - bool - sdb_is_kernel(const char *application) - { -@@ -368,25 +171,6 @@ sdb_is_kernel(const char *application) - return false; - } - --const char * --sdb_get_next_kernel(void) --{ -- static char result[SDB_LINE_MAX]; -- sdb_entry_list_t entry_list; -- -- memset(&entry_list, 0, sizeof(entry_list)); -- if (!sdb_get_entry_list(&entry_list)) { -- error("Error generating the list of boot entries\n"); -- goto fail; -- } -- -- strncpy(result, entry_list.entries[0].image, SDB_LINE_MAX); -- return result; -- --fail: -- return NULL; --} -- - /* - * Identify the next kernel and initrd given an ID - */ -diff --git a/src/sd-boot.h b/src/sd-boot.h -index fa56751..2b11dc1 100644 ---- a/src/sd-boot.h -+++ b/src/sd-boot.h -@@ -43,9 +43,7 @@ typedef struct sdb_entry_list { - } sdb_entry_list_t; - - extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id); --extern bool sdb_get_entry_list(sdb_entry_list_t *result); - extern bool sdb_is_kernel(const char *application); --extern const char * sdb_get_next_kernel(void); - - /* This will have to update the systemd json file, and add a new entry. */ - extern bool sdb_policy_file_add_entry(const char *filename, - -From 737d8d561cfbd1dd03e7c4d37d7c515b709cce11 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 10:30:10 +0100 -Subject: [PATCH 08/13] Manpage fixes - -Signed-off-by: Olaf Kirch ---- - man/pcr-oracle.8.in | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in -index 4bd60ba..3682afa 100644 ---- a/man/pcr-oracle.8.in -+++ b/man/pcr-oracle.8.in -@@ -82,7 +82,7 @@ object in a native format defined in the TPM specification. - Finally, the systemd-boot implementation for unlocking disk partitions - stores policies in a JSON formatted file, which can be fed to the - \fBsystemd-cryptenroll\fP tool. This file will contain any number of --signed policies that we want \fBsystemd-cryptsetup\fB to recognize during -+signed policies that we want \fBsystemd-cryptsetup\fP to recognize during - boot time. Each entry contains the list of PCRs that compose the PCR policy, a - finger print of the public key, the hash of the policy and the signature (in - base64) of the PCR policy. -@@ -366,7 +366,7 @@ that. The main difference is in the way the signed policy is stored: - --from eventlog \\ - --output tpm2-pcr-signature.json \\ - --policy-format systemd \\ -- sign 0,2,4,7,9,11 -+ sign 0,2,4,7,9,12 - .fi - .P - This will predict a set of PCR values, sign them using the specified -@@ -384,9 +384,8 @@ These policies can then be enrolled for future system boots using - # systemd-cryptenroll \\ - --tpm2-device=auto \\ - --tpm2-public-key=public-key.pem \\ -- --tpm2-public-key-pcrs="0,2,4,7,9,11" \ -+ --tpm2-public-key-pcrs="0,2,4,7,9,12" \ - --tpm2-signature=tpm2-pcr-signature.json \\ -- --policy-format systemd \\ - /dev/sda3 - .fi - .\" ################################################################## -@@ -510,7 +509,7 @@ kernel image will be used on next boot. - .BI --authorized-policy " path - Specify the location of the authorized policy. In conjunction with - the \fBcreate-authorized-policy\fP action, the newly created policy --is written to this location. For subsequent actions, such as \fBseal\fB, -+is written to this location. For subsequent actions, such as \fBseal\fP, - the policy will be read from this location. - .TP - .BI --private-key " path - -From c0011884d8685d4f59523e45f69bd77d2c113838 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 10:42:12 +0100 -Subject: [PATCH 09/13] Several fixes resulting from review by alberto - -Signed-off-by: Olaf Kirch ---- - src/uapi.c | 4 +--- - src/util.c | 2 +- - 2 files changed, 2 insertions(+), 4 deletions(-) - -diff --git a/src/uapi.c b/src/uapi.c -index bbcaea9..a12ad21 100644 ---- a/src/uapi.c -+++ b/src/uapi.c -@@ -123,8 +123,6 @@ uapi_boot_entry_applies(const uapi_boot_entry_t *entry, const char *machine_id, - return false; - if (entry->architecture && architecture && strcmp(entry->architecture, architecture)) - return false; -- /* We don't check the efi key because it can only express "entry is EFI only"; it cannot express -- * "this is a legacy BIOS entry" */ - return true; - } - -@@ -147,7 +145,7 @@ uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_en - - /* - * We pass in a best_ret pointer in case we need to extend this -- * to search more than on directory -+ * to search more than one directory - */ - uapi_boot_entry_t * - uapi_find_matching_boot_entry(const char *dir_path, -diff --git a/src/util.c b/src/util.c -index 644d138..7343ffb 100644 ---- a/src/util.c -+++ b/src/util.c -@@ -526,7 +526,7 @@ read_single_line_file(const char *path, char *buffer, size_t size) - } - - if (fgets(buffer, size, fp) != NULL) -- buffer[strcspn(buffer, "\n")] = 0; -+ buffer[strcspn(buffer, "\n")] = '\0'; - else - buffer[0] = '\0'; - - -From f0c09557aa72794c7149529056e6fc9ea1cd2763 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 10:45:15 +0100 -Subject: [PATCH 10/13] When matching UAPI boot entries, check against all - possible entry-tokens - -Signed-off-by: Olaf Kirch ---- - src/sd-boot.c | 87 +++++++++++++++++++++++++++++++++++++-------------- - src/uapi.c | 50 ++++++++++++++++++++++++----- - src/uapi.h | 11 ++++++- - 3 files changed, 115 insertions(+), 33 deletions(-) - -diff --git a/src/sd-boot.c b/src/sd-boot.c -index c878f6c..8dc9bf1 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -32,7 +32,6 @@ - #include "sd-boot.h" - #include "util.h" - -- - static const char * - read_entry_token(void) - { -@@ -100,6 +99,34 @@ read_machine_id(void) - return read_single_line_file("/etc/machine-id", id, sizeof(id)); - } - -+/* -+ * Kernels installed by kernel-install can use a variety of IDs as entry-token. -+ * Try to cater to all of them. -+ */ -+static const uapi_kernel_entry_tokens_t * -+get_valid_kernel_entry_tokens(void) -+{ -+ static uapi_kernel_entry_tokens_t valid_tokens; -+ const char *token; -+ -+ if (valid_tokens.count != 0) -+ return &valid_tokens; /* I've been here before */ -+ -+ if ((token = read_entry_token()) != NULL) -+ uapi_kernel_entry_tokens_add(&valid_tokens, token); -+ -+ if ((token = read_machine_id()) != NULL) -+ uapi_kernel_entry_tokens_add(&valid_tokens, token); -+ -+ if ((token = read_os_release("ID")) != NULL) -+ uapi_kernel_entry_tokens_add(&valid_tokens, token); -+ -+ if ((token = read_os_release("IMAGE_ID")) != NULL) -+ uapi_kernel_entry_tokens_add(&valid_tokens, token); -+ -+ return &valid_tokens; -+} -+ - static bool - exists_efi_dir(const char *path) - { -@@ -151,24 +178,28 @@ get_token_id(void) - bool - sdb_is_kernel(const char *application) - { -- const char *token_id; -- const char *prefix = "linux-"; -- char path[PATH_MAX]; -- -- if (!(token_id = get_token_id())) -- goto fail; -- -- snprintf(path, PATH_MAX, "/%s/", token_id); -- if (strncmp(path, application, strlen(path))) -- goto fail; -- -- strncpy(path, application, PATH_MAX); -- for (char *ptr = strtok(path, "/"); ptr; ptr = strtok(NULL, "/")) -- if (!strncmp(ptr, prefix, strlen(prefix))) -- return true; -+ static const char prefix[] = "linux-"; -+ const uapi_kernel_entry_tokens_t *match; -+ char *path_copy; -+ int found = 0; -+ -+ match = get_valid_kernel_entry_tokens(); -+ path_copy = strdup(application); -+ -+ for (char *ptr = strtok(path_copy, "/"); ptr; ptr = strtok(NULL, "/")) { -+ unsigned int i; -+ for (i = 0; i < match->count; ++i) { -+ const char *token = match->entry_token[i]; -+ -+ if (!strcmp(ptr, token)) -+ found |= 1; -+ else if (!strncmp(ptr, prefix, sizeof(prefix) - 1)) -+ found |= 2; -+ } -+ } - --fail: -- return false; -+ free(path_copy); -+ return (found == 3); - } - - /* -@@ -177,17 +208,25 @@ sdb_is_kernel(const char *application) - uapi_boot_entry_t * - sdb_identify_next_kernel(const char *id) - { -+ uapi_kernel_entry_tokens_t id_match = { 0 }; -+ const uapi_kernel_entry_tokens_t *match; - const char *machine_id; -+ uapi_boot_entry_t *result = NULL; - -- if (id == NULL || !strcasecmp(id, "default")) { -- if (!(id = get_token_id())) -- return NULL; -+ if (id == NULL || !strcasecmp(id, "auto")) { -+ match = get_valid_kernel_entry_tokens(); -+ } else { -+ uapi_kernel_entry_tokens_add(&id_match, id); -+ match = &id_match; - } - -- if (!(machine_id = read_machine_id())) -- return NULL; -+ machine_id = read_machine_id(); -+ -+ if (machine_id != NULL) -+ result = uapi_find_boot_entry(match, machine_id); - -- return uapi_find_boot_entry(id, machine_id); -+ uapi_kernel_entry_tokens_destroy(&id_match); -+ return result; - } - - /* -diff --git a/src/uapi.c b/src/uapi.c -index a12ad21..acba37a 100644 ---- a/src/uapi.c -+++ b/src/uapi.c -@@ -149,11 +149,10 @@ uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_en - */ - uapi_boot_entry_t * - uapi_find_matching_boot_entry(const char *dir_path, -- const char *entry_id, const char *machine_id, const char *architecture, -+ const uapi_kernel_entry_tokens_t *match, const char *machine_id, const char *architecture, - uapi_boot_entry_t **best_ret) - { - uapi_boot_entry_t *best = *best_ret; -- unsigned int entry_id_len = 0; - struct dirent *d; - DIR *dir; - -@@ -163,9 +162,6 @@ uapi_find_matching_boot_entry(const char *dir_path, - return NULL; - } - -- if (entry_id) -- entry_id_len = strlen(entry_id); -- - while ((d = readdir(dir)) != NULL) { - char config_path[PATH_MAX]; - uapi_boot_entry_t *entry; -@@ -173,7 +169,7 @@ uapi_find_matching_boot_entry(const char *dir_path, - if (d->d_type != DT_REG) - continue; - -- if (entry_id && strncmp(d->d_name, entry_id, entry_id_len)) -+ if (match && !uapi_kernel_entry_tokens_match_filename(match, d->d_name)) - continue; - - snprintf(config_path, sizeof(config_path), "%s/%s", dir_path, d->d_name); -@@ -201,7 +197,7 @@ uapi_find_matching_boot_entry(const char *dir_path, - } - - uapi_boot_entry_t * --uapi_find_boot_entry(const char *id, const char *machine_id) -+uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id) - { - uapi_boot_entry_t *best = NULL; - struct utsname uts; -@@ -211,7 +207,7 @@ uapi_find_boot_entry(const char *id, const char *machine_id) - architecture = uts.machine; - - return uapi_find_matching_boot_entry(UAPI_BOOT_DIRECTORY, -- id, machine_id, architecture, -+ match, machine_id, architecture, - &best); - } - -@@ -227,6 +223,44 @@ uapi_boot_entry_free(uapi_boot_entry_t *ube) - free(ube); - } - -+/* -+ * Manage list of valid entry-tokens -+ */ -+void -+uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *match, const char *id) -+{ -+ if (id == NULL) -+ return; -+ -+ if (match->count >= UAPI_MAX_ENTRY_TOKENS) -+ fatal("%s: too many tokens\n", __func__); -+ -+ match->entry_token[match->count++] = strdup(id); -+} -+ -+void -+uapi_kernel_entry_tokens_destroy(uapi_kernel_entry_tokens_t *match) -+{ -+ while (match->count) -+ drop_string(&match->entry_token[--(match->count)]); -+} -+ -+bool -+uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *token_list, const char *filename) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < token_list->count; ++i) { -+ const char *token = token_list->entry_token[i]; -+ int len = strlen(token); -+ -+ if (!strncmp(filename, token, len) && filename[len] == '-') -+ return true; -+ } -+ -+ return false; -+} -+ - /* - * Version comparison - */ -diff --git a/src/uapi.h b/src/uapi.h -index ba1147e..cc38395 100644 ---- a/src/uapi.h -+++ b/src/uapi.h -@@ -35,9 +35,18 @@ struct uapi_boot_entry { - char * options; - }; - -+#define UAPI_MAX_ENTRY_TOKENS 8 -+typedef struct uapi_kernel_entry_tokens { -+ unsigned int count; -+ char * entry_token[UAPI_MAX_ENTRY_TOKENS]; -+} uapi_kernel_entry_tokens_t; -+ - #define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries" - --extern uapi_boot_entry_t * uapi_find_boot_entry(const char *id, const char *machine_id); -+extern uapi_boot_entry_t * uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id); - extern void uapi_boot_entry_free(uapi_boot_entry_t *); -+extern void uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *, const char *); -+extern void uapi_kernel_entry_tokens_destroy(uapi_kernel_entry_tokens_t *); -+extern bool uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *, const char *filename); - - #endif /* UAPI_H */ - -From 8a0d1e8050340034e4690123c205a8b98abd7d24 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 10:46:20 +0100 -Subject: [PATCH 11/13] Remove code that's been obsoleted by - uapi_kernel_entry_tokens stuff - -Signed-off-by: Olaf Kirch ---- - src/sd-boot.c | 45 --------------------------------------------- - 1 file changed, 45 deletions(-) - -diff --git a/src/sd-boot.c b/src/sd-boot.c -index 8dc9bf1..3b72e37 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -127,51 +127,6 @@ get_valid_kernel_entry_tokens(void) - return &valid_tokens; - } - --static bool --exists_efi_dir(const char *path) --{ -- DIR *d = NULL; -- char full_path[PATH_MAX]; -- -- if (path == NULL) -- return false; -- -- snprintf(full_path, PATH_MAX, "/boot/efi/%s", path); -- if (!(d = opendir(full_path))) -- return false; -- -- closedir(d); -- return true; --} -- --static const char * --get_token_id(void) --{ -- static const char *token_id = NULL; -- const char *id = NULL; -- const char *image_id = NULL; -- const char *machine_id = NULL; -- -- /* All IDs are optional (cannot be present), except machine_id */ -- token_id = read_entry_token(); -- id = read_os_release("ID"); -- image_id = read_os_release("IMAGE_ID"); -- if (!(machine_id = read_machine_id())) -- return NULL; -- -- /* The order is not correct, and it is using some heuristics -- * to find the correct prefix. Other tools like sdbootutil -- * seems to use parameters to decide */ -- if (token_id == NULL && exists_efi_dir(id)) -- token_id = id; -- if (token_id == NULL && exists_efi_dir(image_id)) -- token_id = id; -- if (token_id == NULL && exists_efi_dir(machine_id)) -- token_id = machine_id; -- -- return token_id; --} -- - /* - * This should probably use UAPI boot entry logic as well - */ - -From 07203a598a95a11afb4cf4a6f50bb92c7d4ae981 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 14:01:40 +0100 -Subject: [PATCH 12/13] Fix an issue with not being able to find an entry - referenced exactly by the boot id - -Signed-off-by: Olaf Kirch ---- - src/sd-boot.c | 8 ++++++++ - src/uapi.c | 31 ++++++++++++++++++++++++++++++- - src/uapi.h | 1 + - 3 files changed, 39 insertions(+), 1 deletion(-) - -diff --git a/src/sd-boot.c b/src/sd-boot.c -index 3b72e37..e3e0568 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -171,6 +171,13 @@ sdb_identify_next_kernel(const char *id) - if (id == NULL || !strcasecmp(id, "auto")) { - match = get_valid_kernel_entry_tokens(); - } else { -+ /* Try to load the entry referenced _exactly_ by the -+ * given id. */ -+ result = uapi_get_boot_entry(id); -+ if (result != NULL) -+ goto done; -+ -+ /* No cigar, revert to a prefix based search */ - uapi_kernel_entry_tokens_add(&id_match, id); - match = &id_match; - } -@@ -180,6 +187,7 @@ sdb_identify_next_kernel(const char *id) - if (machine_id != NULL) - result = uapi_find_boot_entry(match, machine_id); - -+done: - uapi_kernel_entry_tokens_destroy(&id_match); - return result; - } -diff --git a/src/uapi.c b/src/uapi.c -index acba37a..f0db62a 100644 ---- a/src/uapi.c -+++ b/src/uapi.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -196,6 +197,29 @@ uapi_find_matching_boot_entry(const char *dir_path, - return best; - } - -+/* -+ * Get the exact boot entry identified by id. -+ * This is mainly for iterating over entries like -+ * for name in "/boot/efi/loader/entries/"*.conf; do -+ * pcr-oracle --boot-entry $(basename $name .conf) ... -+ * done -+ */ -+uapi_boot_entry_t * -+uapi_get_boot_entry(const char *id) -+{ -+ char path[PATH_MAX]; -+ -+ if (path_has_file_extension(id, ".conf")) -+ snprintf(path, sizeof(path), "%s/%s", UAPI_BOOT_DIRECTORY, id); -+ else -+ snprintf(path, sizeof(path), "%s/%s.conf", UAPI_BOOT_DIRECTORY, id); -+ -+ if (access(path, R_OK) < 0) -+ return NULL; -+ -+ return uapi_boot_entry_load(path); -+} -+ - uapi_boot_entry_t * - uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id) - { -@@ -253,8 +277,13 @@ uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *token_ - for (i = 0; i < token_list->count; ++i) { - const char *token = token_list->entry_token[i]; - int len = strlen(token); -+ char cc; -+ -+ if (strncmp(filename, token, len)) -+ continue; - -- if (!strncmp(filename, token, len) && filename[len] == '-') -+ cc = filename[len]; -+ if (cc == '\0' || cc == '-' || cc == '.') - return true; - } - -diff --git a/src/uapi.h b/src/uapi.h -index cc38395..96ca7ed 100644 ---- a/src/uapi.h -+++ b/src/uapi.h -@@ -43,6 +43,7 @@ typedef struct uapi_kernel_entry_tokens { - - #define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries" - -+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); - extern void uapi_boot_entry_free(uapi_boot_entry_t *); - extern void uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *, const char *); - -From 0db6dae5c065944506255b92033314c97b45e4e4 Mon Sep 17 00:00:00 2001 -From: Olaf Kirch -Date: Tue, 28 Nov 2023 14:04:43 +0100 -Subject: [PATCH 13/13] Rename --next-kernel to --boot-entry - -Signed-off-by: Olaf Kirch ---- - man/pcr-oracle.8.in | 4 ++-- - src/efi-application.c | 4 ++-- - src/eventlog.c | 22 +++++++++++----------- - src/eventlog.h | 2 +- - src/oracle.c | 26 +++++++++++++------------- - src/sd-boot.c | 2 +- - src/sd-boot.h | 2 +- - 7 files changed, 31 insertions(+), 31 deletions(-) - -diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in -index 3682afa..86ac275 100644 ---- a/man/pcr-oracle.8.in -+++ b/man/pcr-oracle.8.in -@@ -494,14 +494,14 @@ events (tracked in PCR9). In this case, it would be totally sufficient - to stop processing after grub loaded \fPgrub.cfg\fP from the EFI - System Partition. - .TP --.BI --next-kernel " id -+.BI --boot-entry " id - In a systemd-boot environment, the values of PCR registers also depend on - the contents of the kernel and initrd image, as well as the kernel command line - options. After a kernel update or an initrd rebuild, these values will change. - So when predicting PCR values in this case, \fBpcr-oracle\fP needs to be - instructed to refer to the future kernel rather than the current one. - .IP --This is what the \fB--next-kernel\fP option is for. It takes one argument, which -+This is what the \fB--boot-entry\fP option is for. It takes one argument, which - is either an ID (in the sense of systemd-boot IDs), or \fBauto\fP. When - the latter is given, \fBpcr-oracle\fP will make a best guess as to what - kernel image will be used on next boot. -diff --git a/src/efi-application.c b/src/efi-application.c -index 9d7e531..3e80083 100644 ---- a/src/efi-application.c -+++ b/src/efi-application.c -@@ -291,8 +291,8 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars - } - - /* The next boot can have a different kernel */ -- if (sdb_is_kernel(evspec->efi_application) && ctx->next_kernel) { -- new_application = ctx->next_kernel->image_path; -+ if (sdb_is_kernel(evspec->efi_application) && ctx->boot_entry) { -+ new_application = ctx->boot_entry->image_path; - if (new_application) { - evspec_clone = *evspec; - evspec_clone.efi_application = strdup(new_application); -diff --git a/src/eventlog.c b/src/eventlog.c -index 3498790..4277d42 100644 ---- a/src/eventlog.c -+++ b/src/eventlog.c -@@ -789,24 +789,24 @@ __tpm_event_systemd_describe(const tpm_parsed_event_t *parsed) - static const tpm_evdigest_t * - __tpm_event_systemd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) - { -- const uapi_boot_entry_t *next_kernel = ctx->next_kernel; -+ const uapi_boot_entry_t *boot_entry = ctx->boot_entry; - char initrd[2048]; - char initrd_utf16[4096]; - unsigned int len; - - /* If no --next-kernel option was given, do not rehash anything */ -- if (next_kernel == NULL) -+ if (boot_entry == NULL) - return tpm_event_get_digest(ev, ctx->algo); - -- if (!next_kernel->image_path) { -+ if (!boot_entry->image_path) { - error("Unable to identify the next kernel\n"); - return NULL; - } - -- debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : ""); -+ debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : ""); - snprintf(initrd, sizeof(initrd), "initrd=%s %s", -- path_unix2dos(next_kernel->initrd_path), -- next_kernel->options? : ""); -+ path_unix2dos(boot_entry->initrd_path), -+ boot_entry->options? : ""); - - len = (strlen(initrd) + 1) << 1; - assert(len <= sizeof(initrd_utf16)); -@@ -863,20 +863,20 @@ __tpm_event_tag_initrd_describe(const tpm_parsed_event_t *parsed) - static const tpm_evdigest_t * - __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) - { -- const uapi_boot_entry_t *next_kernel = ctx->next_kernel; -+ const uapi_boot_entry_t *boot_entry = ctx->boot_entry; - - /* If no --next-kernel option was given, do not rehash anything */ -- if (next_kernel == NULL) -+ if (boot_entry == NULL) - return tpm_event_get_digest(ev, ctx->algo); - -- if (!next_kernel->initrd_path) { -+ if (!boot_entry->initrd_path) { - /* Can this happen eg when going from a split kernel to a unified kernel? */ - error("Unable to identify the next initrd\n"); - return NULL; - } - -- debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : ""); -- return runtime_digest_efi_file(ctx->algo, next_kernel->initrd_path); -+ debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : ""); -+ return runtime_digest_efi_file(ctx->algo, boot_entry->initrd_path); - } - - /* -diff --git a/src/eventlog.h b/src/eventlog.h -index 65e5322..3741b58 100644 ---- a/src/eventlog.h -+++ b/src/eventlog.h -@@ -202,7 +202,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 */ -- uapi_boot_entry_t * next_kernel; -+ uapi_boot_entry_t * boot_entry; - } tpm_event_log_rehash_ctx_t; - - #define GRUB_COMMAND_ARGV_MAX 32 -diff --git a/src/oracle.c b/src/oracle.c -index 2cc53c1..1cafafc 100644 ---- a/src/oracle.c -+++ b/src/oracle.c -@@ -59,7 +59,7 @@ struct predictor { - const char * initial_source; - - const char * tpm_event_log_path; -- const char * next_kernel_id; -+ const char * boot_entry_id; - - const char * algo; - const tpm_algo_info_t * algo_info; -@@ -100,7 +100,7 @@ enum { - OPT_POLICY_NAME, - OPT_POLICY_FORMAT, - OPT_TARGET_PLATFORM, -- OPT_NEXT_KERNEL, -+ OPT_BOOT_ENTRY, - }; - - static struct option options[] = { -@@ -117,7 +117,7 @@ static struct option options[] = { - { "before", no_argument, 0, OPT_BEFORE }, - { "verify", required_argument, 0, OPT_VERIFY }, - { "use-pesign", no_argument, 0, OPT_USE_PESIGN }, -- { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL }, -+ { "boot-entry", required_argument, 0, OPT_BOOT_ENTRY }, - { "create-testcase", required_argument, 0, OPT_CREATE_TESTCASE }, - { "replay-testcase", required_argument, 0, OPT_REPLAY_TESTCASE }, - -@@ -133,7 +133,7 @@ static struct option options[] = { - { "policy-name", required_argument, 0, OPT_POLICY_NAME }, - { "policy-format", required_argument, 0, OPT_POLICY_FORMAT }, - { "target-platform", required_argument, 0, OPT_TARGET_PLATFORM }, -- { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL }, -+ { "next-kernel", required_argument, 0, OPT_BOOT_ENTRY }, - - { NULL } - }; -@@ -256,7 +256,7 @@ static struct predictor * - predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source, - const char *tpm_eventlog_path, - const char *output_format, -- const char *next_kernel_id) -+ const char *boot_entry_id) - { - struct predictor *pred; - -@@ -266,7 +266,7 @@ predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source, - pred = calloc(1, sizeof(*pred)); - pred->pcr_mask = pcr_selection->pcr_mask; - pred->initial_source = source; -- pred->next_kernel_id = next_kernel_id; -+ pred->boot_entry_id = boot_entry_id; - - pred->algo = pcr_selection->algo_info->openssl_name; - pred->algo_info = pcr_selection->algo_info; -@@ -662,9 +662,9 @@ 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->next_kernel_id != NULL -- && !(rehash_ctx.next_kernel = sdb_identify_next_kernel(pred->next_kernel_id))) -- fatal("unable to identify next kernel \"%s\"\n", pred->next_kernel_id); -+ 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); - - for (ev = pred->event_log; ev; ev = ev->next) { - tpm_evdigest_t *pcr; -@@ -1036,7 +1036,7 @@ main(int argc, char **argv) - char *opt_rsa_bits = NULL; - char *opt_policy_name = NULL; - char *opt_target_platform = NULL; -- char *opt_next_kernel = NULL; -+ char *opt_boot_entry = NULL; - const target_platform_t *target; - unsigned int action_flags = 0; - unsigned int rsa_bits = 2048; -@@ -1071,8 +1071,8 @@ main(int argc, char **argv) - case OPT_USE_PESIGN: - opt_use_pesign = 1; - break; -- case OPT_NEXT_KERNEL: -- opt_next_kernel = optarg; -+ case OPT_BOOT_ENTRY: -+ opt_boot_entry = optarg; - break; - case OPT_STOP_EVENT: - opt_stop_event = optarg; -@@ -1315,7 +1315,7 @@ main(int argc, char **argv) - fatal("BUG: action %u should have parsed a PCR selection argument", action); - - pred = predictor_new(pcr_selection, opt_from, opt_eventlog_path, -- opt_output_format, opt_next_kernel); -+ opt_output_format, opt_boot_entry); - - if (opt_stop_event) - predictor_set_stop_event(pred, opt_stop_event, !opt_stop_before); -diff --git a/src/sd-boot.c b/src/sd-boot.c -index e3e0568..ad13617 100644 ---- a/src/sd-boot.c -+++ b/src/sd-boot.c -@@ -161,7 +161,7 @@ sdb_is_kernel(const char *application) - * Identify the next kernel and initrd given an ID - */ - uapi_boot_entry_t * --sdb_identify_next_kernel(const char *id) -+sdb_identify_boot_entry(const char *id) - { - uapi_kernel_entry_tokens_t id_match = { 0 }; - const uapi_kernel_entry_tokens_t *match; -diff --git a/src/sd-boot.h b/src/sd-boot.h -index 2b11dc1..0472320 100644 ---- a/src/sd-boot.h -+++ b/src/sd-boot.h -@@ -42,7 +42,7 @@ typedef struct sdb_entry_list { - sdb_entry_data_t entries[SDB_MAX_ENTRIES]; - } sdb_entry_list_t; - --extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id); -+extern uapi_boot_entry_t * sdb_identify_boot_entry(const char *id); - extern bool sdb_is_kernel(const char *application); - - /* This will have to update the systemd json file, and add a new entry. */ diff --git a/fix_pcr_index.patch b/fix_pcr_index.patch deleted file mode 100644 index 739b86e..0000000 --- a/fix_pcr_index.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 152f97b1b49ca12d1de1df67c892b1c35140c056 Mon Sep 17 00:00:00 2001 -From: Alberto Planas -Date: Thu, 30 Nov 2023 13:20:54 +0100 -Subject: [PATCH 1/3] Remove old systemd parameter - -Signed-off-by: Alberto Planas ---- - man/pcr-oracle.8.in | 1 - - 1 file changed, 1 deletion(-) - -Index: pcr-oracle-0.5.3/src/sd-boot.c -=================================================================== ---- pcr-oracle-0.5.3.orig/src/sd-boot.c -+++ pcr-oracle-0.5.3/src/sd-boot.c -@@ -233,7 +233,7 @@ sdb_policy_entry_set_pcr_mask(struct jso - pcrs = json_object_new_array(); - json_object_object_add(entry, "pcrs", pcrs); - -- for (pcr_index = 1; pcr_mask; pcr_index++, pcr_mask >>= 1) { -+ for (pcr_index = 0; pcr_mask; pcr_index++, pcr_mask >>= 1) { - if (pcr_mask & 1) - json_object_array_add(pcrs, json_object_new_int(pcr_index)); - } -@@ -315,7 +315,7 @@ sdb_policy_file_add_entry(const char *fi - goto out; - - sdb_policy_entry_set_pcr_mask(entry, pcr_mask); -- json_object_object_add(entry, "pfkp", -+ json_object_object_add(entry, "pkfp", - json_object_new_string(print_hex_string(fingerprint, fingerprint_len))); - json_object_object_add(entry, "sig", - json_object_new_string(print_base64_value(signature, signature_len))); diff --git a/pcr-oracle-0.5.3.tar.xz b/pcr-oracle-0.5.3.tar.xz deleted file mode 100644 index fb394b1..0000000 --- a/pcr-oracle-0.5.3.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc53ad505c90d59675f87bd00769d7be8a6c9a3fbfa30c8013dc26d2f9a96bf7 -size 80368 diff --git a/pcr-oracle-0.5.4.tar.xz b/pcr-oracle-0.5.4.tar.xz new file mode 100644 index 0000000..4df482d --- /dev/null +++ b/pcr-oracle-0.5.4.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:130085dbd77b8e4001356cbe9411829228eb29cdd6f14931aea5ecb57c75a2e6 +size 81828 diff --git a/pcr-oracle.changes b/pcr-oracle.changes index 3c7c3d0..41c6959 100644 --- a/pcr-oracle.changes +++ b/pcr-oracle.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Fri Dec 8 07:17:35 UTC 2023 - Gary Ching-Pang Lin + +- Update to 0.5.4 + - Improve systemd-boot support + - Add --boot-entry for systemd-boot + - Manpage fixes + - Fix PCR index in JSON file + - Fix GrubPcrSnapshot parsing +- Drop upstreamed patches: boot_entry.patch and fix_pcr_index.patch + ------------------------------------------------------------------- Wed Nov 29 15:56:39 UTC 2023 - Alberto Planas Dominguez diff --git a/pcr-oracle.spec b/pcr-oracle.spec index d44ca61..2949abd 100644 --- a/pcr-oracle.spec +++ b/pcr-oracle.spec @@ -18,17 +18,13 @@ Name: pcr-oracle -Version: 0.5.3 +Version: 0.5.4 Release: 0 Summary: Predict TPM PCR values License: GPL-2.0-only Group: System/Boot URL: https://github.com/okirch/pcr-oracle Source: %{name}-%{version}.tar.xz -# PATCH-FEATURE-UPSTREAM boot_entry.patch gh#okirch/pcr-oracle#40 -Patch1: boot_entry.patch -# PATCH-FEATURE-UPSTREAM boot_entry.patch gh#okirch/pcr-oracle#44 -Patch2: fix_pcr_index.patch BuildRequires: libopenssl-devel >= 0.9.8 BuildRequires: tpm2-0-tss-devel >= 2.4.0 Requires: libtss2-tcti-device0