Fix #2983 - double-free issue in Java.RAnalOp.cases switch

This commit is contained in:
pancake 2018-02-04 12:42:42 +01:00
parent 1d58bab2af
commit 79bac9c5d7
3 changed files with 43 additions and 39 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2017 - pancake, nibble */
/* radare - LGPL - Copyright 2010-2018 - pancake, nibble */
#include <r_anal.h>
#include <r_util.h>
@ -50,6 +50,7 @@ R_API bool r_anal_op_fini(RAnalOp *op) {
r_strbuf_fini (&op->opex);
r_strbuf_fini (&op->esil);
r_anal_switch_op_free (op->switch_op);
op->switch_op = NULL;
R_FREE (op->mnemonic);
return true;
}

View File

@ -422,9 +422,11 @@ static int handle_bb_cf_linear_sweep (RAnal *anal, RAnalState *state) {
IFDBG eprintf (" - Handling a bb->jump @ 0x%04"PFMT64x", adding 0x%04"PFMT64x" for future visit\n", addr, *paddr64);
r_list_append (nodes->cfg_node_addrs, paddr64);
paddr64 = malloc (sizeof(ut64));
*paddr64 = bb->fail;
IFDBG eprintf (" - Handling a bb->fail @ 0x%04"PFMT64x", adding 0x%04"PFMT64x" for future visit\n", addr, *paddr64);
r_list_append (nodes->cfg_node_addrs, paddr64);
if (paddr64) {
*paddr64 = bb->fail;
IFDBG eprintf (" - Handling a bb->fail @ 0x%04"PFMT64x", adding 0x%04"PFMT64x" for future visit\n", addr, *paddr64);
r_list_append (nodes->cfg_node_addrs, paddr64);
}
result = R_ANAL_RET_END;
break;
case R_ANAL_OP_TYPE_SWITCH:
@ -532,8 +534,8 @@ static int analyze_from_code_attr (RAnal *anal, RAnalFunction *fcn, RBinJavaFiel
result = analyze_from_code_buffer (anal, fcn, code_addr + loadaddr, code_buf, code_length);
free (code_buf);
{
char *name = strdup (method->name);
char *name = strdup (method->name);
if (name) {
r_name_filter (name, 80);
free (fcn->name);
if (method->class_name) {
@ -567,7 +569,6 @@ static int analyze_method(RAnal *anal, RAnalFunction *fcn, RAnalState *state) {
}
static int java_analyze_fns_from_buffer( RAnal *anal, ut64 start, ut64 end, int reftype, int depth) {
int result = R_ANAL_RET_ERROR;
ut64 addr = start;
ut64 offset = 0;
@ -612,7 +613,6 @@ static int java_analyze_fns_from_buffer( RAnal *anal, ut64 start, ut64 end, int
return result;
}
static int java_analyze_fns( RAnal *anal, ut64 start, ut64 end, int reftype, int depth) {
//anal->iob.read_at (anal->iob.io, op.jump, bbuf, sizeof (bbuf));
RBinJavaObj *bin = NULL;// = get_java_bin_obj (anal);
@ -698,9 +698,12 @@ static int java_switch_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data,
break;
}
int offset = (int)(ut32)(R_BIN_JAVA_UINT (data, pos));
caseop = r_anal_switch_op_add_case (op->switch_op, addr+pos, cur_case+min_val, addr+offset);
caseop->bb_ref_to = addr+offset;
caseop->bb_ref_from = addr; // TODO figure this one out
caseop = r_anal_switch_op_add_case (op->switch_op,
addr + pos, cur_case + min_val, addr + offset);
if (caseop) {
caseop->bb_ref_to = addr+offset;
caseop->bb_ref_from = addr; // TODO figure this one out
}
}
} else {
eprintf ("Invalid switch boundaries at 0x%"PFMT64x"\n", addr);
@ -711,16 +714,14 @@ static int java_switch_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data,
}
static int java_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
int sz = 1;
/* get opcode size */
//ut8 op_byte = data[0];
ut8 op_byte = data[0];
sz = JAVA_OPS[op_byte].size;
if (!op) return sz;
int sz = JAVA_OPS[op_byte].size;
if (!op) {
return sz;
}
memset (op, '\0', sizeof (RAnalOp));
IFDBG {
//eprintf ("Extracting op from buffer (%d byte(s)) @ 0x%04x\n", len, addr);
//eprintf ("Parsing op: (0x%02x) %s.\n", op_byte, JAVA_OPS[op_byte].name);
@ -870,24 +871,24 @@ static int java_cmd_ext(RAnal *anal, const char* input) {
return -1;
}
switch (*input) {
case 'c':
// reset bytes counter for case operations
r_java_new_method ();
break;
case 'u':
switch (*(input+1)) {
case 't': {java_update_anal_types (anal, obj); return true;}
default: break;
}
break;
case 's':
switch (*(input+1)) {
//case 'e': return java_resolve_cp_idx_b64 (anal, input+2);
default: break;
}
break;
case 'c':
// reset bytes counter for case operations
r_java_new_method ();
break;
case 'u':
switch (*(input+1)) {
case 't': {java_update_anal_types (anal, obj); return true;}
default: break;
}
break;
case 's':
switch (*(input+1)) {
//case 'e': return java_resolve_cp_idx_b64 (anal, input+2);
default: break;
}
break;
default: eprintf("Command not supported"); break;
default: eprintf("Command not supported"); break;
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2014-2016 - pancake, dso */
/* radare - LGPL - Copyright 2014-2018 - pancake, dso */
#include <r_anal.h>
@ -28,14 +28,16 @@ R_API RAnalSwitchOp * r_anal_switch_op_new(ut64 addr, ut64 min_val, ut64 def_val
}
R_API void r_anal_switch_op_free(RAnalSwitchOp * swop) {
if (!swop || (((ut32)(size_t)swop) == UT32_MAX)) {
return;
if (swop) {
r_list_free (swop->cases);
free (swop);
}
r_list_free (swop->cases);
free (swop);
}
R_API RAnalCaseOp* r_anal_switch_op_add_case(RAnalSwitchOp * swop, ut64 addr, ut64 value, ut64 jump) {
if (!swop) {
return NULL;
}
RAnalCaseOp * caseop = R_NEW0 (RAnalCaseOp);
if (!caseop) {
return NULL;