From 5fdcd2c3089343b4e88ec95fcb76c1abf8e9ec10 Mon Sep 17 00:00:00 2001 From: DistroBaker Date: Fri, 26 Mar 2021 19:57:01 +0000 Subject: [PATCH] Merged update from upstream sources This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/mokutil.git#caaa4205782a12bac5a9d893baa27243f99264d2 --- ...on-to-print-the-UEFI-SBAT-variable-c.patch | 124 +++++++++ ...il-add-mok-variables-parsing-support.patch | 241 ++++++++++++++++++ mokutil.spec | 7 +- 3 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch create mode 100644 0004-mokutil-add-mok-variables-parsing-support.patch diff --git a/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch b/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch new file mode 100644 index 0000000..34f7fbc --- /dev/null +++ b/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch @@ -0,0 +1,124 @@ +From 698994102afcbbe16e65930a09e0df5248c4d200 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 17 Mar 2021 14:38:57 +0100 +Subject: [PATCH] mokutil: Add option to print the UEFI SBAT variable content + +This variable contains the descriptive form of all the components used by +the operating systems that ship signed shim binaries. Along with a minimum +generation number for each component. More information in can be found in +the UEFI Secure Boot Advanced Targeting (SBAT) specification: + + https://github.com/rhboot/shim/blob/main/SBAT.md + +Since a SBAT variable contains a set of Comma Separated Values (CSV) UTF-8 +encoded strings, the data could just be printed without the need to do any +previous processing. + +Signed-off-by: Javier Martinez Canillas +--- + man/mokutil.1 | 5 +++++ + src/mokutil.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/man/mokutil.1 b/man/mokutil.1 +index 25fe8b433da..446298763ad 100644 +--- a/man/mokutil.1 ++++ b/man/mokutil.1 +@@ -73,6 +73,8 @@ mokutil \- utility to manipulate machine owner keys + .br + \fBmokutil\fR [--dbx] + .br ++\fBmokutil\fR [--sbat] ++.br + + .SH DESCRIPTION + \fBmokutil\fR is a tool to import or delete the machines owner keys +@@ -173,3 +175,6 @@ List the keys in the secure boot signature store (db) + \fB--dbx\fR + List the keys in the secure boot blacklist signature store (dbx) + .TP ++\fB--sbat\fR ++List the entries in the Secure Boot Advanced Targeting store (SBAT) ++.TP +diff --git a/src/mokutil.c b/src/mokutil.c +index b66c1b8b5a7..0c25ae5033d 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -84,6 +84,7 @@ + #define DELETE_HASH (1 << 22) + #define VERBOSITY (1 << 23) + #define TIMEOUT (1 << 24) ++#define LIST_SBAT (1 << 25) + + #define DEFAULT_CRYPT_METHOD SHA512_BASED + #define DEFAULT_SALT_SIZE SHA512_SALT_MAX +@@ -176,6 +177,7 @@ print_help () + printf (" --db\t\t\t\t\tList the keys in db\n"); + printf (" --dbx\t\t\t\t\tList the keys in dbx\n"); + printf (" --timeout <-1,0..0x7fff>\t\tSet the timeout for MOK prompt\n"); ++ printf (" --sbat\t\t\t\tList the entries in SBAT\n"); + printf ("\n"); + printf ("Supplimentary Options:\n"); + printf (" --hash-file \t\tUse the specific password hash\n"); +@@ -1598,6 +1600,31 @@ error: + return ret; + } + ++static int ++print_var_content (const char *var_name, const efi_guid_t guid) ++{ ++ uint8_t *data = NULL; ++ size_t data_size; ++ uint32_t attributes; ++ int ret; ++ ++ ret = efi_get_variable (guid, var_name, &data, &data_size, &attributes); ++ if (ret < 0) { ++ if (errno == ENOENT) { ++ printf ("%s is empty\n", var_name); ++ return 0; ++ } ++ ++ fprintf (stderr, "Failed to read %s: %m\n", var_name); ++ return -1; ++ } ++ ++ printf ("%s", data); ++ free (data); ++ ++ return ret; ++} ++ + static int + revoke_request (MokRequest req) + { +@@ -2187,6 +2214,7 @@ main (int argc, char *argv[]) + {"kek", no_argument, 0, 0 }, + {"db", no_argument, 0, 0 }, + {"dbx", no_argument, 0, 0 }, ++ {"sbat", no_argument, 0, 0 }, + {"timeout", required_argument, 0, 0 }, + {0, 0, 0, 0} + }; +@@ -2271,6 +2299,8 @@ main (int argc, char *argv[]) + } else { + db_name = DBX; + } ++ } else if (strcmp (option, "sbat") == 0) { ++ command |= LIST_SBAT; + } else if (strcmp (option, "timeout") == 0) { + command |= TIMEOUT; + timeout = strdup (optarg); +@@ -2543,6 +2573,9 @@ main (int argc, char *argv[]) + case TIMEOUT: + ret = set_timeout (timeout); + break; ++ case LIST_SBAT: ++ ret = print_var_content ("SBAT", efi_guid_shim); ++ break; + default: + print_help (); + break; +-- +2.29.2 + diff --git a/0004-mokutil-add-mok-variables-parsing-support.patch b/0004-mokutil-add-mok-variables-parsing-support.patch new file mode 100644 index 0000000..88ea983 --- /dev/null +++ b/0004-mokutil-add-mok-variables-parsing-support.patch @@ -0,0 +1,241 @@ +From 256639accc910e60496fffef96128dc1afd0fa3a Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 17 Mar 2021 14:49:21 +0100 +Subject: [PATCH] mokutil: add mok-variables parsing support + +his patch adds support for getting mok variables from +/sys/firmware/efi/mok-variables/$NAME , if they are present, as well as +for checking MokListRT, MokListRT1, MokListRT2, etc., for any of the mok +variables. + +Signed-off-by: Peter Jones +--- + src/mokutil.c | 175 +++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 151 insertions(+), 24 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 0c25ae5033d..252dc7a327f 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -251,6 +251,63 @@ signature_size (const efi_guid_t *hash_type) + return 0; + } + ++static int ++mok_get_variable(const char *name, uint8_t **datap, size_t *data_sizep) ++{ ++ char filename[] = "/sys/firmware/efi/mok-variables/implausibly-long-mok-variable-name"; ++ size_t filename_sz = sizeof(filename); ++ int fd, rc; ++ struct stat sb = { 0, }; ++ uint8_t *buf; ++ size_t bufsz, pos = 0; ++ ssize_t ssz; ++ ++ *datap = 0; ++ *data_sizep = 0; ++ ++ snprintf(filename, filename_sz, "/sys/firmware/efi/mok-variables/%s", name); ++ ++ fd = open(filename, O_RDONLY); ++ if (fd < 0) ++ return fd; ++ ++ rc = fstat(fd, &sb); ++ if (rc < 0) { ++err_close: ++ close(fd); ++ return rc; ++ } ++ ++ if (sb.st_size == 0) { ++ errno = ENOENT; ++ rc = -1; ++ goto err_close; ++ } ++ ++ bufsz = sb.st_size; ++ buf = calloc(1, bufsz); ++ if (!buf) ++ goto err_close; ++ ++ while (pos < bufsz) { ++ ssz = read(fd, &buf[pos], bufsz - pos); ++ if (ssz < 0) { ++ if (errno == EAGAIN || ++ errno == EWOULDBLOCK || ++ errno == EINTR) ++ continue; ++ free(buf); ++ goto err_close; ++ } ++ ++ pos += ssz; ++ } ++ *datap = buf; ++ *data_sizep = pos; ++ ++ return 0; ++} ++ + static MokListNode* + build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) + { +@@ -622,25 +679,44 @@ static int + list_keys_in_var (const char *var_name, const efi_guid_t guid) + { + uint8_t *data = NULL; +- size_t data_size; ++ char varname[] = "implausibly-long-mok-variable-name"; ++ size_t data_sz, i, varname_sz = sizeof(varname); + uint32_t attributes; + int ret; + +- ret = efi_get_variable (guid, var_name, &data, &data_size, &attributes); +- if (ret < 0) { +- if (errno == ENOENT) { +- printf ("%s is empty\n", var_name); +- return 0; ++ ret = mok_get_variable(var_name, &data, &data_sz); ++ if (ret >= 0) { ++ ret = list_keys (data, data_sz); ++ free(data); ++ return ret; ++ } ++ ++ for (i = 0; i < SIZE_MAX; i++) { ++ if (i == 0) { ++ snprintf(varname, varname_sz, "%s", var_name); ++ } else { ++ snprintf(varname, varname_sz, "%s%zu", var_name, i); + } + +- fprintf (stderr, "Failed to read %s: %m\n", var_name); +- return -1; +- } ++ ret = efi_get_variable (guid, varname, &data, &data_sz, ++ &attributes); ++ if (ret < 0) ++ return 0; + +- ret = list_keys (data, data_size); +- free (data); ++ ret = list_keys (data, data_sz); ++ free(data); ++ /* ++ * If ret is < 0, the next one will error as well. ++ * If ret is 0, we need to test the next variable. ++ * If it's 1, that's a real answer. ++ */ ++ if (ret < 0) ++ return 0; ++ if (ret > 0) ++ return ret; ++ } + +- return ret; ++ return 0; + } + + static int +@@ -1039,22 +1115,15 @@ is_valid_cert (void *cert, uint32_t cert_size) + } + + static int +-is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size, +- const efi_guid_t *vendor, const char *db_name) ++is_one_duplicate (const efi_guid_t *type, ++ const void *data, const uint32_t data_size, ++ uint8_t *var_data, size_t var_data_size) + { +- uint8_t *var_data; +- size_t var_data_size; +- uint32_t attributes; + uint32_t node_num; + MokListNode *list; + int ret = 0; + +- if (!data || data_size == 0 || !db_name) +- return 0; +- +- ret = efi_get_variable (*vendor, db_name, &var_data, &var_data_size, +- &attributes); +- if (ret < 0) ++ if (!data || data_size == 0) + return 0; + + list = build_mok_list (var_data, var_data_size, &node_num); +@@ -1087,11 +1156,69 @@ is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size + done: + if (list) + free (list); +- free (var_data); + + return ret; + } + ++static int ++is_duplicate (const efi_guid_t *type, ++ const void *data, const uint32_t data_size, ++ const efi_guid_t *vendor, const char *db_name) ++{ ++ uint32_t attributes; ++ char varname[] = "implausibly-long-mok-variable-name"; ++ size_t varname_sz = sizeof(varname); ++ int ret = 0; ++ size_t i; ++ ++ if (!strncmp(db_name, "Mok", 3)) { ++ uint8_t *var_data = NULL; ++ size_t var_data_size = 0; ++ ret = mok_get_variable(db_name, &var_data, &var_data_size); ++ if (ret >= 0) { ++ ret = is_one_duplicate(type, data, data_size, ++ var_data, var_data_size); ++ if (ret >= 0) { ++ free (var_data); ++ return ret; ++ } ++ var_data = NULL; ++ var_data_size = 0; ++ } ++ } ++ ++ for (i = 0; i < SIZE_MAX; i++) { ++ uint8_t *var_data = NULL; ++ size_t var_data_size = 0; ++ if (i == 0) { ++ snprintf(varname, varname_sz, "%s", db_name); ++ } else { ++ snprintf(varname, varname_sz, "%s%zu", db_name, i); ++ } ++ ++ ret = efi_get_variable (*vendor, varname, ++ &var_data, &var_data_size, ++ &attributes); ++ if (ret < 0) ++ return 0; ++ ++ ret = is_one_duplicate(type, data, data_size, ++ var_data, var_data_size); ++ free (var_data); ++ /* ++ * If ret is < 0, the next one will error as well. ++ * If ret is 0, we need to test the next variable. ++ * If it's 1, that's a real answer. ++ */ ++ if (ret < 0) ++ return 0; ++ if (ret > 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int + is_valid_request (const efi_guid_t *type, void *mok, uint32_t mok_size, + MokRequest req) +-- +2.29.2 + diff --git a/mokutil.spec b/mokutil.spec index 28291b2..e6de976 100644 --- a/mokutil.spec +++ b/mokutil.spec @@ -1,6 +1,6 @@ Name: mokutil Version: 0.4.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 2 Summary: Tool to manage UEFI Secure Boot MoK Keys License: GPLv3+ @@ -16,6 +16,8 @@ Obsoletes: mokutil < 0.2.0 Patch0001: 0001-Avoid-taking-pointer-to-packed-struct.patch Patch0002: 0002-Fix-a-integer-comparison-sign-issue.patch +Patch0003: 0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch +Patch0004: 0004-mokutil-add-mok-variables-parsing-support.patch %description mokutil provides a tool to manage keys for Secure Boot through the MoK @@ -50,6 +52,9 @@ make PREFIX=%{_prefix} LIBDIR=%{_libdir} DESTDIR=%{buildroot} install %{_datadir}/bash-completion/completions/mokutil %changelog +* Wed Mar 17 2021 Javier Martinez Canillas - 0.4.0-4 +- Add SBAT and mok-variables support + * Tue Jan 26 2021 Fedora Release Engineering - 2:0.4.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild