mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
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: b70cbbfbf9 ("fdtdec: apply DT overlays from bloblist")
Addresses-Coverity-ID: CID 645837: (TAINTED_SCALAR)
Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
Reviewed-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
This commit is contained in:
38
lib/fdtdec.c
38
lib/fdtdec.c
@@ -1729,19 +1729,38 @@ static int fdtdec_match_dto_compatible(const void *base, const void *dto)
|
|||||||
return 0;
|
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)
|
static int fdtdec_apply_dto_blob(void **blob, __maybe_unused int size)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = fdt_check_header(*blob);
|
ret = fdt_check_header(*blob);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return fdtdec_ret_to_errno(ret);
|
||||||
|
|
||||||
ret = fdtdec_match_dto_compatible(gd->fdt_blob, *blob);
|
ret = fdtdec_match_dto_compatible(gd->fdt_blob, *blob);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
static int fdtdec_apply_bloblist_dtos(void)
|
||||||
@@ -1760,6 +1779,10 @@ static int fdtdec_apply_bloblist_dtos(void)
|
|||||||
if (live_fdt != gd->fdt_blob)
|
if (live_fdt != gd->fdt_blob)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
ret = fdt_check_full(live_fdt, blob_size);
|
||||||
|
if (ret)
|
||||||
|
return fdtdec_ret_to_errno(ret);
|
||||||
|
|
||||||
/* Calculate the allowed padded size */
|
/* Calculate the allowed padded size */
|
||||||
padded_size = fdt_totalsize(live_fdt) + CONFIG_SYS_FDT_PAD;
|
padded_size = fdt_totalsize(live_fdt) + CONFIG_SYS_FDT_PAD;
|
||||||
max_size = bloblist_get_total_size() - bloblist_get_size() + blob_size;
|
max_size = bloblist_get_total_size() - bloblist_get_size() + blob_size;
|
||||||
@@ -1772,20 +1795,25 @@ static int fdtdec_apply_bloblist_dtos(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
blob_size = padded_size;
|
||||||
ret = fdt_open_into(live_fdt, live_fdt, padded_size);
|
ret = fdt_open_into(live_fdt, live_fdt, padded_size);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return fdtdec_ret_to_errno(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bloblist_apply_blobs(BLOBLISTT_FDT_OVERLAY, fdtdec_apply_dto_blob);
|
ret = bloblist_apply_blobs(BLOBLISTT_FDT_OVERLAY, fdtdec_apply_dto_blob);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = fdt_pack(live_fdt);
|
||||||
if (ret)
|
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));
|
return bloblist_resize(BLOBLISTT_CONTROL_FDT, fdt_totalsize(live_fdt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user