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. The previous patch introduces the first images for which that assumption does not hold: an image sharing another image's data has no data of its own until the reference is resolved after the import, so it escaped the check and its load region went unvalidated even though the resolved image is loaded like any other. This completes the validation for the new property rather than fixing a pre-existing problem, since a configuration could not reference a data-less image in a meaningful way before.
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]> Reviewed-by: Simon Glass <[email protected]> --- Changes in v2: v2: commit message states that this completes the validation for the new property; complete the kernel-doc of fit_image_effective_data(); comment-only change, Reviewed-by kept tools/fit_image.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/tools/fit_image.c b/tools/fit_image.c index 64e607ea55f..b4a97656ea4 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -951,6 +951,41 @@ 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. + * + * @fdt: FIT blob containing the image nodes + * @images: offset of the /images node + * @img: offset of the image node to look at + * @sizep: returns the length of the data on success + * Return: pointer to the data, or NULL if neither the image nor its + * image-data target carries any + */ +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; @@ -1118,12 +1153,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
