summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymond Mao <[email protected]>2026-05-06 10:55:33 -0400
committerTom Rini <[email protected]>2026-05-08 15:49:27 -0600
commit0a31d3128ee6928d7eac5b830ef79d0a27e3f0a7 (patch)
tree4a9bde626515521f5ec66fce3a98c3ec7d71fdaa
parent26b17dbdb0f19efa67365b30d939d3572871e8ca (diff)
lib: fdtdec: validate bloblist FDT before consuming libfdt size
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() Validate the bloblist FDT with fdt_check_full() before calling fdt_open_into() and again after applying overlays before calling fdt_pack(). This makes the libfdt consumers operate on a checked FDT blob while keeping the existing flow unchanged. Also normalize libfdt return codes from this path to errno values, including the overlay callback path through bloblist_apply_blobs(). Fixes: b70cbbfbf94f ("fdtdec: apply DT overlays from bloblist") Addresses-Coverity-ID: CID 645837: (TAINTED_SCALAR) Signed-off-by: Raymond Mao <[email protected]> Reviewed-by: Alexander Sverdlin <[email protected]>
-rw-r--r--lib/fdtdec.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 2d66860f6ed..c67b6e8c133 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1729,19 +1729,38 @@ static int fdtdec_match_dto_compatible(const void *base, const void *dto)
return 0;
}
+static inline int fdtdec_ret_to_errno(int ret)
+{
+ switch (ret) {
+ case -FDT_ERR_NOTFOUND:
+ return -ENOENT;
+ case -FDT_ERR_EXISTS:
+ return -EEXIST;
+ case -FDT_ERR_NOSPACE:
+ case -FDT_ERR_NOPHANDLES:
+ return -ENOSPC;
+ default:
+ return -EINVAL;
+ }
+}
+
static int fdtdec_apply_dto_blob(void **blob, __maybe_unused int size)
{
int ret;
ret = fdt_check_header(*blob);
if (ret)
- return ret;
+ return fdtdec_ret_to_errno(ret);
ret = fdtdec_match_dto_compatible(gd->fdt_blob, *blob);
if (ret)
return ret;
- return fdt_overlay_apply_verbose((void *)gd->fdt_blob, *blob);
+ ret = fdt_overlay_apply_verbose((void *)gd->fdt_blob, *blob);
+ if (ret)
+ return fdtdec_ret_to_errno(ret);
+
+ return 0;
}
static int fdtdec_apply_bloblist_dtos(void)
@@ -1760,6 +1779,10 @@ static int fdtdec_apply_bloblist_dtos(void)
if (live_fdt != gd->fdt_blob)
return -ENOENT;
+ ret = fdt_check_full(live_fdt, blob_size);
+ if (ret)
+ return fdtdec_ret_to_errno(ret);
+
/* Calculate the allowed padded size */
padded_size = fdt_totalsize(live_fdt) + CONFIG_SYS_FDT_PAD;
max_size = bloblist_get_total_size() - bloblist_get_size() + blob_size;
@@ -1772,20 +1795,25 @@ 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;
+ return fdtdec_ret_to_errno(ret);
}
ret = bloblist_apply_blobs(BLOBLISTT_FDT_OVERLAY, fdtdec_apply_dto_blob);
if (ret)
return ret;
- /* Shrink the blob to the actual FDT size */
+ ret = fdt_check_full(live_fdt, blob_size);
+ if (ret)
+ return fdtdec_ret_to_errno(ret);
+
ret = fdt_pack(live_fdt);
if (ret)
- return ret;
+ return fdtdec_ret_to_errno(ret);
+ /* Shrink the blob to the actual FDT size */
return bloblist_resize(BLOBLISTT_CONTROL_FDT, fdt_totalsize(live_fdt));
}