1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
From aa6917772d2f32e5a7daab25a46c72df0b5ea406 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=A4rkl?= <info@florianmaerkl.de>
Date: Fri, 10 Dec 2021 15:43:12 +0100
Subject: [PATCH] Fix oob write for dwarf with abbrev with count 0 (Fix #2083)
(#2086)
---
librz/bin/dwarf.c | 40 ++++++++++++++++++++++-----------------
test/db/formats/elf/crash | 8 ++++++++
2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/librz/bin/dwarf.c b/librz/bin/dwarf.c
index 1ed1d3517c2..23dd1f9f0b1 100644
--- a/librz/bin/dwarf.c
+++ b/librz/bin/dwarf.c
@@ -1220,9 +1220,13 @@ static int init_die(RzBinDwarfDie *die, ut64 abbr_code, ut64 attr_count) {
if (!die) {
return -1;
}
- die->attr_values = calloc(sizeof(RzBinDwarfAttrValue), attr_count);
- if (!die->attr_values) {
- return -1;
+ if (attr_count) {
+ die->attr_values = calloc(sizeof(RzBinDwarfAttrValue), attr_count);
+ if (!die->attr_values) {
+ return -1;
+ }
+ } else {
+ die->attr_values = NULL;
}
die->abbrev_code = abbr_code;
die->capacity = attr_count;
@@ -1726,25 +1730,27 @@ static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RzBinDwarfDebugI
size_t i;
const char *comp_dir = NULL;
ut64 line_info_offset = UT64_MAX;
- for (i = 0; i < abbrev->count - 1; i++) {
- memset(&die->attr_values[i], 0, sizeof(die->attr_values[i]));
+ if (abbrev->count) {
+ for (i = 0; i < abbrev->count - 1; i++) {
+ memset(&die->attr_values[i], 0, sizeof(die->attr_values[i]));
- buf = parse_attr_value(buf, buf_end - buf, &abbrev->defs[i],
- &die->attr_values[i], hdr, debug_str, debug_str_len, big_endian);
+ buf = parse_attr_value(buf, buf_end - buf, &abbrev->defs[i],
+ &die->attr_values[i], hdr, debug_str, debug_str_len, big_endian);
- RzBinDwarfAttrValue *attribute = &die->attr_values[i];
+ RzBinDwarfAttrValue *attribute = &die->attr_values[i];
- if (attribute->attr_name == DW_AT_comp_dir && (attribute->attr_form == DW_FORM_strp || attribute->attr_form == DW_FORM_string) && attribute->string.content) {
- comp_dir = attribute->string.content;
- }
- if (attribute->attr_name == DW_AT_stmt_list) {
- if (attribute->kind == DW_AT_KIND_CONSTANT) {
- line_info_offset = attribute->uconstant;
- } else if (attribute->kind == DW_AT_KIND_REFERENCE) {
- line_info_offset = attribute->reference;
+ if (attribute->attr_name == DW_AT_comp_dir && (attribute->attr_form == DW_FORM_strp || attribute->attr_form == DW_FORM_string) && attribute->string.content) {
+ comp_dir = attribute->string.content;
+ }
+ if (attribute->attr_name == DW_AT_stmt_list) {
+ if (attribute->kind == DW_AT_KIND_CONSTANT) {
+ line_info_offset = attribute->uconstant;
+ } else if (attribute->kind == DW_AT_KIND_REFERENCE) {
+ line_info_offset = attribute->reference;
+ }
}
+ die->count++;
}
- die->count++;
}
// If this is a compilation unit dir attribute, we want to cache it so the line info parsing
diff --git a/test/db/formats/elf/crash b/test/db/formats/elf/crash
index ea6c2c214bb..fb8a572bd56 100644
--- a/test/db/formats/elf/crash
+++ b/test/db/formats/elf/crash
@@ -25,3 +25,11 @@ nth vaddr bind type lib name
[]
EOF
RUN
+
+NAME=ELF/Dwarf: abbrev empty
+FILE=bins/elf/dwarf_fuzzed_abbrev_empty
+CMDS=<<EOF
+aaa
+EOF
+EXPECT=
+RUN
|