!19 fix CVE-2021-27097CVE-2021-27138
From: @yangl777 Reviewed-by: @yanan-rock Signed-off-by: @yanan-rock
This commit is contained in:
commit
725798ad85
66
backport-0001-CVE-2021-27097.patch
Normal file
66
backport-0001-CVE-2021-27097.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From 8a7d4cf9820ea16fabd25a6379351b4dc291204b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Glass <sjg@chromium.org>
|
||||||
|
Date: Mon, 15 Feb 2021 17:08:05 -0700
|
||||||
|
Subject: [PATCH] fdt_region: Check for a single root node of the correct name
|
||||||
|
|
||||||
|
At present fdt_find_regions() assumes that the FIT is a valid devicetree.
|
||||||
|
If the FIT has two root nodes this is currently not detected in this
|
||||||
|
function, nor does libfdt's fdt_check_full() notice. Also it is possible
|
||||||
|
for the root node to have a name even though it should not.
|
||||||
|
|
||||||
|
Add checks for these and return -FDT_ERR_BADSTRUCTURE if a problem is
|
||||||
|
detected.
|
||||||
|
|
||||||
|
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>
|
||||||
|
---
|
||||||
|
common/fdt_region.c | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/common/fdt_region.c b/common/fdt_region.c
|
||||||
|
index ff12c518e97..e4ef0ca7703 100644
|
||||||
|
--- a/common/fdt_region.c
|
||||||
|
+++ b/common/fdt_region.c
|
||||||
|
@@ -43,6 +43,7 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
|
||||||
|
int depth = -1;
|
||||||
|
int want = 0;
|
||||||
|
int base = fdt_off_dt_struct(fdt);
|
||||||
|
+ bool expect_end = false;
|
||||||
|
|
||||||
|
end = path;
|
||||||
|
*end = '\0';
|
||||||
|
@@ -59,6 +60,10 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
|
||||||
|
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||||
|
stop_at = nextoffset;
|
||||||
|
|
||||||
|
+ /* If we see two root nodes, something is wrong */
|
||||||
|
+ if (expect_end && tag != FDT_END)
|
||||||
|
+ return -FDT_ERR_BADLAYOUT;
|
||||||
|
+
|
||||||
|
switch (tag) {
|
||||||
|
case FDT_PROP:
|
||||||
|
include = want >= 2;
|
||||||
|
@@ -81,6 +86,10 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
|
||||||
|
if (depth == FDT_MAX_DEPTH)
|
||||||
|
return -FDT_ERR_BADSTRUCTURE;
|
||||||
|
name = fdt_get_name(fdt, offset, &len);
|
||||||
|
+
|
||||||
|
+ /* The root node must have an empty name */
|
||||||
|
+ if (!depth && *name)
|
||||||
|
+ return -FDT_ERR_BADLAYOUT;
|
||||||
|
if (end - path + 2 + len >= path_len)
|
||||||
|
return -FDT_ERR_NOSPACE;
|
||||||
|
if (end != path + 1)
|
||||||
|
@@ -108,6 +117,8 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
|
||||||
|
while (end > path && *--end != '/')
|
||||||
|
;
|
||||||
|
*end = '\0';
|
||||||
|
+ if (depth == -1)
|
||||||
|
+ expect_end = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FDT_END:
|
||||||
240
backport-0001-CVE-2021-27138.patch
Normal file
240
backport-0001-CVE-2021-27138.patch
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
From 79af75f7776fc20b0d7eb6afe1e27c00fdb4b9b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Glass <sjg@chromium.org>
|
||||||
|
Date: Mon, 15 Feb 2021 17:08:06 -0700
|
||||||
|
Subject: [PATCH] fit: Don't allow verification of images with @ nodes
|
||||||
|
|
||||||
|
When searching for a node called 'fred', any unit address appended to the
|
||||||
|
name is ignored by libfdt, meaning that 'fred' can match 'fred@1'. This
|
||||||
|
means that we cannot be sure that the node originally intended is the one
|
||||||
|
that is used.
|
||||||
|
|
||||||
|
Disallow use of nodes with unit addresses.
|
||||||
|
|
||||||
|
Update the forge test also, since it uses @ addresses.
|
||||||
|
|
||||||
|
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-sig.c | 22 ++++++++++++++++++++--
|
||||||
|
common/image-fit.c | 20 +++++++++++++++-----
|
||||||
|
test/py/tests/test_fit.py | 24 ++++++++++++------------
|
||||||
|
test/py/tests/vboot_forge.py | 12 ++++++------
|
||||||
|
4 files changed, 53 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c
|
||||||
|
index 897e04c7a38..34ebb8edfe2 100644
|
||||||
|
--- a/common/image-fit-sig.c
|
||||||
|
+++ b/common/image-fit-sig.c
|
||||||
|
@@ -149,6 +149,14 @@ static int fit_image_verify_sig(const void *fit, int image_noffset,
|
||||||
|
fdt_for_each_subnode(noffset, fit, image_noffset) {
|
||||||
|
const char *name = fit_get_name(fit, noffset, NULL);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * We don't support this since libfdt considers names with the
|
||||||
|
+ * name root but different @ suffix to be equal
|
||||||
|
+ */
|
||||||
|
+ if (strchr(name, '@')) {
|
||||||
|
+ err_msg = "Node name contains @";
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
if (!strncmp(name, FIT_SIG_NODENAME,
|
||||||
|
strlen(FIT_SIG_NODENAME))) {
|
||||||
|
ret = fit_image_check_sig(fit, noffset, data,
|
||||||
|
@@ -398,9 +406,10 @@ static int fit_config_verify_sig(const void *fit, int conf_noffset,
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
|
||||||
|
- const void *sig_blob)
|
||||||
|
+static int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
|
||||||
|
+ const void *sig_blob)
|
||||||
|
{
|
||||||
|
+ const char *name = fit_get_name(fit, conf_noffset, NULL);
|
||||||
|
int noffset;
|
||||||
|
int sig_node;
|
||||||
|
int verified = 0;
|
||||||
|
@@ -408,6 +417,15 @@ int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
|
||||||
|
bool reqd_policy_all = true;
|
||||||
|
const char *reqd_mode;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * We don't support this since libfdt considers names with the
|
||||||
|
+ * name root but different @ suffix to be equal
|
||||||
|
+ */
|
||||||
|
+ if (strchr(name, '@')) {
|
||||||
|
+ printf("Configuration node '%s' contains '@'\n", name);
|
||||||
|
+ return -EPERM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Work out what we need to verify */
|
||||||
|
sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
|
||||||
|
if (sig_node < 0) {
|
||||||
|
diff --git a/common/image-fit.c b/common/image-fit.c
|
||||||
|
index adc3e551de9..c3dc814115f 100644
|
||||||
|
--- a/common/image-fit.c
|
||||||
|
+++ b/common/image-fit.c
|
||||||
|
@@ -1369,21 +1369,31 @@ int fit_image_verify_with_data(const void *fit, int image_noffset,
|
||||||
|
*/
|
||||||
|
int fit_image_verify(const void *fit, int image_noffset)
|
||||||
|
{
|
||||||
|
+ const char *name = fit_get_name(fit, image_noffset, NULL);
|
||||||
|
const void *data;
|
||||||
|
size_t size;
|
||||||
|
- int noffset = 0;
|
||||||
|
char *err_msg = "";
|
||||||
|
|
||||||
|
+ if (strchr(name, '@')) {
|
||||||
|
+ /*
|
||||||
|
+ * We don't support this since libfdt considers names with the
|
||||||
|
+ * name root but different @ suffix to be equal
|
||||||
|
+ */
|
||||||
|
+ err_msg = "Node name contains @";
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
/* Get image data and data length */
|
||||||
|
if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
|
||||||
|
err_msg = "Can't get image data/size";
|
||||||
|
- printf("error!\n%s for '%s' hash node in '%s' image node\n",
|
||||||
|
- err_msg, fit_get_name(fit, noffset, NULL),
|
||||||
|
- fit_get_name(fit, image_noffset, NULL));
|
||||||
|
- return 0;
|
||||||
|
+ goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fit_image_verify_with_data(fit, image_noffset, data, size);
|
||||||
|
+
|
||||||
|
+err:
|
||||||
|
+ printf("error!\n%s in '%s' image node\n", err_msg,
|
||||||
|
+ fit_get_name(fit, image_noffset, NULL));
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
|
||||||
|
index 84b3f958505..6d5b43c3bab 100755
|
||||||
|
--- a/test/py/tests/test_fit.py
|
||||||
|
+++ b/test/py/tests/test_fit.py
|
||||||
|
@@ -17,7 +17,7 @@
|
||||||
|
#address-cells = <1>;
|
||||||
|
|
||||||
|
images {
|
||||||
|
- kernel@1 {
|
||||||
|
+ kernel-1 {
|
||||||
|
data = /incbin/("%(kernel)s");
|
||||||
|
type = "kernel";
|
||||||
|
arch = "sandbox";
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
load = <0x40000>;
|
||||||
|
entry = <0x8>;
|
||||||
|
};
|
||||||
|
- kernel@2 {
|
||||||
|
+ kernel-2 {
|
||||||
|
data = /incbin/("%(loadables1)s");
|
||||||
|
type = "kernel";
|
||||||
|
arch = "sandbox";
|
||||||
|
@@ -35,19 +35,19 @@
|
||||||
|
%(loadables1_load)s
|
||||||
|
entry = <0x0>;
|
||||||
|
};
|
||||||
|
- fdt@1 {
|
||||||
|
+ fdt-1 {
|
||||||
|
description = "snow";
|
||||||
|
data = /incbin/("%(fdt)s");
|
||||||
|
type = "flat_dt";
|
||||||
|
arch = "sandbox";
|
||||||
|
%(fdt_load)s
|
||||||
|
compression = "%(compression)s";
|
||||||
|
- signature@1 {
|
||||||
|
+ signature-1 {
|
||||||
|
algo = "sha1,rsa2048";
|
||||||
|
key-name-hint = "dev";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
- ramdisk@1 {
|
||||||
|
+ ramdisk-1 {
|
||||||
|
description = "snow";
|
||||||
|
data = /incbin/("%(ramdisk)s");
|
||||||
|
type = "ramdisk";
|
||||||
|
@@ -56,7 +56,7 @@
|
||||||
|
%(ramdisk_load)s
|
||||||
|
compression = "%(compression)s";
|
||||||
|
};
|
||||||
|
- ramdisk@2 {
|
||||||
|
+ ramdisk-2 {
|
||||||
|
description = "snow";
|
||||||
|
data = /incbin/("%(loadables2)s");
|
||||||
|
type = "ramdisk";
|
||||||
|
@@ -67,10 +67,10 @@
|
||||||
|
};
|
||||||
|
};
|
||||||
|
configurations {
|
||||||
|
- default = "conf@1";
|
||||||
|
- conf@1 {
|
||||||
|
- kernel = "kernel@1";
|
||||||
|
- fdt = "fdt@1";
|
||||||
|
+ default = "conf-1";
|
||||||
|
+ conf-1 {
|
||||||
|
+ kernel = "kernel-1";
|
||||||
|
+ fdt = "fdt-1";
|
||||||
|
%(ramdisk_config)s
|
||||||
|
%(loadables_config)s
|
||||||
|
};
|
||||||
|
@@ -410,7 +410,7 @@ def run_fit_test(mkimage):
|
||||||
|
|
||||||
|
# Try a ramdisk
|
||||||
|
with cons.log.section('Kernel + FDT + Ramdisk load'):
|
||||||
|
- params['ramdisk_config'] = 'ramdisk = "ramdisk@1";'
|
||||||
|
+ params['ramdisk_config'] = 'ramdisk = "ramdisk-1";'
|
||||||
|
params['ramdisk_load'] = 'load = <%#x>;' % params['ramdisk_addr']
|
||||||
|
fit = make_fit(mkimage, params)
|
||||||
|
cons.restart_uboot()
|
||||||
|
@@ -419,7 +419,7 @@ def run_fit_test(mkimage):
|
||||||
|
|
||||||
|
# Configuration with some Loadables
|
||||||
|
with cons.log.section('Kernel + FDT + Ramdisk load + Loadables'):
|
||||||
|
- params['loadables_config'] = 'loadables = "kernel@2", "ramdisk@2";'
|
||||||
|
+ params['loadables_config'] = 'loadables = "kernel-2", "ramdisk-2";'
|
||||||
|
params['loadables1_load'] = ('load = <%#x>;' %
|
||||||
|
params['loadables1_addr'])
|
||||||
|
params['loadables2_load'] = ('load = <%#x>;' %
|
||||||
|
diff --git a/test/py/tests/vboot_forge.py b/test/py/tests/vboot_forge.py
|
||||||
|
index 0fb7ef40247..b41105bd0e3 100644
|
||||||
|
--- a/test/py/tests/vboot_forge.py
|
||||||
|
+++ b/test/py/tests/vboot_forge.py
|
||||||
|
@@ -376,12 +376,12 @@ def manipulate(root, strblock):
|
||||||
|
"""
|
||||||
|
Maliciously manipulates the structure to create a crafted FIT file
|
||||||
|
"""
|
||||||
|
- # locate /images/kernel@1 (frankly, it just expects it to be the first one)
|
||||||
|
+ # locate /images/kernel-1 (frankly, it just expects it to be the first one)
|
||||||
|
kernel_node = root[0][0]
|
||||||
|
# clone it to save time filling all the properties
|
||||||
|
fake_kernel = kernel_node.clone()
|
||||||
|
# rename the node
|
||||||
|
- fake_kernel.name = b'kernel@2'
|
||||||
|
+ fake_kernel.name = b'kernel-2'
|
||||||
|
# get rid of signatures/hashes
|
||||||
|
fake_kernel.children = []
|
||||||
|
# NOTE: this simply replaces the first prop... either description or data
|
||||||
|
@@ -391,13 +391,13 @@ def manipulate(root, strblock):
|
||||||
|
root[0].children.append(fake_kernel)
|
||||||
|
|
||||||
|
# modify the default configuration
|
||||||
|
- root[1].props[0].value = b'conf@2\x00'
|
||||||
|
+ root[1].props[0].value = b'conf-2\x00'
|
||||||
|
# clone the first (only?) configuration
|
||||||
|
fake_conf = root[1][0].clone()
|
||||||
|
# rename and change kernel and fdt properties to select the crafted kernel
|
||||||
|
- fake_conf.name = b'conf@2'
|
||||||
|
- fake_conf.props[0].value = b'kernel@2\x00'
|
||||||
|
- fake_conf.props[1].value = b'fdt@1\x00'
|
||||||
|
+ fake_conf.name = b'conf-2'
|
||||||
|
+ fake_conf.props[0].value = b'kernel-2\x00'
|
||||||
|
+ fake_conf.props[1].value = b'fdt-1\x00'
|
||||||
|
# insert the new configuration under /configurations
|
||||||
|
root[1].children.append(fake_conf)
|
||||||
|
|
||||||
403
backport-0002-CVE-2021-27097.patch
Normal file
403
backport-0002-CVE-2021-27097.patch
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
From c5819701a3de61e2ba2ef7ad0b616565b32305e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Glass <sjg@chromium.org>
|
||||||
|
Date: Mon, 15 Feb 2021 17:08:09 -0700
|
||||||
|
Subject: [PATCH] image: Adjust the workings of fit_check_format()
|
||||||
|
|
||||||
|
At present this function does not accept a size for the FIT. This means
|
||||||
|
that it must be read from the FIT itself, introducing potential security
|
||||||
|
risk. Update the function to include a size parameter, which can be
|
||||||
|
invalid, in which case fit_check_format() calculates it.
|
||||||
|
|
||||||
|
For now no callers pass the size, but this can be updated later.
|
||||||
|
|
||||||
|
Also adjust the return value to an error code so that all the different
|
||||||
|
types of problems can be distinguished by the user.
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
---
|
||||||
|
arch/arm/cpu/armv8/sec_firmware.c | 2 +-
|
||||||
|
cmd/bootm.c | 6 ++--
|
||||||
|
cmd/disk.c | 2 +-
|
||||||
|
cmd/fpga.c | 2 +-
|
||||||
|
cmd/nand.c | 2 +-
|
||||||
|
cmd/source.c | 2 +-
|
||||||
|
cmd/ximg.c | 2 +-
|
||||||
|
common/image-fdt.c | 2 +-
|
||||||
|
common/image-fit.c | 45 +++++++++++++++---------------
|
||||||
|
common/splash_source.c | 6 ++--
|
||||||
|
common/update.c | 2 +-
|
||||||
|
drivers/fpga/socfpga_arria10.c | 6 ++--
|
||||||
|
drivers/net/fsl-mc/mc.c | 2 +-
|
||||||
|
drivers/net/pfe_eth/pfe_firmware.c | 2 +-
|
||||||
|
include/image.h | 21 +++++++++++++-
|
||||||
|
tools/fit_common.c | 3 +-
|
||||||
|
tools/fit_image.c | 2 +-
|
||||||
|
tools/mkimage.h | 2 ++
|
||||||
|
18 files changed, 67 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c
|
||||||
|
index bfc0fac3..0561f5ef 100644
|
||||||
|
--- a/arch/arm/cpu/armv8/sec_firmware.c
|
||||||
|
+++ b/arch/arm/cpu/armv8/sec_firmware.c
|
||||||
|
@@ -316,7 +316,7 @@ __weak bool sec_firmware_is_valid(const void *sec_firmware_img)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!fit_check_format(sec_firmware_img)) {
|
||||||
|
+ if (fit_check_format(sec_firmware_img, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diff --git a/cmd/bootm.c b/cmd/bootm.c
|
||||||
|
index d5f877cb..cf9c8def 100644
|
||||||
|
--- a/cmd/bootm.c
|
||||||
|
+++ b/cmd/bootm.c
|
||||||
|
@@ -291,7 +291,7 @@ static int image_info(ulong addr)
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
puts(" FIT image found\n");
|
||||||
|
|
||||||
|
- if (!fit_check_format(hdr)) {
|
||||||
|
+ if (fit_check_format(hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
puts("Bad FIT image format!\n");
|
||||||
|
unmap_sysmem(hdr);
|
||||||
|
return 1;
|
||||||
|
@@ -368,7 +368,7 @@ static int do_imls_nor(void)
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_FIT)
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
- if (!fit_check_format(hdr))
|
||||||
|
+ if (fit_check_format(hdr, IMAGE_SIZE_INVAL))
|
||||||
|
goto next_sector;
|
||||||
|
|
||||||
|
printf("FIT Image at %08lX:\n", (ulong)hdr);
|
||||||
|
@@ -448,7 +448,7 @@ static int nand_imls_fitimage(struct mtd_info *mtd, int nand_dev, loff_t off,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!fit_check_format(imgdata)) {
|
||||||
|
+ if (fit_check_format(imgdata, IMAGE_SIZE_INVAL)) {
|
||||||
|
free(imgdata);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/cmd/disk.c b/cmd/disk.c
|
||||||
|
index 8060e753..3195db91 100644
|
||||||
|
--- a/cmd/disk.c
|
||||||
|
+++ b/cmd/disk.c
|
||||||
|
@@ -114,7 +114,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc,
|
||||||
|
/* This cannot be done earlier,
|
||||||
|
* we need complete FIT image in RAM first */
|
||||||
|
if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
|
||||||
|
- if (!fit_check_format(fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
|
||||||
|
puts("** Bad FIT image format\n");
|
||||||
|
return 1;
|
||||||
|
diff --git a/cmd/fpga.c b/cmd/fpga.c
|
||||||
|
index 8ae1c936..51410a8e 100644
|
||||||
|
--- a/cmd/fpga.c
|
||||||
|
+++ b/cmd/fpga.c
|
||||||
|
@@ -330,7 +330,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!fit_check_format(fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
puts("Bad FIT image format\n");
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
diff --git a/cmd/nand.c b/cmd/nand.c
|
||||||
|
index 92d039af..97e117a9 100644
|
||||||
|
--- a/cmd/nand.c
|
||||||
|
+++ b/cmd/nand.c
|
||||||
|
@@ -917,7 +917,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd,
|
||||||
|
#if defined(CONFIG_FIT)
|
||||||
|
/* This cannot be done earlier, we need complete FIT image in RAM first */
|
||||||
|
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
|
||||||
|
- if (!fit_check_format (fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ);
|
||||||
|
puts ("** Bad FIT image format\n");
|
||||||
|
return 1;
|
||||||
|
diff --git a/cmd/source.c b/cmd/source.c
|
||||||
|
index b6c709a3..71f71528 100644
|
||||||
|
--- a/cmd/source.c
|
||||||
|
+++ b/cmd/source.c
|
||||||
|
@@ -107,7 +107,7 @@ int image_source_script(ulong addr, const char *fit_uname)
|
||||||
|
#if defined(CONFIG_FIT)
|
||||||
|
case IMAGE_FORMAT_FIT:
|
||||||
|
fit_hdr = buf;
|
||||||
|
- if (!fit_check_format (fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
puts ("Bad FIT image format\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/cmd/ximg.c b/cmd/ximg.c
|
||||||
|
index 159ba516..ef738ebf 100644
|
||||||
|
--- a/cmd/ximg.c
|
||||||
|
+++ b/cmd/ximg.c
|
||||||
|
@@ -136,7 +136,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||||
|
"at %08lx ...\n", uname, addr);
|
||||||
|
|
||||||
|
fit_hdr = (const void *)addr;
|
||||||
|
- if (!fit_check_format(fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
puts("Bad FIT image format\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/common/image-fdt.c b/common/image-fdt.c
|
||||||
|
index b63e772b..0b770e27 100644
|
||||||
|
--- a/common/image-fdt.c
|
||||||
|
+++ b/common/image-fdt.c
|
||||||
|
@@ -399,7 +399,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,
|
||||||
|
*/
|
||||||
|
#if CONFIG_IS_ENABLED(FIT)
|
||||||
|
/* check FDT blob vs FIT blob */
|
||||||
|
- if (fit_check_format(buf)) {
|
||||||
|
+ if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
|
||||||
|
ulong load, len;
|
||||||
|
|
||||||
|
fdt_noffset = boot_get_fdt_fit(images,
|
||||||
|
diff --git a/common/image-fit.c b/common/image-fit.c
|
||||||
|
index 1ece100a..470321c5 100644
|
||||||
|
--- a/common/image-fit.c
|
||||||
|
+++ b/common/image-fit.c
|
||||||
|
@@ -8,6 +8,8 @@
|
||||||
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#define LOG_CATEGORY LOGC_BOOT
|
||||||
|
+
|
||||||
|
#ifdef USE_HOSTCC
|
||||||
|
#include "mkimage.h"
|
||||||
|
#include <time.h>
|
||||||
|
@@ -1533,40 +1535,39 @@ int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
|
||||||
|
return (comp == image_comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * fit_check_format - sanity check FIT image format
|
||||||
|
- * @fit: pointer to the FIT format image header
|
||||||
|
- *
|
||||||
|
- * fit_check_format() runs a basic sanity FIT image verification.
|
||||||
|
- * Routine checks for mandatory properties, nodes, etc.
|
||||||
|
- *
|
||||||
|
- * returns:
|
||||||
|
- * 1, on success
|
||||||
|
- * 0, on failure
|
||||||
|
- */
|
||||||
|
-int fit_check_format(const void *fit)
|
||||||
|
+int fit_check_format(const void *fit, ulong size)
|
||||||
|
{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* A FIT image must be a valid FDT */
|
||||||
|
+ ret = fdt_check_header(fit);
|
||||||
|
+ if (ret) {
|
||||||
|
+ log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
|
||||||
|
+ ret);
|
||||||
|
+ return -ENOEXEC;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* mandatory / node 'description' property */
|
||||||
|
- if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
|
||||||
|
- debug("Wrong FIT format: no description\n");
|
||||||
|
- return 0;
|
||||||
|
+ if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
|
||||||
|
+ log_debug("Wrong FIT format: no description\n");
|
||||||
|
+ return -ENOMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IMAGE_ENABLE_TIMESTAMP) {
|
||||||
|
/* mandatory / node 'timestamp' property */
|
||||||
|
- if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
|
||||||
|
- debug("Wrong FIT format: no timestamp\n");
|
||||||
|
- return 0;
|
||||||
|
+ if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
|
||||||
|
+ log_debug("Wrong FIT format: no timestamp\n");
|
||||||
|
+ return -ENODATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mandatory subimages parent '/images' node */
|
||||||
|
if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
|
||||||
|
- debug("Wrong FIT format: no images parent node\n");
|
||||||
|
- return 0;
|
||||||
|
+ log_debug("Wrong FIT format: no images parent node\n");
|
||||||
|
+ return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return 1;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1899,7 +1900,7 @@ 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)) {
|
||||||
|
+ if (fit_check_format(fit, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("Bad FIT %s image format!\n", prop_name);
|
||||||
|
bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
|
||||||
|
return -ENOEXEC;
|
||||||
|
diff --git a/common/splash_source.c b/common/splash_source.c
|
||||||
|
index f51ca5dd..bad9a779 100644
|
||||||
|
--- a/common/splash_source.c
|
||||||
|
+++ b/common/splash_source.c
|
||||||
|
@@ -336,10 +336,10 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr)
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
- res = fit_check_format(fit_header);
|
||||||
|
- if (!res) {
|
||||||
|
+ res = fit_check_format(fit_header, IMAGE_SIZE_INVAL);
|
||||||
|
+ if (res) {
|
||||||
|
debug("Could not find valid FIT image\n");
|
||||||
|
- return -EINVAL;
|
||||||
|
+ return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the splash image node */
|
||||||
|
diff --git a/common/update.c b/common/update.c
|
||||||
|
index c8dd346a..12626706 100644
|
||||||
|
--- a/common/update.c
|
||||||
|
+++ b/common/update.c
|
||||||
|
@@ -282,7 +282,7 @@ int update_tftp(ulong addr, char *interface, char *devstring)
|
||||||
|
got_update_file:
|
||||||
|
fit = (void *)addr;
|
||||||
|
|
||||||
|
- if (!fit_check_format((void *)fit)) {
|
||||||
|
+ if (fit_check_format((void *)fit, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("Bad FIT format of the update file, aborting "
|
||||||
|
"auto-update\n");
|
||||||
|
return 1;
|
||||||
|
diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c
|
||||||
|
index dfd3cbb4..c80c4bc3 100644
|
||||||
|
--- a/drivers/fpga/socfpga_arria10.c
|
||||||
|
+++ b/drivers/fpga/socfpga_arria10.c
|
||||||
|
@@ -564,10 +564,10 @@ static int first_loading_rbf_to_buffer(struct udevice *dev,
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- ret = fit_check_format(buffer_p);
|
||||||
|
- if (!ret) {
|
||||||
|
+ ret = fit_check_format(buffer_p, IMAGE_SIZE_INVAL);
|
||||||
|
+ if (ret) {
|
||||||
|
debug("FPGA: No valid FIT image was found.\n");
|
||||||
|
- return -EBADF;
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
confs_noffset = fdt_path_offset(buffer_p, FIT_CONFS_PATH);
|
||||||
|
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
|
||||||
|
index e516c3c1..c7df8d24 100644
|
||||||
|
--- a/drivers/net/fsl-mc/mc.c
|
||||||
|
+++ b/drivers/net/fsl-mc/mc.c
|
||||||
|
@@ -141,7 +141,7 @@ int parse_mc_firmware_fit_image(u64 mc_fw_addr,
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!fit_check_format(fit_hdr)) {
|
||||||
|
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
diff --git a/drivers/net/pfe_eth/pfe_firmware.c b/drivers/net/pfe_eth/pfe_firmware.c
|
||||||
|
index 0493cfe8..b0ef83c5 100644
|
||||||
|
--- a/drivers/net/pfe_eth/pfe_firmware.c
|
||||||
|
+++ b/drivers/net/pfe_eth/pfe_firmware.c
|
||||||
|
@@ -154,7 +154,7 @@ static int pfe_fit_check(void)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!fit_check_format(pfe_fit_addr)) {
|
||||||
|
+ if (fit_check_format(pfe_fit_addr, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("PFE Firmware: Bad firmware image (bad FIT header)\n");
|
||||||
|
ret = -1;
|
||||||
|
return ret;
|
||||||
|
diff --git a/include/image.h b/include/image.h
|
||||||
|
index ad81dad4..2ea5a685 100644
|
||||||
|
--- a/include/image.h
|
||||||
|
+++ b/include/image.h
|
||||||
|
@@ -116,6 +116,9 @@ extern ulong image_load_addr; /* Default Load Address */
|
||||||
|
extern ulong image_save_addr; /* Default Save Address */
|
||||||
|
extern ulong image_save_size; /* Default Save Size */
|
||||||
|
|
||||||
|
+/* An invalid size, meaning that the image size is not known */
|
||||||
|
+#define IMAGE_SIZE_INVAL (-1UL)
|
||||||
|
+
|
||||||
|
enum ih_category {
|
||||||
|
IH_ARCH,
|
||||||
|
IH_COMP,
|
||||||
|
@@ -1112,7 +1115,23 @@ int fit_image_check_os(const void *fit, int noffset, uint8_t os);
|
||||||
|
int fit_image_check_arch(const void *fit, int noffset, uint8_t arch);
|
||||||
|
int fit_image_check_type(const void *fit, int noffset, uint8_t type);
|
||||||
|
int fit_image_check_comp(const void *fit, int noffset, uint8_t comp);
|
||||||
|
-int fit_check_format(const void *fit);
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * fit_check_format() - Check that the FIT is valid
|
||||||
|
+ *
|
||||||
|
+ * This performs various checks on the FIT to make sure it is suitable for
|
||||||
|
+ * use, looking for mandatory properties, nodes, etc.
|
||||||
|
+ *
|
||||||
|
+ * If FIT_FULL_CHECK is enabled, it also runs it through libfdt to make
|
||||||
|
+ * sure that there are no strange tags or broken nodes in the FIT.
|
||||||
|
+ *
|
||||||
|
+ * @fit: pointer to the FIT format image header
|
||||||
|
+ * @return 0 if OK, -ENOEXEC if not an FDT file, -EINVAL if the full FDT check
|
||||||
|
+ * failed (e.g. due to bad structure), -ENOMSG if the description is
|
||||||
|
+ * missing, -ENODATA if the timestamp is missing, -ENOENT if the /images
|
||||||
|
+ * path is missing
|
||||||
|
+ */
|
||||||
|
+int fit_check_format(const void *fit, ulong size);
|
||||||
|
|
||||||
|
int fit_conf_find_compat(const void *fit, const void *fdt);
|
||||||
|
|
||||||
|
diff --git a/tools/fit_common.c b/tools/fit_common.c
|
||||||
|
index cdf987d3..52b63296 100644
|
||||||
|
--- a/tools/fit_common.c
|
||||||
|
+++ b/tools/fit_common.c
|
||||||
|
@@ -26,7 +26,8 @@
|
||||||
|
int fit_verify_header(unsigned char *ptr, int image_size,
|
||||||
|
struct image_tool_params *params)
|
||||||
|
{
|
||||||
|
- if (fdt_check_header(ptr) != EXIT_SUCCESS || !fit_check_format(ptr))
|
||||||
|
+ if (fdt_check_header(ptr) != EXIT_SUCCESS ||
|
||||||
|
+ fit_check_format(ptr, IMAGE_SIZE_INVAL))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
diff --git a/tools/fit_image.c b/tools/fit_image.c
|
||||||
|
index a082d938..44990822 100644
|
||||||
|
--- a/tools/fit_image.c
|
||||||
|
+++ b/tools/fit_image.c
|
||||||
|
@@ -883,7 +883,7 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params)
|
||||||
|
/* Indent string is defined in header image.h */
|
||||||
|
p = IMAGE_INDENT_STRING;
|
||||||
|
|
||||||
|
- if (!fit_check_format(fit)) {
|
||||||
|
+ if (fit_check_format(fit, IMAGE_SIZE_INVAL)) {
|
||||||
|
printf("Bad FIT image format\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
diff --git a/tools/mkimage.h b/tools/mkimage.h
|
||||||
|
index 5b096a54..0d314844 100644
|
||||||
|
--- a/tools/mkimage.h
|
||||||
|
+++ b/tools/mkimage.h
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
#define debug(fmt,args...)
|
||||||
|
#endif /* MKIMAGE_DEBUG */
|
||||||
|
|
||||||
|
+#define log_debug(fmt, args...) debug(fmt, ##args)
|
||||||
|
+
|
||||||
|
static inline void *map_sysmem(ulong paddr, unsigned long len)
|
||||||
|
{
|
||||||
|
return (void *)(uintptr_t)paddr;
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
106
backport-0002-CVE-2021-27138.patch
Normal file
106
backport-0002-CVE-2021-27138.patch
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
From 3f04db891a353f4b127ed57279279f851c6b4917 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Glass <sjg@chromium.org>
|
||||||
|
Date: Mon, 15 Feb 2021 17:08:12 -0700
|
||||||
|
Subject: [PATCH] image: Check for unit addresses in FITs
|
||||||
|
|
||||||
|
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 ++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 52 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/common/image-fit.c b/common/image-fit.c
|
||||||
|
index 47f3b7f7..3d173ad4 100644
|
||||||
|
--- a/common/image-fit.c
|
||||||
|
+++ b/common/image-fit.c
|
||||||
|
@@ -1545,6 +1545,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;
|
||||||
|
@@ -1566,10 +1594,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1926,10 +1971,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) {
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
118
backport-0003-CVE-2021-27097.patch
Normal file
118
backport-0003-CVE-2021-27097.patch
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
From 6f3c2d8aa5e6cbd80b5e869bbbddecb66c329d01 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Glass <sjg@chromium.org>
|
||||||
|
Date: Mon, 15 Feb 2021 17:08:10 -0700
|
||||||
|
Subject: [PATCH] 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>
|
||||||
|
---
|
||||||
|
Kconfig | 19 +++++++++++++++++++
|
||||||
|
common/image-fit.c | 18 +++++++++++++++++-
|
||||||
|
2 files changed, 36 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Kconfig b/Kconfig
|
||||||
|
index 8f3fba08..11b480f6 100644
|
||||||
|
--- a/Kconfig
|
||||||
|
+++ b/Kconfig
|
||||||
|
@@ -365,6 +365,15 @@ config FIT_ENABLE_SHA256_SUPPORT
|
||||||
|
SHA256 variant is supported: SHA512 and others are not currently
|
||||||
|
supported in U-Boot.
|
||||||
|
|
||||||
|
+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
|
||||||
|
@@ -372,6 +381,7 @@ config FIT_SIGNATURE
|
||||||
|
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
|
||||||
|
@@ -455,6 +465,14 @@ config SPL_FIT_PRINT
|
||||||
|
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
|
||||||
|
@@ -462,6 +480,7 @@ config SPL_FIT_SIGNATURE
|
||||||
|
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)"
|
||||||
|
diff --git a/common/image-fit.c b/common/image-fit.c
|
||||||
|
index 470321c5..e49baea7 100644
|
||||||
|
--- a/common/image-fit.c
|
||||||
|
+++ b/common/image-fit.c
|
||||||
|
@@ -17,7 +17,6 @@
|
||||||
|
#include <u-boot/crc.h>
|
||||||
|
#else
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
-#include <linux/kconfig.h>
|
||||||
|
#include <common.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <log.h>
|
||||||
|
@@ -29,6 +28,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#include <bootm.h>
|
||||||
|
#include <image.h>
|
||||||
|
+#include <linux/kconfig.h>
|
||||||
|
#include <bootstage.h>
|
||||||
|
#include <u-boot/crc.h>
|
||||||
|
#include <u-boot/md5.h>
|
||||||
|
@@ -1547,6 +1547,22 @@ int fit_check_format(const void *fit, ulong size)
|
||||||
|
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");
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: uboot-tools
|
Name: uboot-tools
|
||||||
Version: 2020.07
|
Version: 2020.07
|
||||||
Release: 4
|
Release: 5
|
||||||
Summary: tools for U-Boot
|
Summary: tools for U-Boot
|
||||||
License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+
|
License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+
|
||||||
URL: http://www.denx.de/wiki/U-Boot
|
URL: http://www.denx.de/wiki/U-Boot
|
||||||
@ -28,6 +28,11 @@ Patch0008: rockchip-Pinebook-Pro-Fixes.patch
|
|||||||
# RPi4
|
# RPi4
|
||||||
Patch0009: USB-host-support-for-Raspberry-Pi-4-board-64-bit.patch
|
Patch0009: USB-host-support-for-Raspberry-Pi-4-board-64-bit.patch
|
||||||
Patch0010: rpi-Enable-using-the-DT-provided-by-the-Raspberry-Pi.patch
|
Patch0010: rpi-Enable-using-the-DT-provided-by-the-Raspberry-Pi.patch
|
||||||
|
Patch0011: backport-0001-CVE-2021-27097.patch
|
||||||
|
Patch0012: backport-0002-CVE-2021-27097.patch
|
||||||
|
Patch0013: backport-0003-CVE-2021-27097.patch
|
||||||
|
Patch0014: backport-0001-CVE-2021-27138.patch
|
||||||
|
Patch0015: backport-0002-CVE-2021-27138.patch
|
||||||
|
|
||||||
BuildRequires: bc dtc gcc make flex bison git-core openssl-devel gdb
|
BuildRequires: bc dtc gcc make flex bison git-core openssl-devel gdb
|
||||||
BuildRequires: python3-unversioned-command python3-devel python3-setuptools
|
BuildRequires: python3-unversioned-command python3-devel python3-setuptools
|
||||||
@ -244,6 +249,12 @@ cp -p board/warp7/README builds/docs/README.warp7
|
|||||||
%{_mandir}/man1/mkimage.1*
|
%{_mandir}/man1/mkimage.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 16 2021 yanglu <yanglu@60huawei.com> - 2020.07-5
|
||||||
|
- Type:cves
|
||||||
|
- ID:CVE-2021-27097 CVE-2021-27138
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2021-27097CVE-2021-27138
|
||||||
|
|
||||||
* Wed Dec 16 2020 zhanzhimin <zhanzhimin@huawei.com> - 2020.07-4
|
* Wed Dec 16 2020 zhanzhimin <zhanzhimin@huawei.com> - 2020.07-4
|
||||||
- Update Source0
|
- Update Source0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user