From 7837f508a5cca2c82ec46f076d115853a4eaac38 Mon Sep 17 00:00:00 2001 From: Parshintsev Anatoly Date: Fri, 8 Nov 2024 07:12:46 +0300 Subject: [PATCH] target: fix wrap-around detection for read_memory/write_memory while at it change the order of checks for requested region sizes to get rid of potential overflow during multiplication. Change-Id: I97dac68e7024591cfd7abb70c8c62dff791298fe Signed-off-by: Parshintsev Anatoly Reviewed-on: https://review.openocd.org/c/openocd/+/8572 Tested-by: jenkins Reviewed-by: zapb Reviewed-by: Antonio Borneo --- src/target/target.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 9c5a33d3d..0e41f0d10 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -4447,15 +4447,17 @@ COMMAND_HANDLER(handle_target_read_memory) return ERROR_COMMAND_ARGUMENT_INVALID; } - const unsigned int width = width_bits / 8; - - if ((addr + (count * width)) < addr) { - command_print(CMD, "read_memory: addr + count wraps to zero"); + if (count > 65536) { + command_print(CMD, "read_memory: too large read request, exceeds 64K elements"); return ERROR_COMMAND_ARGUMENT_INVALID; } - if (count > 65536) { - command_print(CMD, "read_memory: too large read request, exceeds 64K elements"); + const unsigned int width = width_bits / 8; + /* -1 is needed to handle cases when (addr + count * width) results in zero + * due to overflow. + */ + if ((addr + count * width - 1) < addr) { + command_print(CMD, "read_memory: memory region wraps over address zero"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -4584,15 +4586,19 @@ static int target_jim_write_memory(Jim_Interp *interp, int argc, return JIM_ERR; } - const unsigned int width = width_bits / 8; - - if ((addr + (count * width)) < addr) { - Jim_SetResultString(interp, "write_memory: addr + len wraps to zero", -1); + if (count > 65536) { + Jim_SetResultString(interp, + "write_memory: too large memory write request, exceeds 64K elements", -1); return JIM_ERR; } - if (count > 65536) { - Jim_SetResultString(interp, "write_memory: too large memory write request, exceeds 64K elements", -1); + const unsigned int width = width_bits / 8; + /* -1 is needed to handle cases when (addr + count * width) results in zero + * due to overflow. + */ + if ((addr + count * width - 1) < addr) { + Jim_SetResultFormatted(interp, + "write_memory: memory region wraps over address zero"); return JIM_ERR; }