load_simple_fit() is expected to fill in the image_info structure it
receives upon successful return, but the path which skips a zero-sized
image returns success without touching it. The result is that
spl_fit_record_loadable() then publishes whatever else the descriptor
happened to hold in /fit-images under the skipped image's name: the size
and entry point of the previous loadable, or - for the first one, since
image_info is declared without an initialiser - uninitialised stack.

This is reachable whenever a FIT carries an image node with no content,
which binman produces for an optional blob that was not supplied, such as
an OP-TEE which the build did not provide.

Ensure that the image_info structure is filled in with a size and entry
point before returning, same way as other successful paths do (but
skipping the actual load).

Fixes: 6d99f866952b ("spl: fit: Skip attempting to load 0 length image")
Signed-off-by: Alexey Charkov <[email protected]>
---
 common/spl/spl_fit.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 18bff7b8d4af..0dbc0ba81535 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -193,6 +193,33 @@ static int get_aligned_image_size(struct spl_load_info 
*info, int data_size,
        return ALIGN(data_size, spl_get_bl_len(info));
 }
 
+/**
+ * fit_fill_image_info(): describe a loaded image to the caller
+ * @fit:       points to the FIT image
+ * @node:      offset of the DT node describing the image
+ * @image_info:        filled in with where the image ended up and how big it 
is;
+ *             ignored if NULL
+ * @load_addr: address the image was loaded to
+ * @size:      number of bytes loaded, which may be zero
+ */
+static void fit_fill_image_info(const void *fit, int node,
+                               struct spl_image_info *image_info,
+                               ulong load_addr, ulong size)
+{
+       ulong entry_point;
+
+       if (!image_info)
+               return;
+
+       image_info->load_addr = load_addr;
+       image_info->size = size;
+
+       if (!fit_image_get_entry(fit, node, &entry_point))
+               image_info->entry_point = entry_point;
+       else
+               image_info->entry_point = FDT_ERROR;
+}
+
 /**
  * load_simple_fit(): load the image described in a certain FIT node
  * @info:      points to information about the device to load data from
@@ -291,6 +318,7 @@ static int load_simple_fit(struct spl_load_info *info, 
ulong fit_offset,
                if (!len) {
                        log_warning("%s: Skip load '%s': image size is 0!\n",
                                    __func__, fit_get_name(fit, node, NULL));
+                       fit_fill_image_info(fit, node, image_info, load_addr, 
0);
                        return 0;
                }
 
@@ -385,17 +413,7 @@ static int load_simple_fit(struct spl_load_info *info, 
ulong fit_offset,
                memmove(load_ptr, src, length);
        }
 
-       if (image_info) {
-               ulong entry_point;
-
-               image_info->load_addr = load_addr;
-               image_info->size = length;
-
-               if (!fit_image_get_entry(fit, node, &entry_point))
-                       image_info->entry_point = entry_point;
-               else
-                       image_info->entry_point = FDT_ERROR;
-       }
+       fit_fill_image_info(fit, node, image_info, load_addr, length);
        log_debug("- done loading\n");
 
        upl_add_image(fit, node, load_addr, length);

---
base-commit: 44f0dcf476140c1077ee3dbe16a80fdb6f8265c4
change-id: 20260730-b4-spl-fit-clear-loadable-33885aaab2b0

Best regards,
--  
Alexey Charkov <[email protected]>

Reply via email to