Fix double free in r_bp_del_index and other breakpoint index bugs

* Lack of cleanup in r_bp_del_all causing use after free in other dbi
commands
* Copy paste error turning dbix into dbx
* Add dbi- command
* Allow dbi commands to operate with index 0
This commit is contained in:
Kārlis Seņko 2020-01-05 16:55:24 +02:00 committed by radare
parent 9b5aa5527f
commit b0ff7f5285
3 changed files with 60 additions and 20 deletions

View File

@ -236,8 +236,12 @@ R_API RBreakpointItem* r_bp_add_hw(RBreakpoint *bp, ut64 addr, int size, int per
}
R_API int r_bp_del_all(RBreakpoint *bp) {
int i;
if (!r_list_empty (bp->bps)) {
r_list_purge (bp->bps);
for (i = 0; i < bp->bps_idx_count; i++) {
bp->bps_idx[i] = NULL;
}
return true;
}
return false;
@ -388,7 +392,7 @@ R_API int r_bp_get_index_at (RBreakpoint *bp, ut64 addr) {
R_API int r_bp_del_index(RBreakpoint *bp, int idx) {
if (idx >= 0 && idx < bp->bps_idx_count) {
r_list_delete_data (bp->bps, bp->bps_idx[idx]);
R_FREE (bp->bps_idx[idx]);
bp->bps_idx[idx] = 0;
return true;
}
return false;

View File

@ -72,6 +72,7 @@ static const char *help_msg_db[] = {
"dbi", "", "List breakpoint indexes",
"dbi", " <addr>", "Show breakpoint index in givengiven offset",
"dbi.", "", "Show breakpoint index in current offset",
"dbi-", " <idx>", "Remove breakpoint by index",
"dbix", " <idx> [expr]", "Set expression for bp at given index",
"dbic", " <idx> <cmd>", "Run command at breakpoint index",
"dbie", " <idx>", "Enable breakpoint by index",
@ -3202,19 +3203,27 @@ static void static_debug_stop(void *u) {
r_debug_stop (dbg);
}
static void core_cmd_dbi (RCore *core, const char *input, ut64 addr) {
static void core_cmd_dbi (RCore *core, const char *input, ut64 idx) {
int i;
char *p;
RBreakpointItem *bpi;
switch (input[2]) {
case ' ': // "dbi."
{
ut64 addr = idx;
int idx = r_bp_get_index_at (core->dbg->bp, addr);
if (idx != -1) {
r_cons_printf ("%d\n", idx);
}
}
break;
case '-': // "dbi-"
{
if (!r_bp_del_index (core->dbg->bp, idx)) {
eprintf ("Breakpoint with index %d not found\n", (int)idx);
}
}
break;
case '.': // "dbi."
{
int idx = r_bp_get_index_at (core->dbg->bp, core->offset);
@ -3233,18 +3242,14 @@ static void core_cmd_dbi (RCore *core, const char *input, ut64 addr) {
break;
case 'x': // "dbix"
if (input[3] == ' ') {
int idx = r_bp_get_index_at (core->dbg->bp, addr);
if (idx != -1) {
bpi = r_bp_get_index (core->dbg->bp, idx);
if (bpi) {
char *expr = strchr (input + 4, ' ');
if (expr) {
free (bpi->expr);
bpi->expr = strdup (expr);
}
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
char *expr = strchr (input + 4, ' ');
if (expr) {
free (bpi->expr);
bpi->expr = strdup (expr);
}
r_cons_printf ("%d\n", idx);
}
r_cons_printf ("%d\n", (int)idx);
} else {
for (i = 0; i < core->dbg->bp->bps_idx_count; i++) {
RBreakpointItem *bp = core->dbg->bp->bps_idx[i];
@ -3275,21 +3280,21 @@ static void core_cmd_dbi (RCore *core, const char *input, ut64 addr) {
}
break;
case 'e': // "dbie"
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->enabled = true;
} else {
eprintf ("Cannot unset tracepoint\n");
}
break;
case 'd': // "dbid"
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->enabled = false;
} else {
eprintf ("Cannot unset tracepoint\n");
}
break;
case 's': // "dbis"
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->enabled = !!!bpi->enabled;
} else {
eprintf ("Cannot unset tracepoint\n");
@ -3298,19 +3303,19 @@ static void core_cmd_dbi (RCore *core, const char *input, ut64 addr) {
case 't': // "dbite" "dbitd" ...
switch (input[3]) {
case 'e':
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->trace = true;
} else {
eprintf ("Cannot unset tracepoint\n");
}
break;
case 'd':
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->trace = false;
} else eprintf ("Cannot unset tracepoint\n");
break;
case 's':
if ((bpi = r_bp_get_index (core->dbg->bp, addr))) {
if ((bpi = r_bp_get_index (core->dbg->bp, idx))) {
bpi->trace = !!!bpi->trace;
} else {
eprintf ("Cannot unset tracepoint\n");
@ -3335,9 +3340,10 @@ static void r_core_cmd_bp(RCore *core, const char *input) {
bool watch = false;
int rw = 0;
RList *list;
ut64 addr;
ut64 addr, idx;
p = strchr (input, ' ');
addr = p? r_num_math (core->num, p + 1): UT64_MAX;
idx = addr; // 0 is valid index
if (!addr) {
addr = UT64_MAX;
}
@ -3780,7 +3786,7 @@ static void r_core_cmd_bp(RCore *core, const char *input) {
}
break;
case 'i':
core_cmd_dbi (core, input, addr);
core_cmd_dbi (core, input, idx);
break;
case '?':
default:

View File

@ -217,3 +217,33 @@ EXPECT=<<RUN
"valid"
EOF
RUN
NAME='dbg.bp_remove_index'
FILE=../bins/elf/analysis/x86-helloworld-gcc
ARGS=-d
CMDS=<<EOF
db main
db main+1
db main+2
db main+4
dbi~[0,2]
db-*
dbi
db main
db main+1
dbi- 1
?e ----------
dbi~[0,2]
dbi- 0
dbi~[0,2]
EOF
EXPECT=<<EOF
0 E:1
1 E:1
2 E:1
3 E:1
----------
0 E:1
Hello world!
EOF
RUN