[PATCH v1 4/5] tools: mkimage: detect overlapping load regions in FIT configurations
Aristo Chen
jj251510319013 at gmail.com
Sat Aug 9 04:08:25 CEST 2025
Yannic Moog <Y.Moog at phytec.de> 於 2025年7月31日 週四 下午7:43寫道:
>
> Am Dienstag, dem 29.07.2025 um 12:48 +0000 schrieb Aristo Chen:
> > This patch adds a validation step in mkimage to detect memory region
> > overlaps between images specified in the same configuration of a
> > FIT image. If any overlaps are found, the tool prints an error and
> > aborts the build.
> >
> > This helps prevent runtime memory corruption caused by conflicting
> > load addresses between images.
> >
> > Signed-off-by: Aristo Chen <aristo.chen at canonical.com>
> > ---
> > tools/fit_image.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++
> > tools/mkimage.c | 3 +-
> > 2 files changed, 80 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/fit_image.c b/tools/fit_image.c
> > index 331be5ae71d..d0061adf051 100644
> > --- a/tools/fit_image.c
> > +++ b/tools/fit_image.c
> > @@ -22,6 +22,22 @@
> > #include <version.h>
> > #include <u-boot/crc.h>
> >
> > +#define MAX_IMAGES_PER_CONFIG 16
>
> How did you get this number?
>
> If this is arbitrary, add to the error message below that if someone needs more
> images, they can increase the size.
Yes, it is an arbitrary number, I am planning to dynamically allocate
the memory to solve this concern. Otherwise,
we may need to add a new variable to allow the user to modify the
value of the variable?
>
> > +
> > +struct fit_region {
> > + ulong load;
> > + ulong size;
> > + const char *name;
> > +};
> > +
> > +static int regions_overlap(struct fit_region *a, struct fit_region *b)
>
> Nit: can you constify these?
>
> > +{
> > + ulong a_end = a->load + a->size;
> > + ulong b_end = b->load + b->size;
> > +
> > + return !(a_end <= b->load || b_end <= a->load);
> > +}
> > +
> > static struct legacy_img_hdr header;
> >
> > static int fit_estimate_hash_sig_size(struct image_tool_params *params, const
> > char *fname)
> > @@ -775,6 +791,8 @@ static int fit_import_data(struct image_tool_params
> > *params, const char *fname)
> > }
> >
> > fdt_for_each_subnode(node, fdt, confs) {
> > + struct fit_region regions[MAX_IMAGES_PER_CONFIG];
>
> init to {0}?
>
> > + int img_count = 0;
>
> Nit: use unsigned
>
> > const char *conf_name = fdt_get_name(fdt, node, NULL);
> >
> > for (int i = 0; i < ARRAY_SIZE(props); i++) {
> > @@ -798,6 +816,66 @@ static int fit_import_data(struct image_tool_params
> > *params, const char *fname)
> > ret = FDT_ERR_NOTFOUND;
> > goto err_munmap;
> > }
> > +
> > + ulong img_load = 0;
> > + int img_size = 0;
> > +
> > + if (fit_image_get_load(fdt, img, &img_load))
> > {
> > + fprintf(stderr,
> > + "Warning: not able to get
> > `load` of node '%s'\n",
> > + img_name);
> > + // Skip checking the components that
> > do not have a
> > + // definition for `load`
> > + continue;
> > + }
> > + const char *img_data = fdt_getprop(fdt, img,
> > +
> > FIT_DATA_PROP,
> > +
> > &img_size);
> > +
> > + if (!img_data || img_size == 0)
>
> be consistent, use !img_size
>
> > + continue;
> > +
> > + // Check if we've already added this image to
> > avoid duplicates
> > + bool already_added = false;
> > +
> > + for (int k = 0; k < img_count; k++) {
> > + if (strcmp(regions[k].name, img_name)
> > == 0) {
>
> same here, !strcmp should do, right?
>
> > + already_added = true;
>
> You can simplify and do continue; here?
> Avoids the already_added variable.
>
> > + break;
> > + }
> > + }
> > + if (already_added)
> > + continue;
> > +
> > + if (img_count >= MAX_IMAGES_PER_CONFIG) {
> > + fprintf(stderr, "Too many images in
> > config %s\n",
> > + fdt_get_name(fdt, node,
> > NULL));
> > + break;
> > + }
> > +
> > + regions[img_count].load = img_load;
> > + regions[img_count].size = img_size;
> > + regions[img_count].name = img_name;
> > + img_count++;
> > + }
> > + }
> > +
> > + // Check for overlap within this config only
> > + for (int i = 0; i < img_count; i++) {
> > + for (int j = i + 1; j < img_count; j++) {
>
> Nit: unsigned here as well
>
> Yannic
>
> > + if (regions_overlap(®ions[i],
> > ®ions[j])) {
> > + fprintf(stderr,
> > + "[Config: %s] Error: Overlap
> > detected:\n"
> > + " - %s: [0x%lx - 0x%lx]\n"
> > + " - %s: [0x%lx - 0x%lx]\n",
> > + fdt_get_name(fdt, node,
> > NULL),
> > + regions[i].name,
> > regions[i].load,
> > + regions[i].load +
> > regions[i].size,
> > + regions[j].name,
> > regions[j].load,
> > + regions[j].load +
> > regions[j].size);
> > + ret = FDT_ERR_BADSTRUCTURE;
> > + goto err_munmap;
> > + }
> > }
> > }
> > }
> > diff --git a/tools/mkimage.c b/tools/mkimage.c
> > index 361711c53b2..3f28918f5cf 100644
> > --- a/tools/mkimage.c
> > +++ b/tools/mkimage.c
> > @@ -520,7 +520,8 @@ int main(int argc, char **argv)
> > retval = tparams->fflag_handle(¶ms);
> >
> > if (retval != EXIT_SUCCESS) {
> > - if (retval == FDT_ERR_NOTFOUND) {
> > + if (retval == FDT_ERR_NOTFOUND ||
> > + retval == FDT_ERR_BADSTRUCTURE) {
> > // Already printed error, exit cleanly
> > exit(EXIT_FAILURE);
> > }
More information about the U-Boot
mailing list