From 879a32d4b0dc29a03805a1f46c4cae2d086b87fa Mon Sep 17 00:00:00 2001 From: radare Date: Mon, 21 May 2018 01:59:25 +0200 Subject: [PATCH] Fix use after free and oobread in pf command (#10098) * Fix use after free and oobread in pf command - Spotted by running the testsuite in ASAN mode * Few minor fixes (by @sivaramaaa) --- libr/core/cmd_api.c | 6 ++++-- libr/core/cmd_print.c | 6 +++--- libr/util/p_format.c | 25 +++++++++++++++++-------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/libr/core/cmd_api.c b/libr/core/cmd_api.c index b6929b1247..86dbd1cb0a 100644 --- a/libr/core/cmd_api.c +++ b/libr/core/cmd_api.c @@ -229,9 +229,11 @@ R_API int r_cmd_call(RCmd *cmd, const char *input) { } c = cmd->cmds[((ut8)input[0]) & 0xff]; if (c && c->callback) { - const char *inp = (*input)? input+1: ""; + const char *inp = (*input)? input + 1: ""; ret = c->callback (cmd->data, inp); - } else ret = -1; + } else { + ret = -1; + } free (nstr); } return ret; diff --git a/libr/core/cmd_print.c b/libr/core/cmd_print.c index 3b96f86112..dd1deea7f4 100644 --- a/libr/core/cmd_print.c +++ b/libr/core/cmd_print.c @@ -1021,14 +1021,14 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block, *eq++ = 0; mode = R_PRINT_MUSTSET; r_print_format (core->print, core->offset, - block, core->blocksize, name, mode, eq, dot); + core->block, core->blocksize, name, mode, eq, dot); } else { r_print_format (core->print, core->offset, - block, core->blocksize, name, mode, NULL, dot); + core->block, core->blocksize, name, mode, NULL, dot); } } else { r_print_format (core->print, core->offset, - block, core->blocksize, name, mode, NULL, NULL); + core->block, core->blocksize, name, mode, NULL, NULL); } free (name); } diff --git a/libr/util/p_format.c b/libr/util/p_format.c index 073fc0b968..ae2286da4e 100644 --- a/libr/util/p_format.c +++ b/libr/util/p_format.c @@ -1312,7 +1312,7 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode, int n) { } } - r_str_word_set0_stack (args); + int words = r_str_word_set0_stack (args); fmt_len = strlen (fmt); for (; i < fmt_len; i++) { if (fmt[i] == '[') { @@ -1384,10 +1384,19 @@ int r_print_format_struct_size(const char *f, RPrint *p, int mode, int n) { break; case '?': { + const char *wordAtIndex = NULL; const char *format = NULL; char *endname = NULL, *structname = NULL; char tmp = 0; - structname = strdup (r_str_word_get0 (args, idx)); + if (words < idx) { + eprintf ("Index out of bounds\n"); + } else { + wordAtIndex = r_str_word_get0 (args, idx); + } + if (!wordAtIndex) { + break; + } + structname = strdup (wordAtIndex); if (*structname == '(') { endname = (char*)r_str_rchr (structname, NULL, ')'); } else { @@ -1561,7 +1570,6 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len, const char *argend; int viewflags = 0; char *oarg = NULL; - ut8 *buf; /* Load format from name into fmt */ if (!formatname) { @@ -1581,7 +1589,7 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len, return 0; } // len+2 to save space for the null termination in wide strings - buf = calloc (1, len + 2); + ut8 *buf = calloc (1, len + 2); if (!buf) { return 0; } @@ -1744,13 +1752,14 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len, if (mode & R_PRINT_MUSTSEE && otimes > 1) { p->cb_printf (" "); } - if (idx < nargs && tmp != 'e' && isptr == 0) { char *dot = NULL, *bracket = NULL; - if (field) + if (field) { dot = strchr (field, '.'); - if (dot) + } + if (dot) { *dot = '\0'; + } free (oarg); oarg = fieldname = strdup (r_str_word_get0 (args, idx)); if (ISSTRUCT || tmp=='E' || tmp=='B' || tmp=='r') { @@ -2128,7 +2137,7 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len, slide += NESTEDSTRUCT; if (size == -1) { s = r_print_format_struct (p, seeki, - buf+i, len-i, fmtname, slide, + buf + i, len - i, fmtname, slide, mode, setval, nxtfield, anon); i += (isptr) ? (p->bits / 8) : s; if (MUSTSEEJSON) {