From a7ce29647fcb38386d7439696375e16e093d6acb Mon Sep 17 00:00:00 2001 From: pancake Date: Mon, 21 Mar 2022 17:48:44 +0100 Subject: [PATCH] Fix UAF in aaaa on arm/thumb switching ##crash * Reported by @peacock-doris via huntr.dev * Reproducer tests_65185 * This is a logic fix, but not the fully safe as changes in the code can result on UAF again, to properly protect r2 from crashing we need to break the ABI and add refcounting to RRegItem, which can't happen in 5.6.x because of abi-compat rules --- libr/anal/fcn.c | 13 +++++++++++-- libr/anal/var.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libr/anal/fcn.c b/libr/anal/fcn.c index 9780d010464e7..d159e1ae36c47 100644 --- a/libr/anal/fcn.c +++ b/libr/anal/fcn.c @@ -815,7 +815,7 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int // note, we have still increased size of basic block // (and function) if (anal->verbose) { - eprintf("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%"PFMT64u"\n", at - oplen, bb->size); + eprintf ("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%"PFMT64u"\n", at - oplen, bb->size); } delay.idx = idx - oplen; delay.cnt = op->delay; @@ -882,6 +882,12 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int // swapped parameters wtf r_anal_xrefs_set (anal, op->addr, op->ptr, R_ANAL_REF_TYPE_DATA); } + if (anal->opt.vars && !varset) { + // XXX uses op.src/dst and fails because regprofile invalidates the regitems + // lets just call this BEFORE retpoline() to avoid such issue + r_anal_extract_vars (anal, fcn, op); + } + // this call may cause regprofile changes which cause ranalop.regitem references to be invalid analyze_retpoline (anal, op); switch (op->type & R_ANAL_OP_TYPE_MASK) { case R_ANAL_OP_TYPE_CMOV: @@ -973,7 +979,7 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int fcn->bp_off = fcn->stack - op->src[0]->delta; } if (op->dst && op->dst->reg && op->dst->reg->name && op->ptr > 0 && op->ptr != UT64_MAX) { - free(last_reg_mov_lea_name); + free (last_reg_mov_lea_name); if ((last_reg_mov_lea_name = strdup(op->dst->reg->name))) { last_reg_mov_lea_val = op->ptr; last_is_reg_mov_lea = true; @@ -1404,10 +1410,13 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int } } } +#if 0 if (anal->opt.vars && !varset) { // XXX uses op.src/dst and fails because regprofile invalidates the regitems + // we must ranalop in here to avoid uaf r_anal_extract_vars (anal, fcn, op); } +#endif if (op->type != R_ANAL_OP_TYPE_MOV && op->type != R_ANAL_OP_TYPE_CMOV && op->type != R_ANAL_OP_TYPE_LEA) { last_is_reg_mov_lea = false; } diff --git a/libr/anal/var.c b/libr/anal/var.c index 87f6a601c3f9a..575e7bb471515 100644 --- a/libr/anal/var.c +++ b/libr/anal/var.c @@ -1048,7 +1048,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char free (vartype); } else { st64 frame_off = -(ptr + fcn->bp_off); - if (maxstackframe != 0 && (frame_off > maxstackframe || frame_off < -maxstackframe)) { + if (maxstackframe > 0 && (frame_off > maxstackframe || frame_off < -maxstackframe)) { goto beach; } RAnalVar *var = get_stack_var (fcn, frame_off);