Skip to content

Commit

Permalink
Fix overflow issue in write_memory_progbuf (#714)
Browse files Browse the repository at this point in the history
If range's upper bound was equal to 2^64 or the range was wrapping around 0
(which is perfectly legal), writes were not performed due to riscv_addr_t
overflow.
  • Loading branch information
en-sc authored Aug 1, 2022
1 parent 793def2 commit 5217759
Showing 1 changed file with 5 additions and 7 deletions.
12 changes: 5 additions & 7 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -3834,10 +3834,10 @@ static int write_memory_progbuf(struct target *target, target_addr_t address,
riscv_program_write(&program);

riscv_addr_t cur_addr = address;
riscv_addr_t fin_addr = address + (count * size);
riscv_addr_t distance = (riscv_addr_t)count * size;
bool setup_needed = true;
LOG_DEBUG("writing until final address 0x%016" PRIx64, fin_addr);
while (cur_addr < fin_addr) {
LOG_DEBUG("writing until final address 0x%016" PRIx64, cur_addr + distance);
while (cur_addr - address < distance) {
LOG_DEBUG("transferring burst starting at address 0x%016" PRIx64,
cur_addr);

Expand All @@ -3849,14 +3849,12 @@ static int write_memory_progbuf(struct target *target, target_addr_t address,
goto error;

/* To write another word, we put it in S1 and execute the program. */
unsigned start = (cur_addr - address) / size;
for (unsigned i = start; i < count; ++i) {
unsigned offset = size*i;
for (riscv_addr_t offset = cur_addr - address; offset < distance; offset += size) {
const uint8_t *t_buffer = buffer + offset;

uint64_t value = buf_get_u64(t_buffer, 0, 8 * size);

log_memory_access(address + offset, value, size, false);
log_memory_access(cur_addr, value, size, false);
cur_addr += size;

if (setup_needed) {
Expand Down

0 comments on commit 5217759

Please sign in to comment.