[PATCH v7 2/5] certs: Check that builtin blacklist hashes are valid

Jarkko Sakkinen jarkko at kernel.org
Sat Mar 13 18:53:36 UTC 2021


On Fri, Mar 12, 2021 at 06:12:29PM +0100, Mickaël Salaün wrote:
> From: Mickaël Salaün <mic at linux.microsoft.com>
> 
> Add and use a check-blacklist-hashes.awk script to make sure that the
> builtin blacklist hashes set with CONFIG_SYSTEM_BLACKLIST_HASH_LIST will
> effectively be taken into account as blacklisted hashes.  This is useful
> to debug invalid hash formats, and it make sure that previous hashes
> which could have been loaded in the kernel, but silently ignored, are
> now noticed and deal with by the user at kernel build time.
> 
> This also prevent stricter blacklist key description checking (provided
> by following commits) to failed for builtin hashes.
> 
> Update CONFIG_SYSTEM_BLACKLIST_HASH_LIST help to explain the content of
> a hash string and how to generate certificate ones.
> 
> Cc: David Howells <dhowells at redhat.com>
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: Eric Snowberg <eric.snowberg at oracle.com>
> Cc: Jarkko Sakkinen <jarkko at kernel.org>
> Signed-off-by: Mickaël Salaün <mic at linux.microsoft.com>
> Link: https://lore.kernel.org/r/20210312171232.2681989-3-mic@digikod.net


Reviewed-by: Jarkko Sakkinen <jarkko at kernel.org>

/Jarkko

> ---
> 
> Changes since v5:
> * Rebase on keys-next and fix conflict as previously done by David
>   Howells.
> * Enable to use a file path relative to the kernel source directory.
>   This align with the handling of CONFIG_SYSTEM_TRUSTED_KEYS,
>   CONFIG_MODULE_SIG_KEY and CONFIG_SYSTEM_REVOCATION_KEYS.
> 
> Changes since v3:
> * Improve commit description.
> * Update CONFIG_SYSTEM_BLACKLIST_HASH_LIST help.
> * Remove Acked-by Jarkko Sakkinen because of the above changes.
> 
> Changes since v2:
> * Add Jarkko's Acked-by.
> 
> Changes since v1:
> * Prefix script path with $(scrtree)/ (suggested by David Howells).
> * Fix hexadecimal number check.
> ---
>  MAINTAINERS                        |  1 +
>  certs/.gitignore                   |  1 +
>  certs/Kconfig                      |  7 ++++--
>  certs/Makefile                     | 17 +++++++++++++-
>  scripts/check-blacklist-hashes.awk | 37 ++++++++++++++++++++++++++++++
>  5 files changed, 60 insertions(+), 3 deletions(-)
>  create mode 100755 scripts/check-blacklist-hashes.awk
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 773a362e807f..a18fd3d283c6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4118,6 +4118,7 @@ L:	keyrings at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/admin-guide/module-signing.rst
>  F:	certs/
> +F:	scripts/check-blacklist-hashes.awk
>  F:	scripts/extract-cert.c
>  F:	scripts/sign-file.c
>  F:	tools/certs/
> diff --git a/certs/.gitignore b/certs/.gitignore
> index 2a2483990686..42cc2ac24b93 100644
> --- a/certs/.gitignore
> +++ b/certs/.gitignore
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +blacklist_hashes_checked
>  x509_certificate_list
> diff --git a/certs/Kconfig b/certs/Kconfig
> index ab88d2a7f3c7..cf3740c1b22b 100644
> --- a/certs/Kconfig
> +++ b/certs/Kconfig
> @@ -80,8 +80,11 @@ config SYSTEM_BLACKLIST_HASH_LIST
>  	help
>  	  If set, this option should be the filename of a list of hashes in the
>  	  form "<hash>", "<hash>", ... .  This will be included into a C
> -	  wrapper to incorporate the list into the kernel.  Each <hash> should
> -	  be a string of hex digits.
> +	  wrapper to incorporate the list into the kernel.  Each <hash> must be a
> +	  string starting with a prefix ("tbs" or "bin"), then a colon (":"), and
> +	  finally an even number of hexadecimal lowercase characters (up to 128).
> +	  Certificate hashes can be generated with
> +	  tools/certs/print-cert-tbs-hash.sh .
>  
>  config SYSTEM_REVOCATION_LIST
>  	bool "Provide system-wide ring of revocation certificates"
> diff --git a/certs/Makefile b/certs/Makefile
> index b6db52ebf0be..61e82b8eacd2 100644
> --- a/certs/Makefile
> +++ b/certs/Makefile
> @@ -7,7 +7,22 @@ obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o c
>  obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o
>  obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
>  ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"")
> +
> +quiet_cmd_check_blacklist_hashes = CHECK   $(patsubst "%",%,$(2))
> +      cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@
> +
> +$(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST))
> +
> +$(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked
> +
> +CFLAGS_blacklist_hashes.o += -I$(srctree)
> +
> +targets += blacklist_hashes_checked
> +$(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE
> +	$(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST))
> +
>  obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
> +
>  else
>  obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
>  endif
> @@ -30,7 +45,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF
>  	$(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS))
>  endif # CONFIG_SYSTEM_TRUSTED_KEYRING
>  
> -clean-files := x509_certificate_list .x509.list x509_revocation_list
> +clean-files := x509_certificate_list .x509.list x509_revocation_list blacklist_hashes_checked
>  
>  ifeq ($(CONFIG_MODULE_SIG),y)
>  ###############################################################################
> diff --git a/scripts/check-blacklist-hashes.awk b/scripts/check-blacklist-hashes.awk
> new file mode 100755
> index 000000000000..107c1d3204d4
> --- /dev/null
> +++ b/scripts/check-blacklist-hashes.awk
> @@ -0,0 +1,37 @@
> +#!/usr/bin/awk -f
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright © 2020, Microsoft Corporation. All rights reserved.
> +#
> +# Author: Mickaël Salaün <mic at linux.microsoft.com>
> +#
> +# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of
> +# hash strings.  Such string must start with a prefix ("tbs" or "bin"), then a
> +# colon (":"), and finally an even number of hexadecimal lowercase characters
> +# (up to 128).
> +
> +BEGIN {
> +	RS = ","
> +}
> +{
> +	if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) {
> +		print "Not a string (item " NR "):", $0;
> +		exit 1;
> +	}
> +	if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) {
> +		print "Unknown prefix (item " NR "):", part1[1];
> +		exit 1;
> +	}
> +	if (!match(part2[2], "^([0-9a-f]+)$", part3)) {
> +		print "Not a lowercase hexadecimal string (item " NR "):", part2[2];
> +		exit 1;
> +	}
> +	if (length(part3[1]) > 128) {
> +		print "Hash string too long (item " NR "):", part3[1];
> +		exit 1;
> +	}
> +	if (length(part3[1]) % 2 == 1) {
> +		print "Not an even number of hexadecimal characters (item " NR "):", part3[1];
> +		exit 1;
> +	}
> +}
> -- 
> 2.30.2
> 
> 



More information about the Linux-security-module-archive mailing list