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

Reply via email to