Browse Source

common: bootm: add checks to verify if ramdisk / fdtimage overlaps OS image

These cases are typically fatal and are difficult to debug for random
users. Add checks for detecting overlapping images and abort if overlap
is detected.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tero Kristo 3 years ago
parent
commit
fbde7589ce
5 changed files with 33 additions and 7 deletions
  1. 1 1
      cmd/booti.c
  2. 1 1
      cmd/bootz.c
  3. 27 2
      common/bootm.c
  4. 2 2
      common/bootm_os.c
  5. 2 1
      include/bootm.h

+ 1 - 1
cmd/booti.c

@@ -93,7 +93,7 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc,
 	 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
 	 * have a header that provide this informaiton.
 	 */
-	if (bootm_find_images(flag, argc, argv))
+	if (bootm_find_images(flag, argc, argv, relocated_addr, image_size))
 		return 1;
 
 	return 0;

+ 1 - 1
cmd/bootz.c

@@ -54,7 +54,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
 	 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
 	 * have a header that provide this informaiton.
 	 */
-	if (bootm_find_images(flag, argc, argv))
+	if (bootm_find_images(flag, argc, argv, zi_start, zi_end - zi_start))
 		return 1;
 
 	return 0;

+ 27 - 2
common/bootm.c

@@ -228,6 +228,8 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
  * @flag: Ignored Argument
  * @argc: command argument count
  * @argv: command argument list
+ * @start: OS image start address
+ * @size: OS image size
  *
  * boot_find_images() will attempt to load an available ramdisk,
  * flattened device tree, as well as specifically marked
@@ -239,7 +241,8 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
  *     0, if all existing images were loaded correctly
  *     1, if an image is found but corrupted, or invalid
  */
-int bootm_find_images(int flag, int argc, char *const argv[])
+int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
+		      ulong size)
 {
 	int ret;
 
@@ -251,6 +254,16 @@ int bootm_find_images(int flag, int argc, char *const argv[])
 		return 1;
 	}
 
+	/* check if ramdisk overlaps OS image */
+	if (images.rd_start && (((ulong)images.rd_start >= start &&
+				 (ulong)images.rd_start <= start + size) ||
+				((ulong)images.rd_end >= start &&
+				 (ulong)images.rd_end <= start + size))) {
+		printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
+		       start, start + size);
+		return 1;
+	}
+
 #if IMAGE_ENABLE_OF_LIBFDT
 	/* find flattened device tree */
 	ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
@@ -259,6 +272,18 @@ int bootm_find_images(int flag, int argc, char *const argv[])
 		puts("Could not find a valid device tree\n");
 		return 1;
 	}
+
+	/* check if FDT overlaps OS image */
+	if (images.ft_addr &&
+	    (((ulong)images.ft_addr >= start &&
+	      (ulong)images.ft_addr <= start + size) ||
+	     ((ulong)images.ft_addr + images.ft_len >= start &&
+	      (ulong)images.ft_addr + images.ft_len <= start + size))) {
+		printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
+		       start, start + size);
+		return 1;
+	}
+
 	if (CONFIG_IS_ENABLED(CMD_FDT))
 		set_working_fdt_addr(map_to_sysmem(images.ft_addr));
 #endif
@@ -294,7 +319,7 @@ static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
 	     (images.os.type == IH_TYPE_MULTI)) &&
 	    (images.os.os == IH_OS_LINUX ||
 		 images.os.os == IH_OS_VXWORKS))
-		return bootm_find_images(flag, argc, argv);
+		return bootm_find_images(flag, argc, argv, 0, 0);
 
 	return 0;
 }

+ 2 - 2
common/bootm_os.c

@@ -495,7 +495,7 @@ static int do_bootm_tee(int flag, int argc, char *const argv[],
 		return ret;
 
 	/* Locate FDT etc */
-	ret = bootm_find_images(flag, argc, argv);
+	ret = bootm_find_images(flag, argc, argv, 0, 0);
 	if (ret)
 		return ret;
 
@@ -516,7 +516,7 @@ static int do_bootm_efi(int flag, int argc, char *const argv[],
 		return 0;
 
 	/* Locate FDT, if provided */
-	ret = bootm_find_images(flag, argc, argv);
+	ret = bootm_find_images(flag, argc, argv, 0, 0);
 	if (ret)
 		return ret;
 

+ 2 - 1
include/bootm.h

@@ -53,7 +53,8 @@ int boot_selected_os(int argc, char *const argv[], int state,
 ulong bootm_disable_interrupts(void);
 
 /* This is a special function used by booti/bootz */
-int bootm_find_images(int flag, int argc, char *const argv[]);
+int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
+		      ulong size);
 
 int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
 		    char *const argv[], int states, bootm_headers_t *images,