The overlap check at the end of fit_import_data() sizes each referenced image from its data property and skips images without data, since such images are never copied anywhere. That assumption no longer holds for an image that shares another image's data through image-data: the reference is resolved only after the import, so the image has no data yet when the check runs and escaped it entirely, leaving its load region unvalidated even though the resolved image is loaded like any other.
Size such images from their target's data instead. References that do not resolve are left alone here; fit_resolve_image_data() rejects them right after the import. Signed-off-by: Aristo Chen <[email protected]> --- tools/fit_image.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/tools/fit_image.c b/tools/fit_image.c index 03239fbf0f7..c9310155d19 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -951,6 +951,34 @@ err: return ret; } +/** + * fit_image_effective_data() - Get the data an image will carry once resolved + * + * Returns the image's own data or, for an image that shares another + * image's data through a not yet resolved image-data reference, the + * target's data. References that do not resolve are left alone here, + * since fit_resolve_image_data() rejects them right after the import. + */ +static const char *fit_image_effective_data(const void *fdt, int images, + int img, int *sizep) +{ + const char *data, *ref; + int target; + + data = fdt_getprop(fdt, img, FIT_DATA_PROP, sizep); + if (data) + return data; + + ref = fdt_getprop(fdt, img, FIT_IMAGE_DATA_PROP, NULL); + if (!ref) + return NULL; + target = fdt_subnode_offset(fdt, images, ref); + if (target < 0) + return NULL; + + return fdt_getprop(fdt, target, FIT_DATA_PROP, sizep); +} + static int fit_import_data(struct image_tool_params *params, const char *fname) { void *fdt, *old_fdt; @@ -1100,12 +1128,16 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) * Collect the memory region the image is * loaded to. Images without a load address or * without data are never copied anywhere, so - * they cannot conflict. + * they cannot conflict. An image-data + * reference is resolved only after the + * import, but the image ends up with the + * target's data, so size its region from the + * target. */ if (fit_image_get_load(fdt, img, &img_load)) continue; - img_data = fdt_getprop(fdt, img, FIT_DATA_PROP, - &img_size); + img_data = fit_image_effective_data(fdt, + images, img, &img_size); if (!img_data || img_size <= 0) continue; -- 2.43.0
