diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2014-12-10 18:20:53 +0800 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2015-01-05 16:40:19 -0500 |
commit | 22cfddc2a0343cdbef7f1263830c2dacaa75f22e (patch) | |
tree | ea6070f8d43b7fe181e5046005da58d86379cc5e /common/image.c | |
parent | eb54d2c70ce3b14e0c9ae141e216d5ad0b22d0dd (diff) |
memmove_wd: copy chunk down from big address if parameter to is larger than from
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>
Diffstat (limited to 'common/image.c')
-rw-r--r-- | common/image.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/common/image.c b/common/image.c index b75a5ce29a6..e691a517894 100644 --- a/common/image.c +++ b/common/image.c @@ -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) */ |