[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