summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch')
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch362
1 files changed, 362 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch
new file mode 100644
index 000000000..deb40a938
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/CVE-2021-27097/0001-image-Adjust-the-workings-of-fit_check_format.patch
@@ -0,0 +1,362 @@
+From 8c6e79df48988760178787af39ecd01954569e81 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>
+---
+ board/aspeed/ast-g5/fw-update.c | 2 +-
+ cmd/bootm.c | 6 ++---
+ cmd/disk.c | 2 +-
+ cmd/fdc.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 | 44 ++++++++++++++++-----------------
+ common/update.c | 2 +-
+ drivers/misc/fsl_debug_server.c | 2 +-
+ drivers/net/fsl-mc/mc.c | 2 +-
+ include/image.h | 21 +++++++++++++++-
+ tools/fit_image.c | 2 +-
+ tools/mkimage.h | 2 ++
+ 16 files changed, 59 insertions(+), 38 deletions(-)
+
+diff --git a/board/aspeed/ast-g5/fw-update.c b/board/aspeed/ast-g5/fw-update.c
+index 99239938b5ee..50b46a2eff5a 100644
+--- a/board/aspeed/ast-g5/fw-update.c
++++ b/board/aspeed/ast-g5/fw-update.c
+@@ -328,7 +328,7 @@ static int verify_image(void)
+ switch (genimg_get_format(hdr)) {
+ case IMAGE_FORMAT_FIT:
+ printf(" FIT image found\n");
+- if (!fit_check_format(hdr)) {
++ if (fit_check_format(hdr, IMAGE_SIZE_INVAL)) {
+ printf("Bad FIT image format!\n");
+ return -1;
+ }
+diff --git a/cmd/bootm.c b/cmd/bootm.c
+index 8da750ec5101..442ae0ba600e 100644
+--- a/cmd/bootm.c
++++ b/cmd/bootm.c
+@@ -288,7 +288,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");
+ return 1;
+ }
+@@ -361,7 +361,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);
+@@ -441,7 +441,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 92de3af8a5c0..3038aacf2215 100644
+--- a/cmd/disk.c
++++ b/cmd/disk.c
+@@ -113,7 +113,7 @@ int common_diskboot(cmd_tbl_t *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/fdc.c b/cmd/fdc.c
+index d2281abbda90..7395e61fcdae 100644
+--- a/cmd/fdc.c
++++ b/cmd/fdc.c
+@@ -731,7 +731,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ #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)) {
+ puts ("** Bad FIT image format\n");
+ return 1;
+ }
+diff --git a/cmd/fpga.c b/cmd/fpga.c
+index 8956eb1b654a..ecb26d77c1cc 100644
+--- a/cmd/fpga.c
++++ b/cmd/fpga.c
+@@ -248,7 +248,7 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ return 1;
+ }
+
+- 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/nand.c b/cmd/nand.c
+index ffdeea41a5a7..2b1c931bd937 100644
+--- a/cmd/nand.c
++++ b/cmd/nand.c
+@@ -902,7 +902,7 @@ static int nand_load_image(cmd_tbl_t *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 db7ab7e5f409..300db33b73cd 100644
+--- a/cmd/source.c
++++ b/cmd/source.c
+@@ -97,7 +97,7 @@ source (ulong addr, const char *fit_uname)
+ }
+
+ 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 d033c15b629c..0e26e747f25d 100644
+--- a/cmd/ximg.c
++++ b/cmd/ximg.c
+@@ -132,7 +132,7 @@ do_imgextract(cmd_tbl_t * 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 6cac7dbb7f8b..9b372577dafc 100644
+--- a/common/image-fdt.c
++++ b/common/image-fdt.c
+@@ -353,7 +353,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 = fit_image_load(images,
+diff --git a/common/image-fit.c b/common/image-fit.c
+index 322fde728b50..34bbc8645205 100644
+--- a/common/image-fit.c
++++ b/common/image-fit.c
+@@ -9,6 +9,8 @@
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
++#define LOG_CATEGORY LOGC_BOOT
++
+ #ifdef USE_HOSTCC
+ #include "mkimage.h"
+ #include <image.h>
+@@ -1212,40 +1214,38 @@ 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;
++
++ 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;
+ }
+
+
+@@ -1585,7 +1585,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/update.c b/common/update.c
+index 1da80b70f2db..521772c3645b 100644
+--- a/common/update.c
++++ b/common/update.c
+@@ -279,7 +279,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/misc/fsl_debug_server.c b/drivers/misc/fsl_debug_server.c
+index 98d9fbe534c3..25713316a1f5 100644
+--- a/drivers/misc/fsl_debug_server.c
++++ b/drivers/misc/fsl_debug_server.c
+@@ -63,7 +63,7 @@ int debug_server_parse_firmware_fit_image(const void **raw_image_addr,
+ goto out_error;
+ }
+
+- if (!fit_check_format(fit_hdr)) {
++ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
+ printf("Debug Server FW: Bad FIT image format\n");
+ goto out_error;
+ }
+diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
+index 1811b0fe1a3f..243563eac400 100644
+--- a/drivers/net/fsl-mc/mc.c
++++ b/drivers/net/fsl-mc/mc.c
+@@ -124,7 +124,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/include/image.h b/include/image.h
+index 2c6ef4de259d..130dc03bfb3c 100644
+--- a/include/image.h
++++ b/include/image.h
+@@ -384,6 +384,9 @@ extern bootm_headers_t images;
+ #define uimage_to_cpu(x) be32_to_cpu(x)
+ #define cpu_to_uimage(x) cpu_to_be32(x)
+
++/* An invalid size, meaning that the image size is not known */
++#define IMAGE_SIZE_INVAL (-1UL)
++
+ /*
+ * Translation table for entries of a specific type; used by
+ * get_table_entry_id() and get_table_entry_name().
+@@ -907,7 +910,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_image.c b/tools/fit_image.c
+index 58aa8e27db3e..6960cc74d23f 100644
+--- a/tools/fit_image.c
++++ b/tools/fit_image.c
+@@ -721,7 +721,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 3f369b748ed1..3c6c680218a2 100644
+--- a/tools/mkimage.h
++++ b/tools/mkimage.h
+@@ -30,6 +30,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.17.1
+