diff options
Diffstat (limited to 'freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch')
-rw-r--r-- | freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch b/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch new file mode 100644 index 000000000..e3941eeaa --- /dev/null +++ b/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch @@ -0,0 +1,197 @@ +From e4c62c12635a371e43bd17e8d33a936668264491 Mon Sep 17 00:00:00 2001 +From: Dave Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:58 +0100 +Subject: [PATCH 2/4] efi: Add an EFI signature blob parser + +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 + +diff --git a/certs/Kconfig b/certs/Kconfig +index 6ce51ed..630ae09 100644 +--- a/certs/Kconfig ++++ b/certs/Kconfig +@@ -82,4 +82,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 +diff --git a/certs/Makefile b/certs/Makefile +index 4119bb3..738151a 100644 +--- a/certs/Makefile ++++ b/certs/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o + 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) + +diff --git a/certs/efi_parser.c b/certs/efi_parser.c +new file mode 100644 +index 0000000..4e396f9 +--- /dev/null ++++ b/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; ++} +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 3259ad6..08024c6 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1055,6 +1055,15 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm, + 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 +-- +2.9.3 + |