Skip to content

Check the value read from target before performing address arithmetic based on it #1311

@en-sc

Description

@en-sc

When accessing memory through program buffer, in case of an AC busy, the number of elements accessed is derived from a value of a register read from target.

/* See how far we got by reading s0/a0 */
uint32_t index_on_target;
if (/*is_repeated_read*/ args.increment == 0) {
/* s0 is constant, a0 is incremented by one each execution */
riscv_reg_t counter;
if (register_read_direct(target, &counter, GDB_REGNO_A0) != ERROR_OK)
return ERROR_FAIL;
index_on_target = counter;
} else {
target_addr_t address_on_target;
if (register_read_direct(target, &address_on_target, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
index_on_target = (address_on_target - args.address) /
args.increment;
}
/* According to the spec, if an abstract command fails, one can't make any
* assumptions about dm_data registers, so all the values in the pipeline
* are clobbered now and need to be reread.
*/
const uint32_t min_index_on_target = start_index + 2;
if (index_on_target < min_index_on_target) {
LOG_TARGET_ERROR(target, "Arithmetic does not work correctly on the target");
return ERROR_FAIL;
} else if (index_on_target == min_index_on_target) {
LOG_TARGET_DEBUG(target, "No forward progress");
}
const uint32_t next_index = (index_on_target - 2);
*elements_read = next_index - start_index;

target_addr_t address_on_target;
if (register_read_direct(target, &address_on_target, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
const uint8_t * const curr_buff = buffer + (address_on_target - *address_p);

This value should not be assumed to be bound, therefore these bounds should be checked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions