Hi Raymond,

On Mon, 2026-05-04 at 17:25 -0400, Raymond Mao wrote:
> From: Raymond Mao <[email protected]>
> 
> 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 <[email protected]>
> ---
> 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;

here you return an error from the libfdt error space, but...

> +
> +     *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;

... the caller returns the codes from the standard errno.h

>  
> +     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);

doesn't the fdt_pack() already guarantee a valid header? Can the packed size
exceed the blob_size if packing only shrinks?

> +     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)

-- 
Alexander Sverdlin
Siemens AG
www.siemens.com

Reply via email to