
Check for overwrites during image move/uncompress, return with error when the original image gets corrupted. Report clear message to the user and prevent further troubles when pointer to the corrupted images is passed to do_bootm_linux routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 23 ++++++++++++++++++++++- lib_ppc/ppc_linux.c | 14 ++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 6a9d5ad..b5f7526 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -133,6 +133,10 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong img_addr; ulong os_data, os_len;
+ ulong image_start, image_end; + ulong load_start, load_end; + + if (argc < 2) img_addr = load_addr; else @@ -232,16 +236,21 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif
+ image_start = (ulong)hdr; + image_end = image_get_image_end(hdr); + load_start = image_get_load(hdr); + load_end = 0; + switch (image_get_comp(hdr)) { case IH_COMP_NONE: if (image_get_load(hdr) == img_addr) { printf(" XIP %s ... ", name); } else { printf(" Loading %s ... ", name); - memmove_wd((void *)image_get_load(hdr), (void *)os_data, os_len, CHUNKSZ);
+ load_end = load_start + os_len; puts("OK\n"); } break; @@ -253,6 +262,8 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress(-6); do_reset(cmdtp, flag, argc, argv); } + + load_end = load_start + os_len; break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: @@ -270,6 +281,8 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress(-6); do_reset(cmdtp, flag, argc, argv); } + + load_end = load_start + unc_len; break; #endif /* CONFIG_BZIP2 */ default: @@ -282,6 +295,14 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) puts("OK\n"); show_boot_progress(7);
+ if ((load_start < image_end) && (load_end > image_start)) { + debug("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end); + debug("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end); + + puts("ERROR: image overwritten - must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + switch (image_get_type(hdr)) { case IH_TYPE_STANDALONE: if (iflag) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 56cdcc8..e0b55db 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -23,6 +23,8 @@ * MA 02111-1307 USA */
+#define DEBUG + #include <common.h> #include <watchdog.h> #include <command.h> @@ -259,11 +261,19 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_data = (ulong)of_flat_tree; #endif } else if (image_check_magic(fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + printf("## Flat Device Tree at %08lX\n", fdt_hdr); print_image_hdr(fdt_hdr);
- if ((image_get_load(fdt_hdr) < image_get_image_end(fdt_hdr)) && - ((image_get_load(fdt_hdr) + image_get_data_size(fdt_hdr)) > (unsigned long)fdt_hdr)) { + image_start = (ulong)fdt_hdr; + image_end = image_get_image_end(fdt_hdr); + + load_start = image_get_load(fdt_hdr); + load_end = load_start + image_get_data_size(fdt_hdr); + + if ((load_start < image_end) && (load_end > image_start)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv);