From: Sasha Levin Date: Mon, 28 Jun 2021 13:48:43 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v5.12.14~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=210cf2da85100de7425bde07492407febc1f400d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/certs-add-efi_cert_x509_guid-support-for-dbx-entries.patch b/queue-5.4/certs-add-efi_cert_x509_guid-support-for-dbx-entries.patch new file mode 100644 index 00000000000..bb79ccd7df2 --- /dev/null +++ b/queue-5.4/certs-add-efi_cert_x509_guid-support-for-dbx-entries.patch @@ -0,0 +1,225 @@ +From 5887ffd6dd44f47a80bbbc535480f1fe2eb8c857 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 13:10:51 -0500 +Subject: certs: Add EFI_CERT_X509_GUID support for dbx entries +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Snowberg + +[ Upstream commit 56c5812623f95313f6a46fbf0beee7fa17c68bbf ] + +This fixes CVE-2020-26541. + +The Secure Boot Forbidden Signature Database, dbx, contains a list of now +revoked signatures and keys previously approved to boot with UEFI Secure +Boot enabled. The dbx is capable of containing any number of +EFI_CERT_X509_SHA256_GUID, EFI_CERT_SHA256_GUID, and EFI_CERT_X509_GUID +entries. + +Currently when EFI_CERT_X509_GUID are contained in the dbx, the entries are +skipped. + +Add support for EFI_CERT_X509_GUID dbx entries. When a EFI_CERT_X509_GUID +is found, it is added as an asymmetrical key to the .blacklist keyring. +Anytime the .platform keyring is used, the keys in the .blacklist keyring +are referenced, if a matching key is found, the key will be rejected. + +[DH: Made the following changes: + - Added to have a config option to enable the facility. This allows a + Kconfig solution to make sure that pkcs7_validate_trust() is + enabled.[1][2] + - Moved the functions out from the middle of the blacklist functions. + - Added kerneldoc comments.] + +Signed-off-by: Eric Snowberg +Signed-off-by: David Howells +Reviewed-by: Jarkko Sakkinen +cc: Randy Dunlap +cc: Mickaël Salaün +cc: Arnd Bergmann +cc: keyrings@vger.kernel.org +Link: https://lore.kernel.org/r/20200901165143.10295-1-eric.snowberg@oracle.com/ # rfc +Link: https://lore.kernel.org/r/20200909172736.73003-1-eric.snowberg@oracle.com/ # v2 +Link: https://lore.kernel.org/r/20200911182230.62266-1-eric.snowberg@oracle.com/ # v3 +Link: https://lore.kernel.org/r/20200916004927.64276-1-eric.snowberg@oracle.com/ # v4 +Link: https://lore.kernel.org/r/20210122181054.32635-2-eric.snowberg@oracle.com/ # v5 +Link: https://lore.kernel.org/r/161428672051.677100.11064981943343605138.stgit@warthog.procyon.org.uk/ +Link: https://lore.kernel.org/r/161433310942.902181.4901864302675874242.stgit@warthog.procyon.org.uk/ # v2 +Link: https://lore.kernel.org/r/161529605075.163428.14625520893961300757.stgit@warthog.procyon.org.uk/ # v3 +Link: https://lore.kernel.org/r/bc2c24e3-ed68-2521-0bf4-a1f6be4a895d@infradead.org/ [1] +Link: https://lore.kernel.org/r/20210225125638.1841436-1-arnd@kernel.org/ [2] +Signed-off-by: Sasha Levin +--- + certs/Kconfig | 9 ++++ + certs/blacklist.c | 43 +++++++++++++++++++ + certs/blacklist.h | 2 + + certs/system_keyring.c | 6 +++ + include/keys/system_keyring.h | 15 +++++++ + .../platform_certs/keyring_handler.c | 11 +++++ + 6 files changed, 86 insertions(+) + +diff --git a/certs/Kconfig b/certs/Kconfig +index c94e93d8bccf..76e469b56a77 100644 +--- a/certs/Kconfig ++++ b/certs/Kconfig +@@ -83,4 +83,13 @@ config SYSTEM_BLACKLIST_HASH_LIST + wrapper to incorporate the list into the kernel. Each should + be a string of hex digits. + ++config SYSTEM_REVOCATION_LIST ++ bool "Provide system-wide ring of revocation certificates" ++ depends on SYSTEM_BLACKLIST_KEYRING ++ depends on PKCS7_MESSAGE_PARSER=y ++ help ++ If set, this allows revocation certificates to be stored in the ++ blacklist keyring and implements a hook whereby a PKCS#7 message can ++ be checked to see if it matches such a certificate. ++ + endmenu +diff --git a/certs/blacklist.c b/certs/blacklist.c +index f1c434b04b5e..59b2f106b294 100644 +--- a/certs/blacklist.c ++++ b/certs/blacklist.c +@@ -144,6 +144,49 @@ int is_binary_blacklisted(const u8 *hash, size_t hash_len) + } + EXPORT_SYMBOL_GPL(is_binary_blacklisted); + ++#ifdef CONFIG_SYSTEM_REVOCATION_LIST ++/** ++ * add_key_to_revocation_list - Add a revocation certificate to the blacklist ++ * @data: The data blob containing the certificate ++ * @size: The size of data blob ++ */ ++int add_key_to_revocation_list(const char *data, size_t size) ++{ ++ key_ref_t key; ++ ++ key = key_create_or_update(make_key_ref(blacklist_keyring, true), ++ "asymmetric", ++ NULL, ++ data, ++ size, ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW), ++ KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); ++ ++ if (IS_ERR(key)) { ++ pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); ++ return PTR_ERR(key); ++ } ++ ++ return 0; ++} ++ ++/** ++ * is_key_on_revocation_list - Determine if the key for a PKCS#7 message is revoked ++ * @pkcs7: The PKCS#7 message to check ++ */ ++int is_key_on_revocation_list(struct pkcs7_message *pkcs7) ++{ ++ int ret; ++ ++ ret = pkcs7_validate_trust(pkcs7, blacklist_keyring); ++ ++ if (ret == 0) ++ return -EKEYREJECTED; ++ ++ return -ENOKEY; ++} ++#endif ++ + /* + * Initialise the blacklist + */ +diff --git a/certs/blacklist.h b/certs/blacklist.h +index 1efd6fa0dc60..51b320cf8574 100644 +--- a/certs/blacklist.h ++++ b/certs/blacklist.h +@@ -1,3 +1,5 @@ + #include ++#include ++#include + + extern const char __initconst *const blacklist_hashes[]; +diff --git a/certs/system_keyring.c b/certs/system_keyring.c +index 798291177186..cc165b359ea3 100644 +--- a/certs/system_keyring.c ++++ b/certs/system_keyring.c +@@ -241,6 +241,12 @@ int verify_pkcs7_message_sig(const void *data, size_t len, + pr_devel("PKCS#7 platform keyring is not available\n"); + goto error; + } ++ ++ ret = is_key_on_revocation_list(pkcs7); ++ if (ret != -ENOKEY) { ++ pr_devel("PKCS#7 platform key is on revocation list\n"); ++ goto error; ++ } + } + ret = pkcs7_validate_trust(pkcs7, trusted_keys); + if (ret < 0) { +diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h +index fb8b07daa9d1..875e002a4180 100644 +--- a/include/keys/system_keyring.h ++++ b/include/keys/system_keyring.h +@@ -31,6 +31,7 @@ extern int restrict_link_by_builtin_and_secondary_trusted( + #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted + #endif + ++extern struct pkcs7_message *pkcs7; + #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING + extern int mark_hash_blacklisted(const char *hash); + extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, +@@ -49,6 +50,20 @@ static inline int is_binary_blacklisted(const u8 *hash, size_t hash_len) + } + #endif + ++#ifdef CONFIG_SYSTEM_REVOCATION_LIST ++extern int add_key_to_revocation_list(const char *data, size_t size); ++extern int is_key_on_revocation_list(struct pkcs7_message *pkcs7); ++#else ++static inline int add_key_to_revocation_list(const char *data, size_t size) ++{ ++ return 0; ++} ++static inline int is_key_on_revocation_list(struct pkcs7_message *pkcs7) ++{ ++ return -ENOKEY; ++} ++#endif ++ + #ifdef CONFIG_IMA_BLACKLIST_KEYRING + extern struct key *ima_blacklist_keyring; + +diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c +index c5ba695c10e3..5604bd57c990 100644 +--- a/security/integrity/platform_certs/keyring_handler.c ++++ b/security/integrity/platform_certs/keyring_handler.c +@@ -55,6 +55,15 @@ static __init void uefi_blacklist_binary(const char *source, + uefi_blacklist_hash(source, data, len, "bin:", 4); + } + ++/* ++ * Add an X509 cert to the revocation list. ++ */ ++static __init void uefi_revocation_list_x509(const char *source, ++ const void *data, size_t len) ++{ ++ add_key_to_revocation_list(data, len); ++} ++ + /* + * Return the appropriate handler for particular signature list types found in + * the UEFI db and MokListRT tables. +@@ -76,5 +85,7 @@ __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type) + return uefi_blacklist_x509_tbs; + if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) + return uefi_blacklist_binary; ++ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) ++ return uefi_revocation_list_x509; + return 0; + } +-- +2.30.2 + diff --git a/queue-5.4/certs-add-wrapper-function-to-check-blacklisted-bina.patch b/queue-5.4/certs-add-wrapper-function-to-check-blacklisted-bina.patch new file mode 100644 index 00000000000..85959246db9 --- /dev/null +++ b/queue-5.4/certs-add-wrapper-function-to-check-blacklisted-bina.patch @@ -0,0 +1,72 @@ +From bf26abb55c4eec48e2fd8645ff374bacbfc02987 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Oct 2019 23:31:31 -0400 +Subject: certs: Add wrapper function to check blacklisted binary hash + +From: Nayna Jain + +[ Upstream commit 2434f7d2d488c3301ae81f1031e1c66c6f076fb7 ] + +The -EKEYREJECTED error returned by existing is_hash_blacklisted() is +misleading when called for checking against blacklisted hash of a +binary. + +This patch adds a wrapper function is_binary_blacklisted() to return +-EPERM error if binary is blacklisted. + +Signed-off-by: Nayna Jain +Reviewed-by: Mimi Zohar +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/1572492694-6520-7-git-send-email-zohar@linux.ibm.com +Signed-off-by: Sasha Levin +--- + certs/blacklist.c | 9 +++++++++ + include/keys/system_keyring.h | 6 ++++++ + 2 files changed, 15 insertions(+) + +diff --git a/certs/blacklist.c b/certs/blacklist.c +index 025a41de28fd..f1c434b04b5e 100644 +--- a/certs/blacklist.c ++++ b/certs/blacklist.c +@@ -135,6 +135,15 @@ int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type) + } + EXPORT_SYMBOL_GPL(is_hash_blacklisted); + ++int is_binary_blacklisted(const u8 *hash, size_t hash_len) ++{ ++ if (is_hash_blacklisted(hash, hash_len, "bin") == -EKEYREJECTED) ++ return -EPERM; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(is_binary_blacklisted); ++ + /* + * Initialise the blacklist + */ +diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h +index c1a96fdf598b..fb8b07daa9d1 100644 +--- a/include/keys/system_keyring.h ++++ b/include/keys/system_keyring.h +@@ -35,12 +35,18 @@ extern int restrict_link_by_builtin_and_secondary_trusted( + extern int mark_hash_blacklisted(const char *hash); + extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, + const char *type); ++extern int is_binary_blacklisted(const u8 *hash, size_t hash_len); + #else + static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len, + const char *type) + { + return 0; + } ++ ++static inline int is_binary_blacklisted(const u8 *hash, size_t hash_len) ++{ ++ return 0; ++} + #endif + + #ifdef CONFIG_IMA_BLACKLIST_KEYRING +-- +2.30.2 + diff --git a/queue-5.4/certs-move-load_system_certificate_list-to-a-common-.patch b/queue-5.4/certs-move-load_system_certificate_list-to-a-common-.patch new file mode 100644 index 00000000000..a626aead2d4 --- /dev/null +++ b/queue-5.4/certs-move-load_system_certificate_list-to-a-common-.patch @@ -0,0 +1,198 @@ +From 834500a81e821b37e20b6232effd47be16fe43a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 13:10:52 -0500 +Subject: certs: Move load_system_certificate_list to a common function + +From: Eric Snowberg + +[ Upstream commit 2565ca7f5ec1a98d51eea8860c4ab923f1ca2c85 ] + +Move functionality within load_system_certificate_list to a common +function, so it can be reused in the future. + +DH Changes: + - Added inclusion of common.h to common.c (Eric [1]). + +Signed-off-by: Eric Snowberg +Acked-by: Jarkko Sakkinen +Signed-off-by: David Howells +cc: keyrings@vger.kernel.org +Link: https://lore.kernel.org/r/EDA280F9-F72D-4181-93C7-CDBE95976FF7@oracle.com/ [1] +Link: https://lore.kernel.org/r/20200930201508.35113-2-eric.snowberg@oracle.com/ +Link: https://lore.kernel.org/r/20210122181054.32635-3-eric.snowberg@oracle.com/ # v5 +Link: https://lore.kernel.org/r/161428672825.677100.7545516389752262918.stgit@warthog.procyon.org.uk/ +Link: https://lore.kernel.org/r/161433311696.902181.3599366124784670368.stgit@warthog.procyon.org.uk/ # v2 +Link: https://lore.kernel.org/r/161529605850.163428.7786675680201528556.stgit@warthog.procyon.org.uk/ # v3 +Signed-off-by: Sasha Levin +--- + certs/Makefile | 2 +- + certs/common.c | 57 ++++++++++++++++++++++++++++++++++++++++++ + certs/common.h | 9 +++++++ + certs/system_keyring.c | 49 +++--------------------------------- + 4 files changed, 70 insertions(+), 47 deletions(-) + create mode 100644 certs/common.c + create mode 100644 certs/common.h + +diff --git a/certs/Makefile b/certs/Makefile +index f4c25b67aad9..f4b90bad8690 100644 +--- a/certs/Makefile ++++ b/certs/Makefile +@@ -3,7 +3,7 @@ + # Makefile for the linux kernel signature checking certificates. + # + +-obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ++obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o + obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o + ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"") + obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o +diff --git a/certs/common.c b/certs/common.c +new file mode 100644 +index 000000000000..16a220887a53 +--- /dev/null ++++ b/certs/common.c +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include ++#include ++#include "common.h" ++ ++int load_certificate_list(const u8 cert_list[], ++ const unsigned long list_size, ++ const struct key *keyring) ++{ ++ key_ref_t key; ++ const u8 *p, *end; ++ size_t plen; ++ ++ p = cert_list; ++ end = p + list_size; ++ while (p < end) { ++ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more ++ * than 256 bytes in size. ++ */ ++ if (end - p < 4) ++ goto dodgy_cert; ++ if (p[0] != 0x30 && ++ p[1] != 0x82) ++ goto dodgy_cert; ++ plen = (p[2] << 8) | p[3]; ++ plen += 4; ++ if (plen > end - p) ++ goto dodgy_cert; ++ ++ key = key_create_or_update(make_key_ref(keyring, 1), ++ "asymmetric", ++ NULL, ++ p, ++ plen, ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ), ++ KEY_ALLOC_NOT_IN_QUOTA | ++ KEY_ALLOC_BUILT_IN | ++ KEY_ALLOC_BYPASS_RESTRICTION); ++ if (IS_ERR(key)) { ++ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", ++ PTR_ERR(key)); ++ } else { ++ pr_notice("Loaded X.509 cert '%s'\n", ++ key_ref_to_ptr(key)->description); ++ key_ref_put(key); ++ } ++ p += plen; ++ } ++ ++ return 0; ++ ++dodgy_cert: ++ pr_err("Problem parsing in-kernel X.509 certificate list\n"); ++ return 0; ++} +diff --git a/certs/common.h b/certs/common.h +new file mode 100644 +index 000000000000..abdb5795936b +--- /dev/null ++++ b/certs/common.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef _CERT_COMMON_H ++#define _CERT_COMMON_H ++ ++int load_certificate_list(const u8 cert_list[], const unsigned long list_size, ++ const struct key *keyring); ++ ++#endif +diff --git a/certs/system_keyring.c b/certs/system_keyring.c +index cc165b359ea3..a44a8915c94c 100644 +--- a/certs/system_keyring.c ++++ b/certs/system_keyring.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include "common.h" + + static struct key *builtin_trusted_keys; + #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING +@@ -136,54 +137,10 @@ device_initcall(system_trusted_keyring_init); + */ + static __init int load_system_certificate_list(void) + { +- key_ref_t key; +- const u8 *p, *end; +- size_t plen; +- + pr_notice("Loading compiled-in X.509 certificates\n"); + +- p = system_certificate_list; +- end = p + system_certificate_list_size; +- while (p < end) { +- /* Each cert begins with an ASN.1 SEQUENCE tag and must be more +- * than 256 bytes in size. +- */ +- if (end - p < 4) +- goto dodgy_cert; +- if (p[0] != 0x30 && +- p[1] != 0x82) +- goto dodgy_cert; +- plen = (p[2] << 8) | p[3]; +- plen += 4; +- if (plen > end - p) +- goto dodgy_cert; +- +- key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), +- "asymmetric", +- NULL, +- p, +- plen, +- ((KEY_POS_ALL & ~KEY_POS_SETATTR) | +- KEY_USR_VIEW | KEY_USR_READ), +- KEY_ALLOC_NOT_IN_QUOTA | +- KEY_ALLOC_BUILT_IN | +- KEY_ALLOC_BYPASS_RESTRICTION); +- if (IS_ERR(key)) { +- pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", +- PTR_ERR(key)); +- } else { +- pr_notice("Loaded X.509 cert '%s'\n", +- key_ref_to_ptr(key)->description); +- key_ref_put(key); +- } +- p += plen; +- } +- +- return 0; +- +-dodgy_cert: +- pr_err("Problem parsing in-kernel X.509 certificate list\n"); +- return 0; ++ return load_certificate_list(system_certificate_list, system_certificate_list_size, ++ builtin_trusted_keys); + } + late_initcall(load_system_certificate_list); + +-- +2.30.2 + diff --git a/queue-5.4/series b/queue-5.4/series index 31fe4bd5525..6d183cd83fc 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -64,3 +64,7 @@ mm-page_vma_mapped_walk-get-vma_address_end-earlier.patch mm-thp-fix-page_vma_mapped_walk-if-thp-mapped-by-ptes.patch mm-thp-another-pvmw_sync-fix-in-page_vma_mapped_walk.patch mm-futex-fix-shared-futex-pgoff-on-shmem-huge-page.patch +certs-add-wrapper-function-to-check-blacklisted-bina.patch +x86-efi-move-common-keyring-handler-functions-to-new.patch +certs-add-efi_cert_x509_guid-support-for-dbx-entries.patch +certs-move-load_system_certificate_list-to-a-common-.patch diff --git a/queue-5.4/x86-efi-move-common-keyring-handler-functions-to-new.patch b/queue-5.4/x86-efi-move-common-keyring-handler-functions-to-new.patch new file mode 100644 index 00000000000..a9f8ed7f248 --- /dev/null +++ b/queue-5.4/x86-efi-move-common-keyring-handler-functions-to-new.patch @@ -0,0 +1,256 @@ +From 5da81d6989172b38c257f1fe45a7b69677b717eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 10 Nov 2019 21:10:35 -0600 +Subject: x86/efi: move common keyring handler functions to new file + +From: Nayna Jain + +[ Upstream commit ad723674d6758478829ee766e3f1a2a24d56236f ] + +The handlers to add the keys to the .platform keyring and blacklisted +hashes to the .blacklist keyring is common for both the uefi and powerpc +mechanisms of loading the keys/hashes from the firmware. + +This patch moves the common code from load_uefi.c to keyring_handler.c + +Signed-off-by: Nayna Jain +Acked-by: Mimi Zohar +Signed-off-by: Eric Richter +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/1573441836-3632-4-git-send-email-nayna@linux.ibm.com +Signed-off-by: Sasha Levin +--- + security/integrity/Makefile | 3 +- + .../platform_certs/keyring_handler.c | 80 +++++++++++++++++++ + .../platform_certs/keyring_handler.h | 32 ++++++++ + security/integrity/platform_certs/load_uefi.c | 67 +--------------- + 4 files changed, 115 insertions(+), 67 deletions(-) + create mode 100644 security/integrity/platform_certs/keyring_handler.c + create mode 100644 security/integrity/platform_certs/keyring_handler.h + +diff --git a/security/integrity/Makefile b/security/integrity/Makefile +index 35e6ca773734..351c9662994b 100644 +--- a/security/integrity/Makefile ++++ b/security/integrity/Makefile +@@ -11,7 +11,8 @@ integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o + integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o + integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o + integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \ +- platform_certs/load_uefi.o ++ platform_certs/load_uefi.o \ ++ platform_certs/keyring_handler.o + integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o + + obj-$(CONFIG_IMA) += ima/ +diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c +new file mode 100644 +index 000000000000..c5ba695c10e3 +--- /dev/null ++++ b/security/integrity/platform_certs/keyring_handler.c +@@ -0,0 +1,80 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../integrity.h" ++ ++static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID; ++static efi_guid_t efi_cert_x509_sha256_guid __initdata = ++ EFI_CERT_X509_SHA256_GUID; ++static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; ++ ++/* ++ * Blacklist a hash. ++ */ ++static __init void uefi_blacklist_hash(const char *source, const void *data, ++ size_t len, const char *type, ++ size_t type_len) ++{ ++ char *hash, *p; ++ ++ hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); ++ if (!hash) ++ return; ++ p = memcpy(hash, type, type_len); ++ p += type_len; ++ bin2hex(p, data, len); ++ p += len * 2; ++ *p = 0; ++ ++ mark_hash_blacklisted(hash); ++ kfree(hash); ++} ++ ++/* ++ * Blacklist an X509 TBS hash. ++ */ ++static __init void uefi_blacklist_x509_tbs(const char *source, ++ const void *data, size_t len) ++{ ++ uefi_blacklist_hash(source, data, len, "tbs:", 4); ++} ++ ++/* ++ * Blacklist the hash of an executable. ++ */ ++static __init void uefi_blacklist_binary(const char *source, ++ const void *data, size_t len) ++{ ++ uefi_blacklist_hash(source, data, len, "bin:", 4); ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI db and MokListRT tables. ++ */ ++__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_to_platform_keyring; ++ return 0; ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI dbx and MokListXRT tables. ++ */ ++__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; ++} +diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h +new file mode 100644 +index 000000000000..2462bfa08fe3 +--- /dev/null ++++ b/security/integrity/platform_certs/keyring_handler.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef PLATFORM_CERTS_INTERNAL_H ++#define PLATFORM_CERTS_INTERNAL_H ++ ++#include ++ ++void blacklist_hash(const char *source, const void *data, ++ size_t len, const char *type, ++ size_t type_len); ++ ++/* ++ * Blacklist an X509 TBS hash. ++ */ ++void blacklist_x509_tbs(const char *source, const void *data, size_t len); ++ ++/* ++ * Blacklist the hash of an executable. ++ */ ++void blacklist_binary(const char *source, const void *data, size_t len); ++ ++/* ++ * Return the handler for particular signature list types found in the db. ++ */ ++efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type); ++ ++/* ++ * Return the handler for particular signature list types found in the dbx. ++ */ ++efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type); ++ ++#endif +diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c +index 020fc7a11ef0..aa874d84e413 100644 +--- a/security/integrity/platform_certs/load_uefi.c ++++ b/security/integrity/platform_certs/load_uefi.c +@@ -9,6 +9,7 @@ + #include + #include + #include "../integrity.h" ++#include "keyring_handler.h" + + static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID; + static efi_guid_t efi_cert_x509_sha256_guid __initdata = +@@ -69,72 +70,6 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, + return db; + } + +-/* +- * Blacklist a hash. +- */ +-static __init void uefi_blacklist_hash(const char *source, const void *data, +- size_t len, const char *type, +- size_t type_len) +-{ +- char *hash, *p; +- +- hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); +- if (!hash) +- return; +- p = memcpy(hash, type, type_len); +- p += type_len; +- bin2hex(p, data, len); +- p += len * 2; +- *p = 0; +- +- mark_hash_blacklisted(hash); +- kfree(hash); +-} +- +-/* +- * Blacklist an X509 TBS hash. +- */ +-static __init void uefi_blacklist_x509_tbs(const char *source, +- const void *data, size_t len) +-{ +- uefi_blacklist_hash(source, data, len, "tbs:", 4); +-} +- +-/* +- * Blacklist the hash of an executable. +- */ +-static __init void uefi_blacklist_binary(const char *source, +- const void *data, size_t len) +-{ +- uefi_blacklist_hash(source, data, len, "bin:", 4); +-} +- +-/* +- * 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_to_platform_keyring; +- 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 into the platform trusted + * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist +-- +2.30.2 +