spl: fit: Don't overwrite previous loadable if "load" is missing
authorAlexandru Gagniuc <mr.nuke.me@gmail.com>
Mon, 29 Mar 2021 17:05:10 +0000 (12:05 -0500)
committerTom Rini <trini@konsulko.com>
Wed, 14 Apr 2021 19:23:01 +0000 (15:23 -0400)
spl_load_fit_image() will try to load an image at the address given
in the "load" property. Absent such property, it uses

image_info->load_addr

Correct use of this is demonstrated in spl_fit_append_fdt(), which
resets the 'load_addr' before each spl_load_fit_image() call.

On the other hand loading "loadables" loop in spl_load_simple_fit()
completely ignores this. It re-uses the same structure, but doesn't
reset load_addr. If loadable [i] does not have a "load" property, its
load address defaults to load_addr, which still contains the address
of loadable [i - 1].

A simple solution is to treat NULL as an invalid load address. The
caller can set load_addr = 0 to request an abort if the "load"
property is absent.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
common/spl/spl_fit.c

index 49508fc..b7755cc 100644 (file)
@@ -224,7 +224,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
  * @image_info:        will be filled with information about the loaded image
  *             If the FIT node does not contain a "load" (address) property,
  *             the image gets loaded to the address pointed to by the
- *             load_addr member in this struct.
+ *             load_addr member in this struct, if load_addr is not 0
  *
  * Return:     0 on success or a negative error number.
  */
@@ -259,8 +259,14 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
                debug("%s ", genimg_get_comp_name(image_comp));
        }
 
-       if (fit_image_get_load(fit, node, &load_addr))
+       if (fit_image_get_load(fit, node, &load_addr)) {
+               if (!image_info->load_addr) {
+                       printf("Can't load %s: No load address and no buffer\n",
+                              fit_get_name(fit, node, NULL));
+                       return -ENOBUFS;
+               }
                load_addr = image_info->load_addr;
+       }
 
        if (!fit_image_get_data_position(fit, node, &offset)) {
                external_data = true;
@@ -700,6 +706,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
                if (firmware_node == node)
                        continue;
 
+               image_info.load_addr = 0;
                ret = spl_load_fit_image(info, sector, &ctx, node, &image_info);
                if (ret < 0) {
                        printf("%s: can't load image loadables index %d (ret = %d)\n",