[PATCH v1 3/7] bootstd: rauc: Free string lists on error paths

Aristo Chen via U-Boot <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260813155617.184928-4-aristo.chen__35779.4238998153$1786643977$gmane$org@canonical.com>
str_to_list() allocates a copy of the input string plus a pointer
array, which must be released with str_free_list(). Several error
paths return early without doing so and leak both allocations:

- distro_rauc_scan_parts() when BOOT_ORDER names an unknown slot
- distro_rauc_read_bootflow() and find_active_slot() when reading or
  writing a BOOT_*_LEFT variable fails

The scan_parts leak is the most visible one: a stray BOOT_ORDER entry
leaks the list on every scan attempt, and scans can be retried
indefinitely from the U-Boot prompt.

Free the list before each early return.

Fixes: 7e5c2c782fb9 ("bootstd: Add implementation for bootmeth rauc")
Fixes: f271b0627001 ("bootstd: rauc: Only scan all partitions instead of boot files")
Signed-off-by: Aristo Chen <[email protected]>
---
 boot/bootmeth_rauc.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
index 3e76eabe2fb..12ab9fc5bbd 100644
--- a/boot/bootmeth_rauc.c
+++ b/boot/bootmeth_rauc.c
@@ -117,8 +117,10 @@ static int distro_rauc_scan_parts(struct bootflow *bflow)
 		const struct distro_rauc_slot *slot;
 
 		slot = get_slot(priv, boot_order_list[i]);
-		if (!slot)
+		if (!slot) {
+			str_free_list(boot_order_list);
 			return log_msg_ret("slot", -EINVAL);
+		}
 		if (desc) {
 			ret = fs_set_blk_dev_with_part(desc, slot->boot_part);
 			if (ret)
@@ -167,8 +169,10 @@ static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow
 		if (!env_get(boot_left)) {
 			log_debug("%s did not exist yet, setting default value\n",
 				  boot_left);
-			if (env_set_ulong(boot_left, CONFIG_BOOTMETH_RAUC_DEFAULT_TRIES))
+			if (env_set_ulong(boot_left, CONFIG_BOOTMETH_RAUC_DEFAULT_TRIES)) {
+				str_free_list(default_boot_order_list);
 				return log_msg_ret("env", -EPERM);
+			}
 		}
 	}
 	str_free_list(default_boot_order_list);
@@ -324,13 +328,17 @@ static int find_active_slot(char **slot_name, ulong *slot_tries)
 	for (i = 0; boot_order_list[i] && !slot_found; i++) {
 		sprintf(boot_left, "BOOT_%s_LEFT", boot_order_list[i]);
 		tries = env_get_ulong(boot_left, 10, ULONG_MAX);
-		if (tries == ULONG_MAX)
+		if (tries == ULONG_MAX) {
+			str_free_list(boot_order_list);
 			return log_msg_ret("env", -ENOENT);
+		}
 
 		if (tries) {
 			ret = env_set_ulong(boot_left, tries - 1);
-			if (ret)
+			if (ret) {
+				str_free_list(boot_order_list);
 				return log_msg_ret("env", ret);
+			}
 			*slot_name = strdup(boot_order_list[i]);
 			*slot_tries = tries;
 			slot_found = true;
@@ -346,8 +354,10 @@ static int find_active_slot(char **slot_name, ulong *slot_tries)
 			for (i = 0; boot_order_list[i]; i++) {
 				sprintf(boot_left, "BOOT_%s_LEFT", boot_order_list[i]);
 				ret = env_set_ulong(boot_left, CONFIG_BOOTMETH_RAUC_DEFAULT_TRIES);
-				if (ret)
+				if (ret) {
+					str_free_list(boot_order_list);
 					return log_msg_ret("env", ret);
+				}
 			}
 			str_free_list(boot_order_list);
 			ret = env_save();
-- 
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.