Skip to content

Commit 637f4bd

Browse files
committed
Fix oobread crash in DWARF parser (tests_64924) ##crash
Reported by giantbranch of NSFOCUS TIANJI Lab
1 parent 0f77010 commit 637f4bd

2 files changed

Lines changed: 18 additions & 21 deletions

File tree

libr/anal/dwarf_process.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,13 +1004,18 @@ static VariableLocation *parse_dwarf_location (Context *ctx, const RBinDwarfAttr
10041004
for (i = 0; i < block.length; i++) {
10051005
switch (block.data[i]) {
10061006
case DW_OP_fbreg: {
1007-
/* TODO sometimes CFA is referenced, but we don't parse that yet
1008-
just an offset involving framebase of a function*/
1007+
/* TODO sometimes CFA is referenced, but we don't parse that yet
1008+
just an offset involving framebase of a function*/
10091009
if (i == block.length - 1) {
10101010
return NULL;
10111011
}
1012-
const ut8 *dump = &block.data[++i];
1013-
offset = r_sleb128 (&dump, &block.data[loc->block.length]);
1012+
i++;
1013+
const ut8 *dump = block.data + i;
1014+
if (loc->block.length > block.length) {
1015+
// eprintf ("skip = %d%c", loc->block.length, 10);
1016+
return NULL;
1017+
}
1018+
offset = r_sleb128 (&dump, block.data + loc->block.length);
10141019
if (frame_base) {
10151020
/* recursive parsing, but frame_base should be only one, but someone
10161021
could make malicious resource exhaustion attack, so a depth counter might be cool? */
@@ -1019,12 +1024,10 @@ static VariableLocation *parse_dwarf_location (Context *ctx, const RBinDwarfAttr
10191024
location->offset += offset;
10201025
return location;
10211026
}
1022-
return NULL;
10231027
} else {
10241028
/* Might happen if frame_base has a frame_base reference? I don't think it can tho */
1025-
return NULL;
10261029
}
1027-
break;
1030+
return NULL;
10281031
}
10291032
case DW_OP_reg0:
10301033
case DW_OP_reg1:

libr/bin/dwarf.c

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -383,21 +383,18 @@ static inline ut64 dwarf_read_offset(bool is_64bit, const ut8 **buf, const ut8 *
383383
if (is_64bit) {
384384
result = READ64 (*buf);
385385
} else {
386-
result = READ32 (*buf);
386+
result = (ut64)READ32 (*buf);
387387
}
388388
return result;
389389
}
390390

391391
static inline ut64 dwarf_read_address(size_t size, const ut8 **buf, const ut8 *buf_end) {
392392
ut64 result;
393393
switch (size) {
394-
case 2:
395-
result = READ16 (*buf); break;
396-
case 4:
397-
result = READ32 (*buf); break;
398-
case 8:
399-
result = READ64 (*buf); break;
400-
default:
394+
case 2: result = READ16 (*buf); break;
395+
case 4: result = READ32 (*buf); break;
396+
case 8: result = READ64 (*buf); break;
397+
default:
401398
result = 0;
402399
*buf += size;
403400
eprintf ("Weird dwarf address size: %zu.", size);
@@ -1857,8 +1854,7 @@ static const ut8 *parse_attr_value(const ut8 *obuf, int obuf_len,
18571854
* @param sdb
18581855
* @return const ut8* Updated buffer
18591856
*/
1860-
static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RBinDwarfAbbrevDecl *abbrev,
1861-
RBinDwarfCompUnitHdr *hdr, RBinDwarfDie *die, const ut8 *debug_str, size_t debug_str_len, Sdb *sdb) {
1857+
static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RBinDwarfAbbrevDecl *abbrev, RBinDwarfCompUnitHdr *hdr, RBinDwarfDie *die, const ut8 *debug_str, size_t debug_str_len, Sdb *sdb) {
18621858
size_t i;
18631859
for (i = 0; i < abbrev->count - 1; i++) {
18641860
memset (&die->attr_values[i], 0, sizeof (die->attr_values[i]));
@@ -1868,9 +1864,8 @@ static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RBinDwarfAbbrevD
18681864

18691865
RBinDwarfAttrValue *attribute = &die->attr_values[i];
18701866

1871-
bool is_valid_string_form = (attribute->attr_form == DW_FORM_strp ||
1872-
attribute->attr_form == DW_FORM_string) &&
1873-
attribute->string.content;
1867+
bool is_string = (attribute->attr_form == DW_FORM_strp || attribute->attr_form == DW_FORM_string);
1868+
bool is_valid_string_form = is_string && attribute->string.content;
18741869
// TODO does this have a purpose anymore?
18751870
// Or atleast it needs to rework becase there will be
18761871
// more comp units -> more comp dirs and only the last one will be kept
@@ -1880,7 +1875,6 @@ static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RBinDwarfAbbrevD
18801875
}
18811876
die->count++;
18821877
}
1883-
18841878
return buf;
18851879
}
18861880

0 commit comments

Comments
 (0)