Fix oob write in disasm.c myregwrite

There was a dangling pointer in esil pointing to RDisasmState

WRITE of size 1 at 0x620000000a88 thread T0
    #0 0x103fab3dc in myregwrite disasm.c:2793
    #1 0x1049544b9 in r_anal_esil_reg_write esil.c:545
    #2 0x1049621e4 in esil_subeq esil.c:1418
    #3 0x1049570e0 in runword esil.c:2365
    #4 0x104955bcf in r_anal_esil_parse esil.c:2466
    #5 0x103f417e4 in r_core_anal_esil anal.c:3145
    #6 0x103df14e0 in cmd_anal_all .cmd_anal.c:4600
    #7 0x103d6c610 in cmd_anal .cmd_anal.c:4829
    #8 0x103f1ee25 in r_cmd_call cmd_api.c:213
    #9 0x103dd7afc in r_core_cmd_subst_i cmd.c:1960
    #10 0x103d66007 in r_core_cmd_subst cmd.c:1311
    #11 0x103d5fd0b in r_core_cmd cmd.c:2477
    #12 0x103d3910c in r_core_prompt_exec core.c:1687
    #13 0x103c9b1de in main radare2.c:1021
    #14 0x7fff9339b5ac in start (libdyld.dylib+0x35ac)
This commit is contained in:
Álvaro Felipe Melchor 2016-11-15 19:34:22 +01:00
parent 7f6f58d2d9
commit 1dcd1273fb
3 changed files with 29 additions and 41 deletions

View File

@ -2372,8 +2372,9 @@ static int runword(RAnalEsil *esil, const char *word) {
// run action
if (op) {
if (esil->cb.hook_command) {
if (esil->cb.hook_command (esil, word))
if (esil->cb.hook_command (esil, word)) {
return 1; // XXX cannot return != 1
}
}
return op (esil);
}
@ -2503,8 +2504,9 @@ repeat:
}
word[wordi] = 0;
if (*word) {
if (!runword (esil, word))
if (!runword (esil, word)) {
return 0;
}
switch (evalWord (esil, ostr, &str)) {
case 0: goto loop;
case 1: return 0;

View File

@ -574,7 +574,7 @@ static void ds_free(RDisasmState *ds) {
free (ds->osl);
free (ds->sl);
free (ds->_tabsbuf);
free (ds);
R_FREE (ds);
}
static void ds_set_pre(RDisasmState *ds, const char * str) {
@ -2830,44 +2830,19 @@ static int mymemwrite1(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
static int myregwrite(RAnalEsil *esil, const char *name, ut64 *val) {
char str[64], *msg = NULL;
ut32 *n32 = (ut32*)str;
RDisasmState *ds = esil->user;
RDisasmState *ds = NULL;
if (!esil) {
return 0;
}
ds = esil->user;
if (ds) {
ds->esil_likely = true;
if (!ds->show_slow) {
return 0;
}
}
memset (str, 0, sizeof (str));
if (*val != 0LL) {
#if 0
RFlagItem *fi = r_flag_get_i (esil->anal->flb.f, val);
if (fi) {
strncpy (str, fi->name, sizeof (str)-1);
}
if (!str[0]) {
(void)r_io_read_at (esil->anal->iob.io, val, (ut8*)str, sizeof (str)-1);
str[sizeof (str)-1] = 0;
if (*str && r_str_is_printable (str)) {
// do nothing
msg = r_str_newf ("\"%s\"", str);
} else {
str[0] = 0;
if (*n32 == 0) {
// msg = strdup ("NULL");
} else if (*n32 == UT32_MAX) {
/* nothing */
} else {
if (ds && !ds->show_emu_str) {
msg = r_str_newf ("-> 0x%x", *n32);
}
}
}
} else {
msg = r_str_newf ("%s", str);
}
#endif
(void)r_io_read_at (esil->anal->iob.io, *val, (ut8*)str, sizeof (str)-1);
str[sizeof (str)-1] = 0;
if (*str && r_str_is_printable (str)) {
@ -2890,13 +2865,15 @@ static int myregwrite(RAnalEsil *esil, const char *name, ut64 *val) {
msg = r_str_concatf (msg, " %s", fi->name);
}
}
if (ds && ds->show_emu_str) {
if (msg && *msg) {
r_cons_printf (" ; %s", msg);
if (ds) {
if (ds->show_emu_str) {
if (msg && *msg) {
r_cons_printf (" ; %s", msg);
}
} else {
r_cons_printf (" ; %s=0x%"PFMT64x" %s", name, *val, msg? msg: "");
}
} else {
r_cons_printf (" ; %s=0x%"PFMT64x" %s", name, *val, msg? msg: "");
}
}
free (msg);
return 0;
}
@ -2930,6 +2907,7 @@ static void ds_print_esil_anal_init(RDisasmState *ds) {
}
static void ds_print_esil_anal_fini(RDisasmState *ds) {
RCore *core = ds->core;
if (ds->show_emu && ds->esil_regstate) {
RCore* core = ds->core;
core->anal->last_disasm_reg = r_reg_arena_peek (core->anal->reg);
@ -2938,6 +2916,10 @@ static void ds_print_esil_anal_fini(RDisasmState *ds) {
r_reg_setv (core->anal->reg, pc, ds->esil_old_pc);
R_FREE (ds->esil_regstate);
}
if (core && core->anal && core->anal->esil) {
//make sure to remove reference to ds to avoid UAF
core->anal->esil->user = NULL;
}
}
static void ds_print_bbline(RDisasmState *ds) {

View File

@ -2225,10 +2225,14 @@ static void visual_refresh(RCore *core) {
r_cons_gotoxy (0, 0);
r_core_visual_title (core, color);
vi = r_config_get (core->config, "cmd.vprompt");
if (vi) r_core_cmd (core, vi, 0);
if (vi) {
r_core_cmd (core, vi, 0);
}
} else {
vi = r_config_get (core->config, "cmd.vprompt");
if (vi) r_core_cmd (core, vi, 0);
if (vi) {
r_core_cmd (core, vi, 0);
}
r_core_visual_title (core, color);
}