mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-29 16:10:52 +00:00
Fix invalid pointer read issue in dwarf parser ##crash (#19459)
* Exploited by tests_65179, tests_65180 and tests_64901 * Fix out of bounds issue causing memory corruption in unit test
This commit is contained in:
parent
e1efe7370f
commit
dafa685c24
@ -164,18 +164,15 @@ static inline char *create_type_name_from_offset(ut64 offset) {
|
||||
* @return char* DIEs name or NULL if error
|
||||
*/
|
||||
static char *get_die_name(const RBinDwarfDie *die) {
|
||||
char *name = NULL;
|
||||
st32 name_attr_idx = find_attr_idx (die, DW_AT_name);
|
||||
if (name_attr_idx < 0 || name_attr_idx >= die->count) {
|
||||
return NULL;
|
||||
}
|
||||
RBinDwarfAttrValue *av = &die->attr_values[name_attr_idx];
|
||||
if (av->kind == DW_AT_KIND_STRING && name_attr_idx != -1 && av->string.content) {
|
||||
name = strdup (av->string.content);
|
||||
} else {
|
||||
name = create_type_name_from_offset (die->offset);
|
||||
return strdup (av->string.content);
|
||||
}
|
||||
return name;
|
||||
return create_type_name_from_offset (die->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,7 +205,11 @@ static ut64 get_die_size(const RBinDwarfDie *die) {
|
||||
* @param strbuf strbuf to store the type into
|
||||
* @return st32 -1 if error else 0
|
||||
*/
|
||||
static st32 parse_array_type(Context *ctx, ut64 idx, RStrBuf *strbuf) {
|
||||
static void parse_array_type(Context *ctx, int idx, RStrBuf *strbuf) {
|
||||
if (idx < 0 || idx >= ctx->count) {
|
||||
// eprintf ("die out of bounds\n");
|
||||
return;
|
||||
}
|
||||
const RBinDwarfDie *die = &ctx->all_dies[idx++];
|
||||
|
||||
if (die->has_children) {
|
||||
@ -242,7 +243,6 @@ static st32 parse_array_type(Context *ctx, ut64 idx, RStrBuf *strbuf) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,7 +391,7 @@ static st32 parse_type(Context *ctx, const ut64 offset, RStrBuf *strbuf, ut64 *s
|
||||
* @param result ptr to result member to fill up
|
||||
* @return RAnalStructMember* ptr to parsed Member
|
||||
*/
|
||||
static RAnalStructMember *parse_struct_member (Context *ctx, ut64 idx, RAnalStructMember *result) {
|
||||
static RAnalStructMember *parse_struct_member(Context *ctx, ut64 idx, RAnalStructMember *result) {
|
||||
r_return_val_if_fail (result, NULL);
|
||||
const RBinDwarfDie *die = &ctx->all_dies[idx];
|
||||
|
||||
@ -1190,15 +1190,16 @@ static st32 parse_function_args_and_vars(Context *ctx, ut64 idx, RStrBuf *args,
|
||||
bool get_linkage_name = prefer_linkage_name (ctx->lang);
|
||||
bool has_linkage_name = false;
|
||||
int argNumber = 1;
|
||||
const char *name = NULL;
|
||||
size_t j;
|
||||
for (j = idx; child_depth > 0 && j < ctx->count; j++) {
|
||||
const RBinDwarfDie *child_die = &ctx->all_dies[j];
|
||||
RStrBuf type;
|
||||
r_strbuf_init (&type);
|
||||
const char *name = NULL;
|
||||
if (child_die->tag == DW_TAG_formal_parameter || child_die->tag == DW_TAG_variable) {
|
||||
Variable *var = R_NEW0 (Variable);
|
||||
size_t i;
|
||||
name = NULL;
|
||||
for (i = 0; i < child_die->count; i++) {
|
||||
const RBinDwarfAttrValue *val = &child_die->attr_values[i];
|
||||
switch (val->attr_name) {
|
||||
@ -1229,10 +1230,10 @@ static st32 parse_function_args_and_vars(Context *ctx, ut64 idx, RStrBuf *args,
|
||||
if (child_die->tag == DW_TAG_formal_parameter && child_depth == 1) {
|
||||
/* arguments sometimes have only type, create generic argX */
|
||||
if (type.len) {
|
||||
if (!name) {
|
||||
var->name = r_str_newf ("arg%d", argNumber);
|
||||
} else {
|
||||
if (name) {
|
||||
var->name = strdup (name);
|
||||
} else {
|
||||
var->name = r_str_newf ("arg%d", argNumber);
|
||||
}
|
||||
r_strbuf_appendf (args, "%s %s,", r_strbuf_get (&type), var->name);
|
||||
var->type = strdup (r_strbuf_get (&type));
|
||||
@ -1434,6 +1435,7 @@ static void parse_function(Context *ctx, ut64 idx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fcn.name || !fcn.addr) { /* we need a name, faddr */
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -1327,7 +1327,7 @@ static void print_abbrev_section(RBinDwarfDebugAbbrev *da, PrintfCallback print)
|
||||
for (i = 0; i < da->count; i++) {
|
||||
int declstag = da->decls[i].tag;
|
||||
print (" %-4"PFMT64d" ", da->decls[i].code);
|
||||
if (declstag>=0 && declstag < DW_TAG_LAST) {
|
||||
if (declstag >= 0 && declstag < DW_TAG_LAST) {
|
||||
print (" %-25s ", dwarf_tag_name_encodings[declstag]);
|
||||
}
|
||||
print ("[%s]", da->decls[i].has_children ?
|
||||
@ -1416,7 +1416,7 @@ R_API void r_bin_dwarf_free_debug_info(RBinDwarfDebugInfo *inf) {
|
||||
}
|
||||
ht_up_free (inf->lookup_table);
|
||||
free (inf->comp_units);
|
||||
free(inf);
|
||||
free (inf);
|
||||
}
|
||||
|
||||
static void print_attr_value(const RBinDwarfAttrValue *val, PrintfCallback print) {
|
||||
@ -1514,7 +1514,7 @@ static void print_debug_info(const RBinDwarfDebugInfo *inf, PrintfCallback print
|
||||
RBinDwarfDie *dies;
|
||||
RBinDwarfAttrValue *values;
|
||||
|
||||
r_return_if_fail(inf);
|
||||
r_return_if_fail (inf);
|
||||
|
||||
for (i = 0; i < inf->count; i++) {
|
||||
print ("\n");
|
||||
@ -1596,6 +1596,13 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
||||
const ut8 *debug_str, size_t debug_str_len) {
|
||||
r_return_val_if_fail (def && value && hdr && obuf, NULL);
|
||||
|
||||
value->attr_form = def->attr_form;
|
||||
value->attr_name = def->attr_name;
|
||||
value->block.data = NULL;
|
||||
value->string.content = NULL;
|
||||
value->string.offset = 0;
|
||||
|
||||
|
||||
const ut8 *buf = obuf;
|
||||
const ut8 *buf_end = obuf + obuf_len;
|
||||
size_t j;
|
||||
@ -1604,12 +1611,6 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value->attr_form = def->attr_form;
|
||||
value->attr_name = def->attr_name;
|
||||
value->block.data = NULL;
|
||||
value->string.content = NULL;
|
||||
value->string.offset = 0;
|
||||
|
||||
// http://www.dwarfstd.org/doc/DWARF4.pdf#page=161&zoom=100,0,560
|
||||
switch (def->attr_form) {
|
||||
case DW_FORM_addr:
|
||||
|
@ -61,7 +61,7 @@ extern "C" {
|
||||
#define DW_TAG_member 0x0d
|
||||
#define DW_TAG_pointer_type 0x0f
|
||||
#define DW_TAG_reference_type 0x10
|
||||
#define DW_TAG_compile_unit 0x11 //
|
||||
#define DW_TAG_compile_unit 0x11
|
||||
#define DW_TAG_string_type 0x12
|
||||
#define DW_TAG_structure_type 0x13
|
||||
#define DW_TAG_subroutine_type 0x15
|
||||
@ -202,8 +202,8 @@ extern "C" {
|
||||
#define DW_AT_description 0x5a
|
||||
#define DW_AT_binary_scale 0x5b
|
||||
#define DW_AT_decimal_scale 0x5c
|
||||
#define DW_AT_small 0x5d
|
||||
#define DW_AT_decimal_sign 0x5e
|
||||
#define DW_AT_small 0x5d
|
||||
#define DW_AT_decimal_sign 0x5e
|
||||
#define DW_AT_digit_count 0x5f
|
||||
#define DW_AT_picture_string 0x60
|
||||
#define DW_AT_mutable 0x61
|
||||
@ -708,19 +708,19 @@ typedef struct dwarf_attr_kind {
|
||||
ut64 attr_name;
|
||||
ut64 attr_form;
|
||||
RBinDwarfAttrKind kind;
|
||||
/* This is subideal, as dw_form_data can be anything
|
||||
we could lose information example: encoding signed
|
||||
/* This is subideal, as dw_form_data can be anything
|
||||
we could lose information example: encoding signed
|
||||
2 byte int into ut64 and then interpreting it as st64 TODO*/
|
||||
union {
|
||||
union {
|
||||
ut64 address;
|
||||
RBinDwarfBlock block;
|
||||
ut64 uconstant;
|
||||
st64 sconstant;
|
||||
ut8 flag;
|
||||
ut64 reference;
|
||||
RBinDwarfBlock block;
|
||||
struct {
|
||||
const char *content;
|
||||
ut64 offset;
|
||||
const char *content;
|
||||
} string;
|
||||
};
|
||||
} RBinDwarfAttrValue;
|
||||
|
@ -3,7 +3,7 @@ BINS=$(patsubst %.c,$(BINDIR)/%,$(wildcard *.c))
|
||||
LDFLAGS+=$(shell pkg-config --libs r_core)
|
||||
CFLAGS+=-I../../libr/include
|
||||
CFLAGS+=-I../../shlr/sdb/src
|
||||
# $(shell pkg-config --cflags r_core) -g
|
||||
CFLAGS+=-g
|
||||
ifeq ($(ASAN),1)
|
||||
ASAN_LD_PRELOAD=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.5
|
||||
else
|
||||
|
@ -45,8 +45,8 @@ bool test_r_reg_get_value_gpr(void) {
|
||||
reg = r_reg_new ();
|
||||
mu_assert_notnull (reg, "r_reg_new () failed");
|
||||
|
||||
r_reg_set_profile_string (reg,
|
||||
"gpr eax .32 0 0\n\
|
||||
r_reg_set_profile_string (reg, "=A0 eax\n\
|
||||
gpr eax .32 0 0\n\
|
||||
gpr ax .16 0 0\n\
|
||||
gpr ah .8 1 0\n\
|
||||
gpr al .8 0 0\n\
|
||||
|
Loading…
Reference in New Issue
Block a user