[PATCH v1 1/7] bootstd: rauc: Fix NULL dereference in get_slot()

Aristo Chen via U-Boot <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260813155617.184928-2-aristo.chen__13241.7608330556$1786643981$gmane$org@canonical.com>
priv->slots is a NULL-terminated array of pointers, but get_slot()
tests priv->slots[i]->name in its loop condition, dereferencing each
entry before checking it against NULL. When slot_name does not match
any configured slot, the loop reaches the terminator and dereferences
a NULL pointer.

This is reachable from the BOOT_ORDER environment variable: an entry
naming a slot that is not listed in CONFIG_BOOTMETH_RAUC_PARTITIONS
crashes U-Boot in distro_rauc_scan_parts() or distro_rauc_boot().
Since BOOT_ORDER is typically stored in a disk-resident environment
written by the OS, a stray or corrupted value must not crash the
bootloader.

Test the array entry itself before using its name, as
distro_rauc_priv_free() already does. Both callers already handle a
NULL return.

Extend the bootflow_rauc test to scan with a BOOT_ORDER naming an
unconfigured slot. Without this fix the test crashes with SIGSEGV.

Fixes: 7e5c2c782fb9 ("bootstd: Add implementation for bootmeth rauc")
Signed-off-by: Aristo Chen <[email protected]>
---
 boot/bootmeth_rauc.c |  2 +-
 test/boot/bootflow.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
index d7b0c686ffe..32be641ab54 100644
--- a/boot/bootmeth_rauc.c
+++ b/boot/bootmeth_rauc.c
@@ -71,7 +71,7 @@ static struct distro_rauc_slot *get_slot(struct distro_rauc_priv *priv,
 {
 	int i;
 
-	for (i = 0; priv->slots[i]->name; i++) {
+	for (i = 0; priv->slots[i]; i++) {
 		if (!strcmp(priv->slots[i]->name, slot_name))
 			return priv->slots[i];
 	}
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 1cc137c9700..837c5a7a4aa 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -1444,6 +1444,22 @@ static int bootflow_rauc(struct unit_test_state *uts)
 
 	ut_assert_console_end();
 
+	/*
+	 * Scan with a BOOT_ORDER naming a slot that has no configured
+	 * partitions. get_slot() must not crash on the NULL array terminator;
+	 * the bootflow just becomes invalid.
+	 */
+	ut_assertok(env_set("BOOT_ORDER", "A B rescue"));
+	ut_assertok(run_command("bootflow scan", 0));
+	ut_assert_nextline("No bootflows found; try again with -l");
+	ut_assert_console_end();
+
+	ut_assertok(run_command("bootflow list", 0));
+	ut_assert_skip_to_line("(0 bootflows, 0 valid)");
+	ut_assert_console_end();
+
+	ut_assertok(env_set("BOOT_ORDER", "A B"));
+
 	/* Restore the order used by the device tree */
 	std->bootdev_order = old_order;
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.