All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [PATCH 8/8] image: Check for unit addresses in FITs
Date: Mon, 15 Feb 2021 17:08:12 -0700	[thread overview]
Message-ID: <20210216000812.2091481-9-sjg@chromium.org> (raw)
In-Reply-To: <20210216000812.2091481-1-sjg@chromium.org>

Using unit addresses in a FIT is a security risk. Add a check for this
and disallow it.

CVE-2021-27138

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>
---

 common/image-fit.c          | 56 ++++++++++++++++++++++++++++++++++---
 test/py/tests/test_vboot.py |  9 +++---
 2 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index bcf395f6a18..28b3d2b1911 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1568,6 +1568,34 @@ int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
 	return (comp == image_comp);
 }
 
+/**
+ * fdt_check_no_at() - Check for nodes whose names contain '@'
+ *
+ * This checks the parent node and all subnodes recursively
+ *
+ * @fit: FIT to check
+ * @parent: Parent node to check
+ * @return 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
+ */
+static int fdt_check_no_at(const void *fit, int parent)
+{
+	const char *name;
+	int node;
+	int ret;
+
+	name = fdt_get_name(fit, parent, NULL);
+	if (!name || strchr(name, '@'))
+		return -EADDRNOTAVAIL;
+
+	fdt_for_each_subnode(node, fit, parent) {
+		ret = fdt_check_no_at(fit, node);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int fit_check_format(const void *fit, ulong size)
 {
 	int ret;
@@ -1589,10 +1617,27 @@ int fit_check_format(const void *fit, ulong size)
 		if (size == IMAGE_SIZE_INVAL)
 			size = fdt_totalsize(fit);
 		ret = fdt_check_full(fit, size);
+		if (ret)
+			ret = -EINVAL;
+
+		/*
+		 * U-Boot stopped using unit addressed in 2017. Since libfdt
+		 * can match nodes ignoring any unit address, signature
+		 * verification can see the wrong node if one is inserted with
+		 * the same name as a valid node but with a unit address
+		 * attached. Protect against this by disallowing unit addresses.
+		 */
+		if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+			ret = fdt_check_no_at(fit, 0);
 
+			if (ret) {
+				log_debug("FIT check error %d\n", ret);
+				return ret;
+			}
+		}
 		if (ret) {
 			log_debug("FIT check error %d\n", ret);
-			return -EINVAL;
+			return ret;
 		}
 	}
 
@@ -1955,10 +2000,13 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 	printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
 
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
-	if (fit_check_format(fit, IMAGE_SIZE_INVAL)) {
-		printf("Bad FIT %s image format!\n", prop_name);
+	ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
+	if (ret) {
+		printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
+		if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
+			printf("Signature checking prevents use of unit addresses (@) in nodes\n");
 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
-		return -ENOEXEC;
+		return ret;
 	}
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
 	if (fit_uname) {
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 22e8fc10d83..6dff6779d17 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -232,8 +232,8 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required,
         util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb])
 
         if full_test:
-            # Make sure that U-Boot checks that the config is in the list of hashed
-            # nodes. If it isn't, a security bypass is possible.
+            # Make sure that U-Boot checks that the config is in the list of
+            # hashed nodes. If it isn't, a security bypass is possible.
             ffit = '%stest.forged.fit' % tmpdir
             shutil.copyfile(fit, ffit)
             with open(ffit, 'rb') as fd:
@@ -263,10 +263,11 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required,
             shutil.copyfile(fit, efit)
             vboot_evil.add_evil_node(fit, efit, evil_kernel, 'kernel@')
 
+            msg = 'Signature checking prevents use of unit addresses (@) in nodes'
             util.run_and_log_expect_exception(
                 cons, [fit_check_sign, '-f', efit, '-k', dtb],
-                1, 'Node name contains @')
-            run_bootm(sha_algo, 'evil kernel@', 'Bad Data Hash', False, efit)
+                1, msg)
+            run_bootm(sha_algo, 'evil kernel@', msg, False, efit)
 
         # Create a new properly signed fit and replace header bytes
         make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
-- 
2.30.0.478.g8a0d178c01-goog

  parent reply	other threads:[~2021-02-16  0:08 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-16  0:08 [PATCH 0/8] vboot: Correct vulnerabilities identified by Intel Simon Glass
2021-02-16  0:08 ` [PATCH 1/8] fdt_region: Check for a single root node of the correct name Simon Glass
2021-02-16  3:35   ` Tom Rini
2021-02-16  0:08 ` [PATCH 2/8] fit: Don't allow verification of images with @ nodes Simon Glass
2021-02-16  3:35   ` Tom Rini
2021-02-16  0:08 ` [PATCH 3/8] test: Add vboot_evil implementation Simon Glass
2021-02-16  3:36   ` Tom Rini
2021-02-16  0:08 ` [PATCH 4/8] test: Add tests for the 'evil' vboot attacks Simon Glass
2021-02-16  3:36   ` Tom Rini
2021-02-16  0:08 ` [PATCH 5/8] image: Adjust the workings of fit_check_format() Simon Glass
2021-02-16  3:36   ` Tom Rini
2021-02-17 13:30   ` Jesper Schmitz Mouridsen
2021-02-17 13:43     ` Tom Rini
2021-02-17 14:12       ` Jesper Schmitz Mouridsen
2021-02-16  0:08 ` [PATCH 6/8] image: Add an option to do a full check of the FIT Simon Glass
2021-02-16  3:36   ` Tom Rini
2021-02-16  0:08 ` [PATCH 7/8] libfdt: Check for multiple/invalid root nodes Simon Glass
2021-02-16  3:36   ` Tom Rini
2021-02-16  0:08 ` Simon Glass [this message]
2021-02-16  3:36   ` [PATCH 8/8] image: Check for unit addresses in FITs Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210216000812.2091481-9-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.