From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2025.09.y 57/58] FIT: reconstruct hashed-nodes property during verification
Date: Fri, 13 Mar 2026 14:25:41 +0100 [thread overview]
Message-ID: <20260313132631.2257573-58-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20260313132631.2257573-1-a.fatoum@pengutronix.de>
From: Sascha Hauer <s.hauer@pengutronix.de>
The hashed-nodes property in FIT signed image configurations is used to
determine which nodes are hashed, but is itself not hashed, so could be
manipulated.
To fix this do not use the hashed-nodes property to calculate which
nodes must be hashed, but instead reconstruct the hashed nodes list by
the images used in a FIT configuration, the same way mkimage does it
when creating the image.
The approach mirrors U-Boot commit 2092322b31c ("boot: Add
fit_config_get_hash_list() to build signed node list")
Fixes: ac55adb321 ("bootm: add initial FIT support")
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Tested-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.kernel.org/barebox/859a45ba-28c0-4d37-853f-39529ab2521b@pengutronix.de
---
common/image-fit.c | 123 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 106 insertions(+), 17 deletions(-)
diff --git a/common/image-fit.c b/common/image-fit.c
index 9748e5f1d8f0..eae6e6efcf64 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -55,18 +55,6 @@ static char *dt_string(struct fdt_header *f, char *strstart, uint32_t ofs)
return strstart + ofs;
}
-static int of_read_string_list(struct device_node *np, const char *name, struct string_list *sl)
-{
- struct property *prop;
- const char *s;
-
- of_property_for_each_string(np, name, prop, s) {
- string_list_add(sl, s);
- }
-
- return prop ? 0 : -EINVAL;
-}
-
static int fit_digest(struct fit_handle *handle, struct digest *digest,
struct string_list *inc_nodes, struct string_list *exc_props,
uint32_t hashed_strings_start, uint32_t hashed_strings_size)
@@ -312,10 +300,106 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
return 0;
}
+static int fit_config_build_hash_nodes(struct fit_handle *handle,
+ struct device_node *conf_node,
+ struct string_list *node_list)
+{
+ struct device_node *image_node, *child;
+ struct property *prop;
+ const char *unit;
+ int i, ret, count;
+
+ ret = string_list_add(node_list, "/");
+ if (ret)
+ return ret;
+ ret = string_list_add_asprintf(node_list, "%s", conf_node->full_name);
+ if (ret)
+ return ret;
+
+ for_each_property_of_node(conf_node, prop) {
+ if (!strcmp(prop->name, "description") ||
+ !strcmp(prop->name, "compatible") ||
+ !strcmp(prop->name, "default"))
+ continue;
+
+ count = of_property_count_strings(conf_node, prop->name);
+ for (i = 0; i < count; i++) {
+ if (of_property_read_string_index(conf_node, prop->name,
+ i, &unit))
+ return -EINVAL;
+
+ if (strchr(unit, '/'))
+ return -EINVAL;
+
+ ret = string_list_add_asprintf(node_list, "/images/%s", unit);
+ if (ret)
+ return ret;
+
+ image_node = of_get_child_by_name(handle->images, unit);
+ if (!image_node)
+ return -EINVAL;
+
+ for_each_child_of_node(image_node, child) {
+ if (!of_node_has_prefix(child, "hash"))
+ continue;
+ ret = string_list_add_asprintf(node_list, "/images/%s/%s",
+ unit, child->name);
+ if (ret)
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int fit_config_check_hash_nodes(struct device_node *sig_node,
+ struct string_list *inc_nodes)
+{
+ struct string_list *entry;
+ const char *node;
+ int ret, i = 0;
+
+ /*
+ * Check if the hashed-nodes property matches the list of nodes we calculated.
+ * We don't use the hashed-nodes property finally, but let's check for consistency
+ * to inform the user if something is wrong.
+ */
+
+ string_list_for_each_entry(entry, inc_nodes) {
+
+ ret = of_property_read_string_index(sig_node, "hashed-nodes", i, &node);
+ if (ret) {
+ pr_err("Cannot read hashed-node[%u]: %pe\n", i,
+ ERR_PTR(ret));
+ return ret;
+ }
+
+ if (strcmp(entry->str, node)) {
+ pr_err("hashed-node[%u] doesn't match calculated node: %s != %s\n",
+ i, entry->str, node);
+ return -EINVAL;
+ }
+
+ i++;
+ }
+
+ ret = of_property_read_string_index(sig_node, "hashed-nodes", i,
+ &node);
+ if (!ret) {
+ pr_err("hashed-nodes property has more entries than we calculated\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/*
* The consistency of the FTD structure was already checked by of_unflatten_dtb()
*/
-static int fit_verify_signature(struct fit_handle *handle, struct device_node *sig_node)
+static int fit_verify_signature(struct fit_handle *handle,
+ struct device_node *sig_node,
+ struct device_node *conf_node)
{
uint32_t hashed_strings_start, hashed_strings_size;
struct string_list inc_nodes, exc_props;
@@ -329,6 +413,7 @@ static int fit_verify_signature(struct fit_handle *handle, struct device_node *s
pr_err("hashed-strings start not found in %pOF\n", sig_node);
return -EINVAL;
}
+
if (of_property_read_u32_index(sig_node, "hashed-strings", 1,
&hashed_strings_size)) {
pr_err("hashed-strings size not found in %pOF\n", sig_node);
@@ -338,12 +423,16 @@ static int fit_verify_signature(struct fit_handle *handle, struct device_node *s
string_list_init(&inc_nodes);
string_list_init(&exc_props);
- if (of_read_string_list(sig_node, "hashed-nodes", &inc_nodes)) {
- pr_err("hashed-nodes property not found in %pOF\n", sig_node);
- ret = -EINVAL;
+ ret = fit_config_build_hash_nodes(handle, conf_node, &inc_nodes);
+ if (ret) {
+ pr_err("Failed to build hash node list for %pOF\n", conf_node);
goto out_sl;
}
+ ret = fit_config_check_hash_nodes(sig_node, &inc_nodes);
+ if (ret)
+ goto out_sl;
+
string_list_add(&exc_props, "data");
digest = fit_alloc_digest(sig_node, &algo);
@@ -738,7 +827,7 @@ int fit_config_verify_signature(struct fit_handle *handle, struct device_node *c
if (handle->verbose)
of_print_nodes(sig_node, 0, ~0);
- ret = fit_verify_signature(handle, sig_node);
+ ret = fit_verify_signature(handle, sig_node, conf_node);
if (ret < 0)
return ret;
}
--
2.47.3
next prev parent reply other threads:[~2026-03-13 13:34 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-13 13:24 [PATCH v2025.09.y 00/58] Backports for v2025.09.1 Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 01/58] clk: clkdev: fix format security Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 02/58] scripts: imx: fix string in further auth block Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 03/58] scripts: imx-image: support DCD_WRITE on closed dev Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 04/58] mci: am654-sdhci: Wait for transfer complete interrupt with MMC_RSP_BUSY cmd Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 05/58] video: simplefb-client: switch to dev_get_resource Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 06/58] MIPS: qemu-malta_defconfig: Use largest possible relocation table Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 07/58] firmware: handle firmware files being links correctly Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 08/58] drivers: don't propagate of_alias_get_id's -ENODEV out of probe Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 09/58] ARM: socfpga: arria10-reset-manager: release UART0 Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 10/58] bug: add support for CONFIG_DEBUG_BUGVERBOSE Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 11/58] driver: implement get_free_deviceid_from() Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 12/58] sandbox: fix make dependency for sandbox Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 13/58] gpio: Fix GPIOD_ASIS flag Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 14/58] i.MX: HAB: fix field return unlock fuse uid Ahmad Fatoum
2026-03-13 13:24 ` [PATCH v2025.09.y 15/58] ARM: cpu: common: skip R_ARM_NONE relocations Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 16/58] mmc: resolve conflict between MMC_CAP_NONREMOVABLE and MMC_CAP_1_8V_DDR Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 17/58] virtio: ring: fix stale data in queue after reset Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 18/58] scripts: Makefile.lib: suppress graph_port warnings for overlays Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 19/58] ARM: Rockchip: rk3576-prtpuk: suppress video graph warning Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 20/58] kbuild: fold rmdirs into rmfiles Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 21/58] mtd: nand: mxc_nand: use clk_get_optional for clock handling Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 22/58] FIT: fix double free issue with >1 reference count Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 23/58] net: phy: mdio_bus: fix freeing of cdev name before devfs_remove Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 24/58] bootm: fix bootm override saving/restoring Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 25/58] common: tlv: Correct eth address list fixup Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 26/58] common: tlv: fix link error when CONFIG_NET is disabled Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 27/58] include: array_size.h: make header self-contained Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 28/58] RISC-V: dts: fix generation of dtbs-list Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 29/58] of: overlay: propagate error unflattening DTBO Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 30/58] efi: fix potential NULL dereference Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 31/58] FIT: fix potential underflow of stack array Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 32/58] of: fdt: fix double free in fdt_ensure_space Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 33/58] of: overlay: initialize ret to fix garbage return value Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 34/58] firmware: xilinx-fpga: fix double free in probe error path Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 35/58] driver: fix missing va_end in dev_add_alias " Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 36/58] net: eth: avoid overlapping memcpy in eth_set_ethaddr Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 37/58] pmdomain: fix dereference before NULL check in genpd_get_from_provider Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 38/58] net: phy: add NULL check for phy driver in page accessors Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 39/58] open: add missing mode argument to O_CREAT calls Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 40/58] hush: add NULL check for gl_pathv after do_glob_in_argv Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 41/58] i2c: rk3x: fix NULL pointer dereference on repeated NACK Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 42/58] mci: imx-esdhc: remove misleading NULL check for cmd pointer Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 43/58] mci: spi: initialize r1 to fix garbage return value Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 44/58] virtio: fix variable shadowing in virtqueue_add_sgs input scatter loop Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 45/58] video: mode-helpers: preserve sync polarity in fb_videomode conversion Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 46/58] ARM: rockchip: dmc: use define instead of hardcoded value Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 47/58] ARM: rockchip: atf: Fix memend Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 48/58] regulator: fix handling of off_on_delay Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 49/58] regulator: fixed: handle startup-delay-us property Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 50/58] scripts: include: break dependency of list.h on kernel.h Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 51/58] Makefile: include scripts/ in compile_commands.json Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 52/58] jwt: fix buffer overflow and double-free in jwt_part_parse Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 53/58] of: fdt: fix heap-buffer-overflow in fdt_machine_is_compatible Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 54/58] powerpc: fix initjmp storing function pointer at wrong offset Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 55/58] net: r8169: drain RX descriptor ring Ahmad Fatoum
2026-03-13 13:25 ` [PATCH v2025.09.y 56/58] of: fdt: refuse / in property and node names Ahmad Fatoum
2026-03-13 13:25 ` Ahmad Fatoum [this message]
2026-03-13 13:25 ` [PATCH v2025.09.y 58/58] scripts: fix build failure with glibc 2.43 Ahmad Fatoum
2026-03-13 14:56 ` [PATCH v2025.09.y 00/58] Backports for v2025.09.1 Sascha Hauer
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=20260313132631.2257573-58-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox