[Concept,09/14] rauc: Implement free_bootflow to fix memory leak

Message ID 20260322235719.1729267-10-sjg@u-boot.org
State New
Headers
Series bootstd: Infrastructure for multi-entry bootflow support |

Commit Message

Simon Glass March 22, 2026, 11:57 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

The RAUC bootmeth allocates a slots array with internal name strings
inside distro_rauc_priv. A plain free() on the priv struct leaks all of
these. The driver already has distro_rauc_priv_free() for proper cleanup
but it is not called from bootflow_free().

Implement free_bootflow() to use the existing cleanup function. Since
bootmeth_free_bootflow() now handles freeing the priv struct itself,
remove that from distro_rauc_priv_free() and add explicit free() + NULL
at the two call sites in read_bootflow and boot which do their own
cleanup.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/bootmeth_rauc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
  

Patch

diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
index a81178db574..53d8dd7836f 100644
--- a/boot/bootmeth_rauc.c
+++ b/boot/bootmeth_rauc.c
@@ -63,7 +63,6 @@  static void distro_rauc_priv_free(struct distro_rauc_priv *priv)
 		free(priv->slots[i]);
 	}
 	free(priv->slots);
-	free(priv);
 }
 
 static struct distro_rauc_slot *get_slot(struct distro_rauc_priv *priv,
@@ -202,6 +201,8 @@  static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow
 	ret = distro_rauc_scan_parts(bflow);
 	if (ret < 0) {
 		distro_rauc_priv_free(priv);
+		free(priv);
+		bflow->bootmeth_priv = NULL;
 		free(boot_order_copy);
 		return ret;
 	}
@@ -412,6 +413,8 @@  static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow)
 		return log_msg_ret("boot", ret);
 
 	distro_rauc_priv_free(priv);
+	free(priv);
+	bflow->bootmeth_priv = NULL;
 
 	return 0;
 }
@@ -426,10 +429,18 @@  static int distro_rauc_bootmeth_bind(struct udevice *dev)
 	return 0;
 }
 
+static void distro_rauc_free_bootflow(struct udevice *dev,
+				      struct bootflow *bflow)
+{
+	if (bflow->bootmeth_priv)
+		distro_rauc_priv_free(bflow->bootmeth_priv);
+}
+
 static struct bootmeth_ops distro_rauc_bootmeth_ops = {
 	.check		= distro_rauc_check,
 	.read_bootflow	= distro_rauc_read_bootflow,
 	.read_file	= distro_rauc_read_file,
+	.free_bootflow	= distro_rauc_free_bootflow,
 	.boot		= distro_rauc_boot,
 };