gdbstub:support gdbstub memory access control

Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
anjiahao 2024-07-17 11:31:40 +08:00 committed by Xiang Xiao
parent 76508d42a9
commit e0bcad3a1d
2 changed files with 70 additions and 3 deletions

View file

@ -25,6 +25,7 @@
****************************************************************************/
#include <ctype.h>
#include <elf.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
@ -35,6 +36,7 @@
#include <nuttx/sched.h>
#include <nuttx/ascii.h>
#include <nuttx/gdbstub.h>
#include <nuttx/memoryregion.h>
/****************************************************************************
* Pre-processor Definitions
@ -68,6 +70,7 @@ struct gdb_state_s
size_t pkt_len; /* Packet send and receive length */
uint8_t running_regs[XCPTCONTEXT_SIZE]; /* Registers of running thread */
size_t size; /* Size of registers */
FAR struct memory_region_s *range; /* Memory regions */
uintptr_t registers[0]; /* Registers of other threads */
};
@ -633,6 +636,7 @@ static ssize_t gdb_hex2bin(FAR void *buf, size_t buf_len,
in[pos], in[pos + 1], 0
};
set_errno(0);
out[pos / 2] = strtoul(ch, NULL, 16); /* Decode high nibble */
if (out[pos / 2] == 0 && get_errno())
{
@ -703,6 +707,40 @@ static ssize_t gdb_bin2bin(FAR void *buf, size_t buf_len,
return out_pos;
}
/****************************************************************************
* Name: gdb_is_valid_region
* Description:
* Check if the address is in the memory region.
*
****************************************************************************/
static bool gdb_is_valid_region(FAR struct gdb_state_s *state,
uintptr_t addr, size_t len, uint32_t flags)
{
FAR struct memory_region_s *region = state->range;
if (state->range == NULL)
{
/* No memory region, so allow all access */
return true;
}
while (region->start < region->end)
{
if (addr >= region->start &&
addr <= region->end - len &&
(region->flags & flags) == flags)
{
return true;
}
region++;
}
return false;
}
/****************************************************************************
* Command Functions
****************************************************************************/
@ -732,7 +770,14 @@ static ssize_t gdb_get_memory(FAR struct gdb_state_s *state,
uintptr_t addr, size_t len,
gdb_format_func_t format)
{
return format(buf, buf_len, (FAR const void *)addr, len);
ssize_t ret = -EINVAL;
if (gdb_is_valid_region(state, addr, len, PF_R))
{
return format(buf, buf_len, (FAR const void *)addr, len);
}
return ret;
}
/****************************************************************************
@ -760,7 +805,14 @@ static ssize_t gdb_put_memory(FAR struct gdb_state_s *state,
uintptr_t addr, size_t len,
gdb_format_func_t format)
{
return format((FAR void *)addr, len, buf, buf_len);
ssize_t ret = -EINVAL;
if (gdb_is_valid_region(state, addr, len, PF_W))
{
return format((FAR void *)addr, len, buf, buf_len);
}
return ret;
}
/****************************************************************************
@ -1786,6 +1838,16 @@ FAR struct gdb_state_s *gdb_state_init(gdb_send_func_t send,
state->priv = priv;
state->monitor = monitor;
if (CONFIG_BOARD_MEMORY_RANGE[0] != '\0')
{
state->range = alloc_memory_region(CONFIG_BOARD_MEMORY_RANGE);
if (state->range == NULL)
{
lib_free(state);
return NULL;
}
}
return state;
}
@ -1804,6 +1866,11 @@ void gdb_state_uninit(FAR struct gdb_state_s *state)
{
if (state != NULL)
{
if (state->range != NULL)
{
free_memory_region(state->range);
}
lib_free(state);
}
}

View file

@ -212,7 +212,7 @@ int coredump_add_memory_region(FAR const void *ptr, size_t size)
{
region = (FAR struct memory_region_s *)g_regions;
while (region->start != 0)
while (region->start < region->end)
{
if ((uintptr_t)ptr >= region->start &&
(uintptr_t)ptr + size < region->end)