distro_rauc_boot() deep-frees the private data once the boot script
has been loaded and run, but leaves bflow->bootmeth_priv pointing at
the freed memory. The bootflow being booted is the one stored in the
bootstd list, so if the boot script returns (bootflow_boot() treats
this as an error), the stale pointer is kept and bootflow_free()
frees it a second time when the bootflow is removed, for example by
the next 'bootflow scan'.
Clear bflow->bootmeth_priv after freeing, as the scan error path
does. Also check priv before using it, like the other users of
bootmeth_priv in this file: after a failed boot attempt, a retry now
finds bootmeth_priv NULL and must not hand it to get_slot(), which
would dereference it.
Fixes: 498e423457a0 ("bootstd: rauc: Free private data when booting")
Signed-off-by: Aristo Chen <[email protected]>
---
boot/bootmeth_rauc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
index 2df141f7424..844df7576bb 100644
--- a/boot/bootmeth_rauc.c
+++ b/boot/bootmeth_rauc.c
@@ -398,6 +398,8 @@ static int distro_rauc_boot(struct udevice *dev, struct
bootflow *bflow)
if (desc->uclass_id != UCLASS_MMC)
return log_msg_ret("blk", -EINVAL);
priv = bflow->bootmeth_priv;
+ if (!priv || !priv->slots)
+ return log_msg_ret("priv", -EINVAL);
/* Device info variables */
ret = env_set("devtype", blk_get_devtype(bflow->blk));
@@ -464,6 +466,7 @@ static int distro_rauc_boot(struct udevice *dev, struct
bootflow *bflow)
return log_msg_ret("boot", ret);
distro_rauc_priv_free(priv);
+ bflow->bootmeth_priv = NULL;
return 0;
}
--
2.43.0