[new uImage] Return error on image move/uncompress overwrites
authorMarian Balakowicz <m8@semihalf.com>
Thu, 31 Jan 2008 12:20:06 +0000 (13:20 +0100)
committerWolfgang Denk <wd@denx.de>
Thu, 7 Feb 2008 00:12:57 +0000 (01:12 +0100)
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
lib_ppc/ppc_linux.c

index 2d17bdd4f9514f103ba7cd1b07b762270dedfb5b..f441e0e011a4312b7c5945a3e54145c84e8e4ce3 100644 (file)
@@ -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 {
@@ -234,6 +238,11 @@ 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) {
@@ -244,6 +253,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                        memmove_wd ((void *)image_get_load (hdr),
                                   (void *)os_data, os_len, CHUNKSZ);
 
+                       load_end = load_start + os_len;
                        puts("OK\n");
                }
                break;
@@ -255,6 +265,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:
@@ -272,6 +284,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:
@@ -284,6 +298,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)
index 0a625fc071a96bc399366e9f775bc7852dd95044..391168787a97cf0c1445e1bf1d9b54f26c2f152f 100644 (file)
@@ -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);