[PATCH v2] lib: fdtdec: validate bloblist FDT before consuming libfdt size

Raymond Mao raymondmaoca at gmail.com
Mon May 4 23:25:23 CEST 2026


From: Raymond Mao <raymond.mao at riscstar.com>

Coverity Scan defects are observed in fdtdec_apply_bloblist_dtos(),
since the live FDT taken from the bloblist is passed to libfdt helpers
which consume header size/offset fields:
- fdt_open_into()
- fdt_pack()
- bloblist_resize(..., fdt_totalsize(...))

Add a small helper to validate the FDT header and confirm that the
advertised totalsize fits within the currently allocated bloblist
record. Use the sanitized size before calling fdt_open_into(), again
after overlays are applied before calling fdt_pack(), and once more
after packing before shrinking the bloblist record.

This keeps the existing flow unchanged while making the size consumers
operate on validated FDT metadata.

Fixes: b70cbbfbf94f ("fdtdec: apply DT overlays from bloblist")
Addresses-Coverity-ID: CID 645837: (TAINTED_SCALAR)
Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
changes in v2:
- Rebased on master.

 lib/fdtdec.c | 43 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 2d66860f6ed..601f418db6e 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1744,9 +1744,31 @@ static int fdtdec_apply_dto_blob(void **blob, __maybe_unused int size)
 	return fdt_overlay_apply_verbose((void *)gd->fdt_blob, *blob);
 }
 
+static int fdtdec_get_valid_fdt_size(const void *fdt, int alloc_size,
+				     int *fdt_sizep)
+{
+	int ret, fdt_size;
+
+	/*
+	 * Validate the header before libfdt trusts any header offsets/sizes.
+	 * Also make sure the advertised totalsize fits in the bloblist record.
+	 */
+	ret = fdt_check_header(fdt);
+	if (ret)
+		return ret;
+
+	fdt_size = fdt_totalsize(fdt);
+	if (fdt_size > alloc_size)
+		return -FDT_ERR_TRUNCATED;
+
+	*fdt_sizep = fdt_size;
+
+	return 0;
+}
+
 static int fdtdec_apply_bloblist_dtos(void)
 {
-	int ret;
+	int ret, live_fdt_size;
 	struct fdt_header *live_fdt;
 	int blob_size;
 	size_t padded_size, max_size;
@@ -1760,8 +1782,12 @@ static int fdtdec_apply_bloblist_dtos(void)
 	if (live_fdt != gd->fdt_blob)
 		return -ENOENT;
 
+	ret = fdtdec_get_valid_fdt_size(live_fdt, blob_size, &live_fdt_size);
+	if (ret)
+		return ret;
+
 	/* Calculate the allowed padded size */
-	padded_size = fdt_totalsize(live_fdt) + CONFIG_SYS_FDT_PAD;
+	padded_size = live_fdt_size + CONFIG_SYS_FDT_PAD;
 	max_size = bloblist_get_total_size() - bloblist_get_size() + blob_size;
 	if (padded_size > max_size)
 		padded_size = max_size;
@@ -1772,6 +1798,7 @@ static int fdtdec_apply_bloblist_dtos(void)
 		if (ret)
 			return ret;
 
+		blob_size = padded_size;
 		ret = fdt_open_into(live_fdt, live_fdt, padded_size);
 		if (ret)
 			return ret;
@@ -1781,12 +1808,20 @@ static int fdtdec_apply_bloblist_dtos(void)
 	if (ret)
 		return ret;
 
-	/* Shrink the blob to the actual FDT size */
+	ret = fdtdec_get_valid_fdt_size(live_fdt, blob_size, &live_fdt_size);
+	if (ret)
+		return ret;
+
 	ret = fdt_pack(live_fdt);
 	if (ret)
 		return ret;
 
-	return bloblist_resize(BLOBLISTT_CONTROL_FDT, fdt_totalsize(live_fdt));
+	ret = fdtdec_get_valid_fdt_size(live_fdt, blob_size, &live_fdt_size);
+	if (ret)
+		return ret;
+
+	/* Shrink the blob to the actual FDT size */
+	return bloblist_resize(BLOBLISTT_CONTROL_FDT, live_fdt_size);
 }
 
 int fdtdec_setup(void)
-- 
2.25.1



More information about the U-Boot mailing list