[U-Boot-Users] [PATCH 13/13] [new uImage] Return error on image move/uncompress overwrites

Marian Balakowicz
2008-01-11T14:31:00Z

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);