[PATCH v1 4/5] tools: mkimage: detect overlapping load regions in FIT configurations

Aristo Chen jj251510319013 at gmail.com
Tue Jul 29 14:48:55 CEST 2025


This patch adds a validation step in mkimage to detect memory region
overlaps between images specified in the same configuration of a
FIT image. If any overlaps are found, the tool prints an error and
aborts the build.

This helps prevent runtime memory corruption caused by conflicting
load addresses between images.

Signed-off-by: Aristo Chen <aristo.chen at canonical.com>
---
 tools/fit_image.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/mkimage.c   |  3 +-
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/tools/fit_image.c b/tools/fit_image.c
index 331be5ae71d..d0061adf051 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -22,6 +22,22 @@
 #include <version.h>
 #include <u-boot/crc.h>
 
+#define MAX_IMAGES_PER_CONFIG 16
+
+struct fit_region {
+	ulong load;
+	ulong size;
+	const char *name;
+};
+
+static int regions_overlap(struct fit_region *a, struct fit_region *b)
+{
+	ulong a_end = a->load + a->size;
+	ulong b_end = b->load + b->size;
+
+	return !(a_end <= b->load || b_end <= a->load);
+}
+
 static struct legacy_img_hdr header;
 
 static int fit_estimate_hash_sig_size(struct image_tool_params *params, const char *fname)
@@ -775,6 +791,8 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
 	}
 
 	fdt_for_each_subnode(node, fdt, confs) {
+		struct fit_region regions[MAX_IMAGES_PER_CONFIG];
+		int img_count = 0;
 		const char *conf_name = fdt_get_name(fdt, node, NULL);
 
 		for (int i = 0; i < ARRAY_SIZE(props); i++) {
@@ -798,6 +816,66 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
 					ret = FDT_ERR_NOTFOUND;
 					goto err_munmap;
 				}
+
+				ulong img_load = 0;
+				int img_size = 0;
+
+				if (fit_image_get_load(fdt, img, &img_load)) {
+					fprintf(stderr,
+						"Warning: not able to get `load` of node '%s'\n",
+						img_name);
+					// Skip checking the components that do not have a
+					// definition for `load`
+					continue;
+				}
+				const char *img_data = fdt_getprop(fdt, img,
+								   FIT_DATA_PROP,
+								   &img_size);
+
+				if (!img_data || img_size == 0)
+					continue;
+
+				// Check if we've already added this image to avoid duplicates
+				bool already_added = false;
+
+				for (int k = 0; k < img_count; k++) {
+					if (strcmp(regions[k].name, img_name) == 0) {
+						already_added = true;
+						break;
+					}
+				}
+				if (already_added)
+					continue;
+
+				if (img_count >= MAX_IMAGES_PER_CONFIG) {
+					fprintf(stderr, "Too many images in config %s\n",
+						fdt_get_name(fdt, node, NULL));
+					break;
+				}
+
+				regions[img_count].load = img_load;
+				regions[img_count].size = img_size;
+				regions[img_count].name = img_name;
+				img_count++;
+			}
+		}
+
+		// Check for overlap within this config only
+		for (int i = 0; i < img_count; i++) {
+			for (int j = i + 1; j < img_count; j++) {
+				if (regions_overlap(&regions[i], &regions[j])) {
+					fprintf(stderr,
+						"[Config: %s] Error: Overlap detected:\n"
+						"  - %s: [0x%lx - 0x%lx]\n"
+						"  - %s: [0x%lx - 0x%lx]\n",
+						fdt_get_name(fdt, node, NULL),
+						regions[i].name, regions[i].load,
+						regions[i].load + regions[i].size,
+						regions[j].name, regions[j].load,
+						regions[j].load + regions[j].size);
+					ret = FDT_ERR_BADSTRUCTURE;
+					goto err_munmap;
+				}
 			}
 		}
 	}
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 361711c53b2..3f28918f5cf 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -520,7 +520,8 @@ int main(int argc, char **argv)
 			retval = tparams->fflag_handle(&params);
 
 		if (retval != EXIT_SUCCESS) {
-			if (retval == FDT_ERR_NOTFOUND) {
+			if (retval == FDT_ERR_NOTFOUND ||
+			    retval == FDT_ERR_BADSTRUCTURE) {
 				// Already printed error, exit cleanly
 				exit(EXIT_FAILURE);
 			}
-- 
2.43.0



More information about the U-Boot mailing list