memmove_wd: copy chunk down from big address if parameter to is larger than from
authorSonic Zhang <sonic.zhang@analog.com>
Wed, 10 Dec 2014 10:20:53 +0000 (18:20 +0800)
committerTom Rini <trini@ti.com>
Mon, 5 Jan 2015 21:40:19 +0000 (16:40 -0500)
When watchdog is enabled, memmove_wd() always copy chunk up from small address.
This damanges overlapped memory data if destination address is smaller than
source address.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Acked-by: Simon Glass <sjg@chromium.org>
common/image.c

index b75a5ce29a669b398c5c652282753a9ee28471ff..e691a517894c32d15f5c321711c4f4ddd919f3bd 100644 (file)
@@ -485,12 +485,22 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
                return;
 
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       if (to > from) {
+               from += len;
+               to += len;
+       }
        while (len > 0) {
                size_t tail = (len > chunksz) ? chunksz : len;
                WATCHDOG_RESET();
+               if (to > from) {
+                       to -= tail;
+                       from -= tail;
+               }
                memmove(to, from, tail);
-               to += tail;
-               from += tail;
+               if (to < from) {
+                       to += tail;
+                       from += tail;
+               }
                len -= tail;
        }
 #else  /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */