diff options
Diffstat (limited to '')
12 files changed, 1193 insertions, 0 deletions
diff --git a/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch new file mode 100644 index 000000000..a67217c02 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch @@ -0,0 +1,91 @@ +From: David Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:56 +0100 +Subject: [PATCH 1/7] KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=40db8fc497d010ae6cee6297c3882d3dc3d76d48 + +Allow keys to be added to the system secondary certificates keyring during +kernel initialisation in an unrestricted fashion. Such keys are implicitly +trusted and don't have their trust chains checked on link. + +This allows keys in the UEFI database to be added in secure boot mode for +the purposes of module signing. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/internal.h | 18 ++++++++++++++++++ + certs/system_keyring.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + create mode 100644 certs/internal.h + +Index: linux/certs/internal.h +=================================================================== +--- /dev/null ++++ linux/certs/internal.h +@@ -0,0 +1,18 @@ ++/* Internal definitions ++ * ++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++/* ++ * system_keyring.c ++ */ ++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING ++extern void __init add_trusted_secondary_key(const char *source, ++ const void *data, size_t len); ++#endif +Index: linux/certs/system_keyring.c +=================================================================== +--- linux.orig/certs/system_keyring.c ++++ linux/certs/system_keyring.c +@@ -19,6 +19,7 @@ + #include <keys/asymmetric-type.h> + #include <keys/system_keyring.h> + #include <crypto/pkcs7.h> ++#include "internal.h" + + static struct key *builtin_trusted_keys; + #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING +@@ -266,3 +267,35 @@ error: + EXPORT_SYMBOL_GPL(verify_pkcs7_signature); + + #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ ++ ++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING ++/** ++ * add_trusted_secondary_key - Add to secondary keyring with no validation ++ * @source: Source of key ++ * @data: The blob holding the key ++ * @len: The length of the data blob ++ * ++ * Add a key to the secondary keyring without checking its trust chain. This ++ * is available only during kernel initialisation. ++ */ ++void __init add_trusted_secondary_key(const char *source, ++ const void *data, size_t len) ++{ ++ key_ref_t key; ++ ++ key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1), ++ "asymmetric", ++ NULL, data, len, ++ (KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW, ++ KEY_ALLOC_NOT_IN_QUOTA | ++ KEY_ALLOC_BYPASS_RESTRICTION); ++ ++ if (IS_ERR(key)) ++ pr_err("Problem loading %s X.509 certificate (%ld)\n", ++ source, PTR_ERR(key)); ++ else ++ pr_notice("Loaded %s cert '%s' linked to secondary sys keyring\n", ++ source, key_ref_to_ptr(key)->description); ++} ++#endif /* CONFIG_SECONDARY_TRUSTED_KEYRING */ diff --git a/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch new file mode 100644 index 000000000..d36028413 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch @@ -0,0 +1,64 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:37:59 +0800 +Subject: [PATCH 1/5] MODSIGN: do not load mok when secure boot disabled +Origin: https://lore.kernel.org/patchwork/patch/933173/ + +The mok can not be trusted when the secure boot is disabled. Which +means that the kernel embedded certificate is the only trusted key. + +Due to db/dbx are authenticated variables, they needs manufacturer's +KEK for update. So db/dbx are secure when secureboot disabled. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -171,17 +171,6 @@ static int __init load_uefi_certs(void) + } + } + +- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); +- if (rc < 0) { +- pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); +- } else if (moksize != 0) { +- rc = parse_efi_signature_list("UEFI:MokListRT", +- mok, moksize, get_handler_for_db); +- if (rc) +- pr_err("Couldn't parse MokListRT signatures: %d\n", rc); +- kfree(mok); +- } +- + rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); +@@ -194,6 +183,21 @@ static int __init load_uefi_certs(void) + kfree(dbx); + } + ++ /* the MOK can not be trusted when secure boot is disabled */ ++ if (!efi_enabled(EFI_SECURE_BOOT)) ++ return 0; ++ ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ if (rc < 0) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); ++ } else if (moksize != 0) { ++ rc = parse_efi_signature_list("UEFI:MokListRT", ++ mok, moksize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); ++ kfree(mok); ++ } ++ + return rc; + } + late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch new file mode 100644 index 000000000..d23b7ac98 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch @@ -0,0 +1,60 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:01 +0800 +Subject: [PATCH 2/4] MODSIGN: load blacklist from MOKx +Origin: https://lore.kernel.org/patchwork/patch/933177/ + +This patch adds the logic to load the blacklisted hash and +certificates from MOKx which is maintained by shim bootloader. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -148,8 +148,8 @@ static int __init load_uefi_certs(void) + { + efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; +- void *db = NULL, *dbx = NULL, *mok = NULL; +- unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ void *db = NULL, *dbx = NULL, *mok = NULL, *mokx = NULL; ++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0, mokxsize = 0; + int rc = 0; + + if (!efi.get_variable) +@@ -183,7 +183,7 @@ static int __init load_uefi_certs(void) + kfree(dbx); + } + +- /* the MOK can not be trusted when secure boot is disabled */ ++ /* the MOK and MOKx can not be trusted when secure boot is disabled */ + if (!efi_enabled(EFI_SECURE_BOOT)) + return 0; + +@@ -198,6 +198,18 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + ++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx); ++ if (rc < 0) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n"); ++ } else if (mokxsize != 0) { ++ rc = parse_efi_signature_list("UEFI:mokx", ++ mokx, mokxsize, ++ get_handler_for_dbx); ++ if (rc) ++ pr_err("Couldn't parse MokListXRT signatures: %d\n", rc); ++ kfree(mokx); ++ } ++ + return rc; + } + late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch new file mode 100644 index 000000000..bf8d40768 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch @@ -0,0 +1,57 @@ +From: Dave Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:58 +0100 +Subject: [PATCH 2/7] efi: Add EFI signature data types +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=446e0e29d7d53fe7786d33603df5a6682dd00c12 + +Add the data types that are used for containing hashes, keys and +certificates for cryptographic verification along with their corresponding +type GUIDs. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + include/linux/efi.h | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -663,6 +663,10 @@ void efi_native_runtime_setup(void); + #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) + #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) + ++#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28) ++#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72) ++#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed) ++ + /* + * This GUID is used to pass to the kernel proper the struct screen_info + * structure that was populated by the stub based on the GOP protocol instance +@@ -934,6 +938,27 @@ typedef struct { + efi_memory_desc_t entry[0]; + } efi_memory_attributes_table_t; + ++typedef struct { ++ efi_guid_t signature_owner; ++ u8 signature_data[]; ++} efi_signature_data_t; ++ ++typedef struct { ++ efi_guid_t signature_type; ++ u32 signature_list_size; ++ u32 signature_header_size; ++ u32 signature_size; ++ u8 signature_header[]; ++ /* efi_signature_data_t signatures[][] */ ++} efi_signature_list_t; ++ ++typedef u8 efi_sha256_hash_t[32]; ++ ++typedef struct { ++ efi_sha256_hash_t to_be_signed_hash; ++ efi_time_t time_of_revocation; ++} efi_cert_x509_sha256_t; ++ + /* + * All runtime access to EFI goes through this structure: + */ diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch new file mode 100644 index 000000000..1a43ca553 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch @@ -0,0 +1,129 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:02 +0800 +Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a + kernel module +Origin: https://lore.kernel.org/patchwork/patch/933175/ + +This patch adds the logic for checking the kernel module's hash +base on blacklist. The hash must be generated by sha256 and enrolled +to dbx/mokx. + +For example: + sha256sum sample.ko + mokutil --mokx --import-hash $HASH_RESULT + +Whether the signature on ko file is stripped or not, the hash can be +compared by kernel. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + kernel/module_signing.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 60 insertions(+), 2 deletions(-) + +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -11,9 +11,12 @@ + + #include <linux/kernel.h> + #include <linux/errno.h> ++#include <linux/module.h> + #include <linux/string.h> + #include <linux/verification.h> + #include <crypto/public_key.h> ++#include <crypto/hash.h> ++#include <keys/system_keyring.h> + #include "module-internal.h" + + enum pkey_id_type { +@@ -42,19 +45,67 @@ struct module_signature { + __be32 sig_len; /* Length of signature data */ + }; + ++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen) ++{ ++ struct crypto_shash *tfm; ++ struct shash_desc *desc; ++ size_t digest_size, desc_size; ++ u8 *digest; ++ int ret = 0; ++ ++ tfm = crypto_alloc_shash("sha256", 0, 0); ++ if (IS_ERR(tfm)) ++ goto error_return; ++ ++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); ++ digest_size = crypto_shash_digestsize(tfm); ++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL); ++ if (!digest) { ++ pr_err("digest memory buffer allocate fail\n"); ++ ret = -ENOMEM; ++ goto error_digest; ++ } ++ desc = (void *)digest + digest_size; ++ desc->tfm = tfm; ++ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; ++ ret = crypto_shash_init(desc); ++ if (ret < 0) ++ goto error_shash; ++ ++ ret = crypto_shash_finup(desc, mod, verifylen, digest); ++ if (ret < 0) ++ goto error_shash; ++ ++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest); ++ ++ ret = is_hash_blacklisted(digest, digest_size, "bin"); ++ if (ret == -EKEYREJECTED) ++ pr_err("Module hash %*phN is blacklisted\n", ++ (int) digest_size, digest); ++ ++error_shash: ++ kfree(digest); ++error_digest: ++ crypto_free_shash(tfm); ++error_return: ++ return ret; ++} ++ + /* + * Verify the signature on a module. + */ + int mod_verify_sig(const void *mod, struct load_info *info) + { + struct module_signature ms; +- size_t sig_len, modlen = info->len; ++ size_t sig_len, modlen = info->len, wholelen; ++ int ret;; + + pr_devel("==>%s(,%zu)\n", __func__, modlen); + + if (modlen <= sizeof(ms)) + return -EBADMSG; + ++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1; + memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); + modlen -= sizeof(ms); + +@@ -82,8 +133,15 @@ int mod_verify_sig(const void *mod, stru + return -EBADMSG; + } + +- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ ++ /* checking hash of module is in blacklist */ ++ if (!ret) ++ ret = mod_is_hash_blacklisted(mod, wholelen); ++ ++ return ret; + } diff --git a/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch new file mode 100644 index 000000000..e82287cff --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch @@ -0,0 +1,193 @@ +From: Dave Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:58 +0100 +Subject: [PATCH 3/7] efi: Add an EFI signature blob parser +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=41a595bb0dc097c19ad377a0c32c993234aa2525 + +Add a function to parse an EFI signature blob looking for elements of +interest. A list is made up of a series of sublists, where all the +elements in a sublist are of the same type, but sublists can be of +different types. + +For each sublist encountered, the function pointed to by the +get_handler_for_guid argument is called with the type specifier GUID and +returns either a pointer to a function to handle elements of that type or +NULL if the type is not of interest. + +If the sublist is of interest, each element is passed to the handler +function in turn. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/Kconfig | 8 ++++ + certs/Makefile | 1 + + certs/efi_parser.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/efi.h | 9 ++++ + 4 files changed, 130 insertions(+) + create mode 100644 certs/efi_parser.c + +Index: linux/certs/Kconfig +=================================================================== +--- linux.orig/certs/Kconfig ++++ linux/certs/Kconfig +@@ -83,4 +83,12 @@ config SYSTEM_BLACKLIST_HASH_LIST + wrapper to incorporate the list into the kernel. Each <hash> should + be a string of hex digits. + ++config EFI_SIGNATURE_LIST_PARSER ++ bool "EFI signature list parser" ++ depends on EFI ++ select X509_CERTIFICATE_PARSER ++ help ++ This option provides support for parsing EFI signature lists for ++ X.509 certificates and turning them into keys. ++ + endmenu +Index: linux/certs/Makefile +=================================================================== +--- linux.orig/certs/Makefile ++++ linux/certs/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) + + else + obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o + endif ++obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o + + ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) + +Index: linux/certs/efi_parser.c +=================================================================== +--- /dev/null ++++ linux/certs/efi_parser.c +@@ -0,0 +1,112 @@ ++/* EFI signature/key/certificate list parser ++ * ++ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) "EFI: "fmt ++#include <linux/module.h> ++#include <linux/printk.h> ++#include <linux/err.h> ++#include <linux/efi.h> ++ ++/** ++ * parse_efi_signature_list - Parse an EFI signature list for certificates ++ * @source: The source of the key ++ * @data: The data blob to parse ++ * @size: The size of the data blob ++ * @get_handler_for_guid: Get the handler func for the sig type (or NULL) ++ * ++ * Parse an EFI signature list looking for elements of interest. A list is ++ * made up of a series of sublists, where all the elements in a sublist are of ++ * the same type, but sublists can be of different types. ++ * ++ * For each sublist encountered, the @get_handler_for_guid function is called ++ * with the type specifier GUID and returns either a pointer to a function to ++ * handle elements of that type or NULL if the type is not of interest. ++ * ++ * If the sublist is of interest, each element is passed to the handler ++ * function in turn. ++ * ++ * Error EBADMSG is returned if the list doesn't parse correctly and 0 is ++ * returned if the list was parsed correctly. No error can be returned from ++ * the @get_handler_for_guid function or the element handler function it ++ * returns. ++ */ ++int __init parse_efi_signature_list( ++ const char *source, ++ const void *data, size_t size, ++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)) ++{ ++ efi_element_handler_t handler; ++ unsigned offs = 0; ++ ++ pr_devel("-->%s(,%zu)\n", __func__, size); ++ ++ while (size > 0) { ++ const efi_signature_data_t *elem; ++ efi_signature_list_t list; ++ size_t lsize, esize, hsize, elsize; ++ ++ if (size < sizeof(list)) ++ return -EBADMSG; ++ ++ memcpy(&list, data, sizeof(list)); ++ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", ++ offs, ++ list.signature_type.b, list.signature_list_size, ++ list.signature_header_size, list.signature_size); ++ ++ lsize = list.signature_list_size; ++ hsize = list.signature_header_size; ++ esize = list.signature_size; ++ elsize = lsize - sizeof(list) - hsize; ++ ++ if (lsize > size) { ++ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", ++ __func__, offs); ++ return -EBADMSG; ++ } ++ ++ if (lsize < sizeof(list) || ++ lsize - sizeof(list) < hsize || ++ esize < sizeof(*elem) || ++ elsize < esize || ++ elsize % esize != 0) { ++ pr_devel("- bad size combo @%x\n", offs); ++ return -EBADMSG; ++ } ++ ++ handler = get_handler_for_guid(&list.signature_type); ++ if (!handler) { ++ data += lsize; ++ size -= lsize; ++ offs += lsize; ++ continue; ++ } ++ ++ data += sizeof(list) + hsize; ++ size -= sizeof(list) + hsize; ++ offs += sizeof(list) + hsize; ++ ++ for (; elsize > 0; elsize -= esize) { ++ elem = data; ++ ++ pr_devel("ELEM[%04x]\n", offs); ++ handler(source, ++ &elem->signature_data, ++ esize - sizeof(*elem)); ++ ++ data += esize; ++ size -= esize; ++ offs += esize; ++ } ++ } ++ ++ return 0; ++} +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -1139,6 +1139,15 @@ extern int efi_memattr_apply_permissions + char * __init efi_md_typeattr_format(char *buf, size_t size, + const efi_memory_desc_t *md); + ++ ++typedef void (*efi_element_handler_t)(const char *source, ++ const void *element_data, ++ size_t element_size); ++extern int __init parse_efi_signature_list( ++ const char *source, ++ const void *data, size_t size, ++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); ++ + /** + * efi_range_is_wc - check the WC bit on an address range + * @start: starting kvirt address diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch new file mode 100644 index 000000000..cdb3b7a22 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch @@ -0,0 +1,242 @@ +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Fri, 5 May 2017 08:21:59 +0100 +Subject: [PATCH 4/7] MODSIGN: Import certificates from UEFI Secure Boot +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=7b7aae2efea13b5a7b80305856c28f235ea8b2fa + +Secure Boot stores a list of allowed certificates in the 'db' variable. +This imports those certificates into the system trusted keyring. This +allows for a third party signing certificate to be used in conjunction +with signed modules. By importing the public certificate into the 'db' +variable, a user can allow a module signed with that certificate to +load. The shim UEFI bootloader has a similar certificate list stored +in the 'MokListRT' variable. We import those as well. + +Secure Boot also maintains a list of disallowed certificates in the 'dbx' +variable. We load those certificates into the newly introduced system +blacklist keyring and forbid any module signed with those from loading and +forbid the use within the kernel of any key with a matching hash. + +This facility is enabled by setting CONFIG_LOAD_UEFI_KEYS. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/Kconfig | 16 +++++ + certs/Makefile | 4 ++ + certs/load_uefi.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 188 insertions(+) + create mode 100644 certs/load_uefi.c + +Index: linux/certs/Kconfig +=================================================================== +--- linux.orig/certs/Kconfig ++++ linux/certs/Kconfig +@@ -91,4 +91,20 @@ config EFI_SIGNATURE_LIST_PARSER + This option provides support for parsing EFI signature lists for + X.509 certificates and turning them into keys. + ++config LOAD_UEFI_KEYS ++ bool "Load certs and blacklist from UEFI db for module checking" ++ depends on SYSTEM_BLACKLIST_KEYRING ++ depends on SECONDARY_TRUSTED_KEYRING ++ depends on EFI ++ depends on EFI_SIGNATURE_LIST_PARSER ++ help ++ If the kernel is booted in secure boot mode, this option will cause ++ the kernel to load the certificates from the UEFI db and MokListRT ++ into the secondary trusted keyring. It will also load any X.509 ++ SHA256 hashes in the dbx list into the blacklist. ++ ++ The effect of this is that, if the kernel is booted in secure boot ++ mode, modules signed with UEFI-stored keys will be permitted to be ++ loaded and keys that match the blacklist will be rejected. ++ + endmenu +Index: linux/certs/Makefile +=================================================================== +--- linux.orig/certs/Makefile ++++ linux/certs/Makefile +@@ -12,6 +12,10 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) + + endif + obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o + ++obj-$(CONFIG_LOAD_UEFI_KEYS) += load_uefi.o ++$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar ++ ++ + ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) + + $(eval $(call config_filename,SYSTEM_TRUSTED_KEYS)) +Index: linux/certs/load_uefi.c +=================================================================== +--- /dev/null ++++ linux/certs/load_uefi.c +@@ -0,0 +1,168 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/cred.h> ++#include <linux/err.h> ++#include <linux/efi.h> ++#include <linux/slab.h> ++#include <keys/asymmetric-type.h> ++#include <keys/system_keyring.h> ++#include "internal.h" ++ ++static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID; ++static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GUID; ++static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID; ++ ++/* ++ * Get a certificate list blob from the named EFI variable. ++ */ ++static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, ++ unsigned long *size) ++{ ++ efi_status_t status; ++ unsigned long lsize = 4; ++ unsigned long tmpdb[4]; ++ void *db; ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (status != EFI_BUFFER_TOO_SMALL) { ++ pr_err("Couldn't get size: 0x%lx\n", status); ++ return NULL; ++ } ++ ++ db = kmalloc(lsize, GFP_KERNEL); ++ if (!db) { ++ pr_err("Couldn't allocate memory for uefi cert list\n"); ++ return NULL; ++ } ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, db); ++ if (status != EFI_SUCCESS) { ++ kfree(db); ++ pr_err("Error reading db var: 0x%lx\n", status); ++ return NULL; ++ } ++ ++ *size = lsize; ++ return db; ++} ++ ++/* ++ * Blacklist an X509 TBS hash. ++ */ ++static __init void uefi_blacklist_x509_tbs(const char *source, ++ const void *data, size_t len) ++{ ++ char *hash, *p; ++ ++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL); ++ if (!hash) ++ return; ++ p = memcpy(hash, "tbs:", 4); ++ p += 4; ++ bin2hex(p, data, len); ++ p += len * 2; ++ *p = 0; ++ ++ mark_hash_blacklisted(hash); ++ kfree(hash); ++} ++ ++/* ++ * Blacklist the hash of an executable. ++ */ ++static __init void uefi_blacklist_binary(const char *source, ++ const void *data, size_t len) ++{ ++ char *hash, *p; ++ ++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL); ++ if (!hash) ++ return; ++ p = memcpy(hash, "bin:", 4); ++ p += 4; ++ bin2hex(p, data, len); ++ p += len * 2; ++ *p = 0; ++ ++ mark_hash_blacklisted(hash); ++ kfree(hash); ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI db and MokListRT tables. ++ */ ++static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type) ++{ ++ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) ++ return add_trusted_secondary_key; ++ return 0; ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI dbx and MokListXRT tables. ++ */ ++static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type) ++{ ++ if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0) ++ return uefi_blacklist_x509_tbs; ++ if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) ++ return uefi_blacklist_binary; ++ return 0; ++} ++ ++/* ++ * Load the certs contained in the UEFI databases ++ */ ++static int __init load_uefi_certs(void) ++{ ++ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; ++ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; ++ void *db = NULL, *dbx = NULL, *mok = NULL; ++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ int rc = 0; ++ ++ if (!efi.get_variable) ++ return false; ++ ++ /* Get db, MokListRT, and dbx. They might not exist, so it isn't ++ * an error if we can't get them. ++ */ ++ db = get_cert_list(L"db", &secure_var, &dbsize); ++ if (!db) { ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:db", ++ db, dbsize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse db signatures: %d\n", rc); ++ kfree(db); ++ } ++ ++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize); ++ if (!mok) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:MokListRT", ++ mok, moksize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); ++ kfree(mok); ++ } ++ ++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); ++ if (!dbx) { ++ pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:dbx", ++ dbx, dbxsize, ++ get_handler_for_dbx); ++ if (rc) ++ pr_err("Couldn't parse dbx signatures: %d\n", rc); ++ kfree(dbx); ++ } ++ ++ return rc; ++} ++late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch new file mode 100644 index 000000000..57b6e61ff --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch @@ -0,0 +1,108 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:03 +0800 +Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok +Origin: https://lore.kernel.org/patchwork/patch/933176/ + +That's better for checking the attributes of db and mok variables +before loading certificates to kernel keyring. + +For db and dbx, both of them are authenticated variables. Which +means that they can only be modified by manufacturer's key. So +the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS +attribute before we trust it. + +For mok-rt and mokx-rt, both of them are created by shim boot loader +to forward the mok/mokx content to runtime. They must be runtime-volatile +variables. So kernel should checks that the attributes map did not set +EFI_VARIABLE_NON_VOLATILE bit before we trust it. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -36,12 +36,14 @@ static __init bool uefi_check_ignore_db( + * Get a certificate list blob from the named EFI variable. + */ + static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size, void **cert_list) ++ unsigned long *size, void **cert_list, ++ u32 pos_attr, u32 neg_attr) + { + efi_status_t status; + unsigned long lsize = 4; + unsigned long tmpdb[4]; + void *db; ++ u32 attr = 0; + + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); + if (status == EFI_NOT_FOUND) { +@@ -61,12 +63,19 @@ static __init int get_cert_list(efi_char + return -ENOMEM; + } + +- status = efi.get_variable(name, guid, NULL, &lsize, db); ++ status = efi.get_variable(name, guid, &attr, &lsize, db); + if (status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", status); + return efi_status_to_err(status); + } ++ /* must have positive attributes and no negative attributes */ ++ if ((pos_attr && !(attr & pos_attr)) || ++ (neg_attr && (attr & neg_attr))) { ++ kfree(db); ++ pr_err("Error reading db var attributes: 0x%016x\n", attr); ++ return -1; ++ } + + *size = lsize; + *cert_list = db; +@@ -159,7 +168,8 @@ static int __init load_uefi_certs(void) + * an error if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- rc = get_cert_list(L"db", &secure_var, &dbsize, &db); ++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (rc < 0) { + pr_err("MODSIGN: Couldn't get UEFI db list\n"); + } else if (dbsize != 0) { +@@ -171,7 +181,8 @@ static int __init load_uefi_certs(void) + } + } + +- rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); ++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); + } else if (dbxsize != 0) { +@@ -187,7 +198,8 @@ static int __init load_uefi_certs(void) + if (!efi_enabled(EFI_SECURE_BOOT)) + return 0; + +- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); + } else if (moksize != 0) { +@@ -198,7 +210,8 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + +- rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx); ++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n"); + } else if (mokxsize != 0) { diff --git a/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch new file mode 100644 index 000000000..b5e2e843c --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch @@ -0,0 +1,85 @@ +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Fri, 5 May 2017 08:21:59 +0100 +Subject: [PATCH 5/7] MODSIGN: Allow the "db" UEFI variable to be suppressed +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=b51ca4e4d6c0c8000789de31a1184a41ac611d33 + +If a user tells shim to not use the certs/hashes in the UEFI db variable +for verification purposes, shim will set a UEFI variable called +MokIgnoreDB. Have the uefi import code look for this and ignore the db +variable if it is found. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/load_uefi.c | 44 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 34 insertions(+), 10 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -13,6 +13,26 @@ static __initdata efi_guid_t efi_cert_x5 + static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID; + + /* ++ * Look to see if a UEFI variable called MokIgnoreDB exists and return true if ++ * it does. ++ * ++ * This UEFI variable is set by the shim if a user tells the shim to not use ++ * the certs/hashes in the UEFI db variable for verification purposes. If it ++ * is set, we should ignore the db variable also and the true return indicates ++ * this. ++ */ ++static __init bool uefi_check_ignore_db(void) ++{ ++ efi_status_t status; ++ unsigned int db = 0; ++ unsigned long size = sizeof(db); ++ efi_guid_t guid = EFI_SHIM_LOCK_GUID; ++ ++ status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db); ++ return status == EFI_SUCCESS; ++} ++ ++/* + * Get a certificate list blob from the named EFI variable. + */ + static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +@@ -113,7 +133,9 @@ static __init efi_element_handler_t get_ + } + + /* +- * Load the certs contained in the UEFI databases ++ * Load the certs contained in the UEFI databases into the secondary trusted ++ * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist ++ * keyring. + */ + static int __init load_uefi_certs(void) + { +@@ -129,15 +151,17 @@ static int __init load_uefi_certs(void) + /* Get db, MokListRT, and dbx. They might not exist, so it isn't + * an error if we can't get them. + */ +- db = get_cert_list(L"db", &secure_var, &dbsize); +- if (!db) { +- pr_err("MODSIGN: Couldn't get UEFI db list\n"); +- } else { +- rc = parse_efi_signature_list("UEFI:db", +- db, dbsize, get_handler_for_db); +- if (rc) +- pr_err("Couldn't parse db signatures: %d\n", rc); +- kfree(db); ++ if (!uefi_check_ignore_db()) { ++ db = get_cert_list(L"db", &secure_var, &dbsize); ++ if (!db) { ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:db", ++ db, dbsize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse db signatures: %d\n", rc); ++ kfree(db); ++ } + } + + mok = get_cert_list(L"MokListRT", &mok_var, &moksize); diff --git a/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch new file mode 100644 index 000000000..c348e2f04 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch @@ -0,0 +1,106 @@ +From: Peter Jones <pjones@redhat.com> +Date: Mon, 2 Oct 2017 18:25:29 -0400 +Subject: [PATCH 6/7] Make get_cert_list() not complain about cert lists that + aren't present. +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=0f4d5c7b49b45e7cf038bb769e33451b78a6445d + +Signed-off-by: Peter Jones <pjones@redhat.com> +--- + certs/load_uefi.c | 37 ++++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -35,8 +35,8 @@ static __init bool uefi_check_ignore_db( + /* + * Get a certificate list blob from the named EFI variable. + */ +-static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size) ++static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, ++ unsigned long *size, void **cert_list) + { + efi_status_t status; + unsigned long lsize = 4; +@@ -44,26 +44,33 @@ static __init void *get_cert_list(efi_ch + void *db; + + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (status == EFI_NOT_FOUND) { ++ *size = 0; ++ *cert_list = NULL; ++ return 0; ++ } ++ + if (status != EFI_BUFFER_TOO_SMALL) { + pr_err("Couldn't get size: 0x%lx\n", status); +- return NULL; ++ return efi_status_to_err(status); + } + + db = kmalloc(lsize, GFP_KERNEL); + if (!db) { + pr_err("Couldn't allocate memory for uefi cert list\n"); +- return NULL; ++ return -ENOMEM; + } + + status = efi.get_variable(name, guid, NULL, &lsize, db); + if (status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", status); +- return NULL; ++ return efi_status_to_err(status); + } + + *size = lsize; +- return db; ++ *cert_list = db; ++ return 0; + } + + /* +@@ -152,10 +159,10 @@ static int __init load_uefi_certs(void) + * an error if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- db = get_cert_list(L"db", &secure_var, &dbsize); +- if (!db) { ++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db); ++ if (rc < 0) { + pr_err("MODSIGN: Couldn't get UEFI db list\n"); +- } else { ++ } else if (dbsize != 0) { + rc = parse_efi_signature_list("UEFI:db", + db, dbsize, get_handler_for_db); + if (rc) +@@ -164,10 +171,10 @@ static int __init load_uefi_certs(void) + } + } + +- mok = get_cert_list(L"MokListRT", &mok_var, &moksize); +- if (!mok) { ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); +- } else { ++ } else if (moksize != 0) { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); + if (rc) +@@ -175,10 +182,10 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + +- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); +- if (!dbx) { ++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); ++ if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); +- } else { ++ } else if (dbxsize != 0) { + rc = parse_efi_signature_list("UEFI:dbx", + dbx, dbxsize, + get_handler_for_dbx); diff --git a/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch new file mode 100644 index 000000000..b831869e4 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch @@ -0,0 +1,28 @@ +From: Ke Wu <mikewu@google.com> +Date: Tue, 6 Nov 2018 15:21:30 -0800 +Subject: modsign: use all trusted keys to verify module signature +Origin: https://git.kernel.org/linus/e84cd7ee630e44a2cc8ae49e85920a271b214cb3 + +Make mod_verify_sig to use all trusted keys. This allows keys in +secondary_trusted_keys to be used to verify PKCS#7 signature on a +kernel module. + +Signed-off-by: Ke Wu <mikewu@google.com> +Signed-off-by: Jessica Yu <jeyu@kernel.org> +--- + kernel/module_signing.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -83,6 +83,7 @@ int mod_verify_sig(const void *mod, stru + } + + return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, +- NULL, VERIFYING_MODULE_SIGNATURE, ++ VERIFY_USE_SECONDARY_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + } diff --git a/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch new file mode 100644 index 000000000..a0aea95a2 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch @@ -0,0 +1,30 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 05 May 2019 13:45:06 +0100 +Subject: MODSIGN: Make shash allocation failure fatal + +mod_is_hash_blacklisted() currently returns 0 (suceess) if +crypto_alloc_shash() fails. This should instead be a fatal error, +so unwrap and pass up the error code. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -51,11 +51,13 @@ static int mod_is_hash_blacklisted(const + struct shash_desc *desc; + size_t digest_size, desc_size; + u8 *digest; +- int ret = 0; ++ int ret; + + tfm = crypto_alloc_shash("sha256", 0, 0); +- if (IS_ERR(tfm)) ++ if (IS_ERR(tfm)) { ++ ret = PTR_ERR(tfm); + goto error_return; ++ } + + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); + digest_size = crypto_shash_digestsize(tfm); |