Fix uaf caused by RRegItem.free instead of .unref ##crash

This commit is contained in:
pancake 2023-03-05 09:15:09 +01:00 committed by pancake
parent f6bc514e00
commit 542f553664
3 changed files with 23 additions and 25 deletions

View File

@ -1507,13 +1507,13 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
: INSOP(0).mem.segment == X86_REG_GS ? "gs"
: INSOP(0).mem.segment == X86_REG_SS ? "ss"
: "unknown_segment_register",
(ut64)INSOP(0).mem.disp,
(ut64)INSOP (0).mem.disp,
rs, pc);
} else {
esilprintf (
op,
"0x%"PFMT64x",[%d],%s,=",
(ut64)INSOP(0).mem.disp, rs, pc);
(ut64)INSOP (0).mem.disp, rs, pc);
}
}
}
@ -2375,18 +2375,17 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
}
}
// R2_590 - return const char * to avoid derefs
static RRegItem *cs_reg2reg(RReg *reg, csh *h, int id) {
if (id == X86_REG_INVALID) {
return NULL;
}
RRegItem *ri = r_reg_get (reg, (char *)cs_reg_name (*h, id), -1);
// r_unref (ri); // XXX this fixes the refleak but its not correct
return ri;
}
static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn, int mode) {
int i;
RAnalValue *val;
int regsz;
x86_reg sp;
switch (mode) {
@ -2413,7 +2412,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
}
// PC register
val = r_anal_value_new ();
RAnalValue *val = r_anal_value_new ();
if (val) {
val->type = R_ANAL_VAL_REG;
val->access = R_PERM_W;
@ -2426,26 +2425,22 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
cs_regs regs_read, regs_write;
ut8 read_count, write_count;
if (cs_regs_access (*handle, insn, regs_read, &read_count, regs_write, &write_count) == 0) {
if (read_count > 0) {
for (i = 0; i < read_count; i++) {
val = r_anal_value_new ();
if (val) {
val->type = R_ANAL_VAL_REG;
val->access = R_PERM_R;
val->reg = cs_reg2reg (reg, handle, regs_read[i]);
r_list_append (ret, val);
}
for (i = 0; i < read_count; i++) {
val = r_anal_value_new ();
if (val) {
val->type = R_ANAL_VAL_REG;
val->access = R_PERM_R;
val->reg = cs_reg2reg (reg, handle, regs_read[i]);
r_list_append (ret, val);
}
}
if (write_count > 0) {
for (i = 0; i < write_count; i++) {
val = r_anal_value_new ();
if (val) {
val->type = R_ANAL_VAL_REG;
val->access = R_PERM_W;
val->reg = cs_reg2reg (reg, handle, regs_write[i]);
r_list_append (ret, val);
}
for (i = 0; i < write_count; i++) {
val = r_anal_value_new ();
if (val) {
val->type = R_ANAL_VAL_REG;
val->access = R_PERM_W;
val->reg = cs_reg2reg (reg, handle, regs_write[i]);
r_list_append (ret, val);
}
}
}

View File

@ -245,7 +245,7 @@ R_API void r_reg_free_internal(RReg *reg, bool init) {
}
if (init) {
r_list_free (reg->regset[i].regs);
reg->regset[i].regs = r_list_newf ((RListFree)r_reg_item_free);
reg->regset[i].regs = r_list_newf ((RListFree)r_reg_item_unref);
} else {
r_list_free (reg->regset[i].regs);
reg->regset[i].regs = NULL;
@ -326,7 +326,7 @@ R_API RReg *r_reg_init(RReg *reg) {
return NULL;
}
reg->regset[i].pool = r_list_newf ((RListFree)r_reg_arena_free);
reg->regset[i].regs = r_list_newf ((RListFree)r_reg_item_free);
reg->regset[i].regs = r_list_newf ((RListFree)r_reg_item_unref);
r_list_push (reg->regset[i].pool, arena);
reg->regset[i].arena = arena;
}

View File

@ -6,6 +6,9 @@ int LLVMFuzzerInitialize(int *lf_argc, char ***lf_argv) {
}
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size < 1) {
return 0;
}
RCore *r = r_core_new();
if (Size < 1) {
return 0;