CVE-2021-27097: Insufficient Information (NVD-CWE-noinfo)
value: The boot loader in Das U-Boot before 2021.04-rc2 mishandles a modified FIT.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 7.8
Published: 2021-02-17T23:15Z
Repository: https://github.com/u-boot/u-boot
Language: C
Files changed: common/Kconfig.boot, common/image-fit.c
Commit date: 2021-02-15 22:31:53 -0500
Commit message: image: Add an option to do a full check of the FIT

Some strange modifications of the FIT can introduce security risks. Add an
option to check it thoroughly, using libfdt's fdt_check_full() function.

Enable this by default if signature verification is enabled.

CVE-2021-27097

Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Bruce Monroe <bruce.monroe@intel.com>
Reported-by: Arie Haenel <arie.haenel@intel.com>
Reported-by: Julien Lenoir <julien.lenoir@intel.com>

Diff: diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 5eaabdfc27..7532e55edb 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -61,17 +61,27 @@ config FIT_ENABLE_SHA512_SUPPORT
 	help
 	  Enable this to support SHA512 checksum of FIT image contents. A
 	  SHA512 checksum is a 512-bit (64-byte) hash value used to check that
 	  the image contents have not been corrupted.
 
+config FIT_FULL_CHECK
+	bool "Do a full check of the FIT before using it"
+	default y
+	help
+	  Enable this do a full check of the FIT to make sure it is valid. This
+	  helps to protect against carefully crafted FITs which take advantage
+	  of bugs or omissions in the code. This includes a bad structure,
+	  multiple root nodes and the like.
+
 config FIT_SIGNATURE
 	bool "Enable signature verification of FIT uImages"
 	depends on DM
 	select HASH
 	select RSA
 	select RSA_VERIFY
 	select IMAGE_SIGN_INFO
+	select FIT_FULL_CHECK
 	help
 	  This option enables signature verification of FIT uImages,
 	  using a hash signed and verified using RSA. If
 	  CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
 	  hashing is available using hardware, then the RSA library will use
@@ -157,19 +167,29 @@ config SPL_FIT_PRINT
 	bool "Support FIT printing within SPL"
 	depends on SPL_FIT
 	help
 	  Support printing the content of the fitImage in a verbose manner in SPL.
 
+config SPL_FIT_FULL_CHECK
+	bool "Do a full check of the FIT before using it"
+	help
+	  Enable this do a full check of the FIT to make sure it is valid. This
+	  helps to protect against carefully crafted FITs which take advantage
+	  of bugs or omissions in the code. This includes a bad structure,
+	  multiple root nodes and the like.
+
+
 config SPL_FIT_SIGNATURE
 	bool "Enable signature verification of FIT firmware within SPL"
 	depends on SPL_DM
 	select SPL_FIT
 	select SPL_CRYPTO_SUPPORT
 	select SPL_HASH_SUPPORT
 	select SPL_RSA
 	select SPL_RSA_VERIFY
 	select SPL_IMAGE_SIGN_INFO
+	select SPL_FIT_FULL_CHECK
 
 config SPL_LOAD_FIT
 	bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
 	select SPL_FIT
 	help
diff --git a/common/image-fit.c b/common/image-fit.c
index f6c0428a96..bcf395f6a1 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1578,10 +1578,26 @@ int fit_check_format(const void *fit, ulong size)
 		log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
 			  ret);
 		return -ENOEXEC;
 	}
 
+	if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
+		/*
+		 * If we are not given the size, make do wtih calculating it.
+		 * This is not as secure, so we should consider a flag to
+		 * control this.
+		 */
+		if (size == IMAGE_SIZE_INVAL)
+			size = fdt_totalsize(fit);
+		ret = fdt_check_full(fit, size);
+
+		if (ret) {
+			log_debug("FIT check error %d\n", ret);
+			return -EINVAL;
+		}
+	}
+
 	/* mandatory / node 'description' property */
 	if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
 		log_debug("Wrong FIT format: no description\n");
 		return -ENOMSG;
 	}

Fixed code: config FIT_FULL_CHECK
	bool "Do a full check of the FIT before using it"
	default y
	help
	  Enable this do a full check of the FIT to make sure it is valid. This
	  helps to protect against carefully crafted FITs which take advantage
	  of bugs or omissions in the code. This includes a bad structure,
	  multiple root nodes and the like.

	select FIT_FULL_CHECK
config SPL_FIT_FULL_CHECK
	bool "Do a full check of the FIT before using it"
	help
	  Enable this do a full check of the FIT to make sure it is valid. This
	  helps to protect against carefully crafted FITs which take advantage
	  of bugs or omissions in the code. This includes a bad structure,
	  multiple root nodes and the like.


	select SPL_FIT_FULL_CHECK
	if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
		/*
		 * If we are not given the size, make do wtih calculating it.
		 * This is not as secure, so we should consider a flag to
		 * control this.
		 */
		if (size == IMAGE_SIZE_INVAL)
			size = fdt_totalsize(fit);
		ret = fdt_check_full(fit, size);

		if (ret) {
			log_debug("FIT check error %d\n", ret);
			return -EINVAL;
		}
	}