/src/libdwarf/fuzz/fuzz_gdbindex.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright 2021 Google LLC |
2 | | Licensed under the Apache License, Version 2.0 (the "License"); |
3 | | you may not use this file except in compliance with the License. |
4 | | You may obtain a copy of the License at |
5 | | http://www.apache.org/licenses/LICENSE-2.0 |
6 | | Unless required by applicable law or agreed to in writing, software |
7 | | distributed under the License is distributed on an "AS IS" BASIS, |
8 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
9 | | See the License for the specific language governing permissions and |
10 | | limitations under the License. |
11 | | */ |
12 | | #include <fcntl.h> /* open() O_RDONLY O_BINARY */ |
13 | | #include <stdint.h> |
14 | | #include <stdio.h> |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include <sys/types.h> |
18 | | #include <unistd.h> |
19 | | |
20 | | #ifndef O_BINARY |
21 | 8.63k | #define O_BINARY 0 /* So it does nothing in Linux/Unix */ |
22 | | #endif |
23 | | |
24 | | /* |
25 | | * Libdwarf library callers can only use these headers. |
26 | | */ |
27 | | #include "dwarf.h" |
28 | | #include "libdwarf.h" |
29 | | |
30 | | int examplew(Dwarf_Debug dbg, Dwarf_Error *error); |
31 | | int examplewgdbindex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error); |
32 | | int examplex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error); |
33 | | |
34 | | /* |
35 | | * A fuzzer that simulates a small part of the simplereader.c example. |
36 | | */ |
37 | 8.63k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
38 | 8.63k | char filename[256]; |
39 | 8.63k | sprintf(filename, "/tmp/libfuzzer.%d", getpid()); |
40 | | |
41 | 8.63k | FILE *fp = fopen(filename, "wb"); |
42 | 8.63k | if (!fp) { |
43 | 0 | return 0; |
44 | 0 | } |
45 | 8.63k | fwrite(data, size, 1, fp); |
46 | 8.63k | fclose(fp); |
47 | | |
48 | 8.63k | Dwarf_Debug dbg = 0; |
49 | 8.63k | int res = DW_DLV_ERROR; |
50 | 8.63k | Dwarf_Error error = 0; |
51 | 8.63k | Dwarf_Handler errhand = 0; |
52 | 8.63k | Dwarf_Ptr errarg = 0; |
53 | 8.63k | int regtabrulecount = 0; |
54 | 8.63k | int curopt = 0; |
55 | | |
56 | 8.63k | int fd = open(filename, O_RDONLY | O_BINARY); |
57 | 8.63k | if (fd < 0) { |
58 | 0 | exit(EXIT_FAILURE); |
59 | 0 | } |
60 | | |
61 | 8.63k | res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error); |
62 | | |
63 | 8.63k | if (res != DW_DLV_OK) { |
64 | 7.80k | dwarf_dealloc_error(dbg, error); |
65 | 7.80k | } else { |
66 | 832 | examplew(dbg, &error); |
67 | 832 | } |
68 | | |
69 | 8.63k | dwarf_finish(dbg); |
70 | 8.63k | close(fd); |
71 | 8.63k | unlink(filename); |
72 | 8.63k | return 0; |
73 | 8.63k | } |
74 | | |
75 | 832 | int examplew(Dwarf_Debug dbg, Dwarf_Error *error) { |
76 | 832 | Dwarf_Gdbindex gindexptr = 0; |
77 | 832 | Dwarf_Unsigned version = 0; |
78 | 832 | Dwarf_Unsigned cu_list_offset = 0; |
79 | 832 | Dwarf_Unsigned types_cu_list_offset = 0; |
80 | 832 | Dwarf_Unsigned address_area_offset = 0; |
81 | 832 | Dwarf_Unsigned symbol_table_offset = 0; |
82 | 832 | Dwarf_Unsigned constant_pool_offset = 0; |
83 | 832 | Dwarf_Unsigned section_size = 0; |
84 | 832 | const char *section_name = 0; |
85 | 832 | int res = 0; |
86 | | |
87 | 832 | res = dwarf_gdbindex_header(dbg, &gindexptr, &version, &cu_list_offset, |
88 | 832 | &types_cu_list_offset, &address_area_offset, |
89 | 832 | &symbol_table_offset, &constant_pool_offset, |
90 | 832 | §ion_size, §ion_name, error); |
91 | 832 | if (res != DW_DLV_OK) { |
92 | 671 | return res; |
93 | 671 | } |
94 | 161 | { |
95 | 161 | Dwarf_Unsigned length = 0; |
96 | 161 | Dwarf_Unsigned typeslength = 0; |
97 | 161 | Dwarf_Unsigned i = 0; |
98 | 161 | res = dwarf_gdbindex_culist_array(gindexptr, &length, error); |
99 | 161 | if (res != DW_DLV_OK) { |
100 | 0 | dwarf_dealloc_gdbindex(gindexptr); |
101 | 0 | return res; |
102 | 0 | } |
103 | 8.41k | for (i = 0; i < length; ++i) { |
104 | 8.25k | Dwarf_Unsigned cuoffset = 0; |
105 | 8.25k | Dwarf_Unsigned culength = 0; |
106 | 8.25k | res = dwarf_gdbindex_culist_entry(gindexptr, i, &cuoffset, &culength, |
107 | 8.25k | error); |
108 | 8.25k | if (res != DW_DLV_OK) { |
109 | 0 | return res; |
110 | 0 | } |
111 | 8.25k | } |
112 | 161 | res = dwarf_gdbindex_types_culist_array(gindexptr, &typeslength, error); |
113 | 161 | if (res != DW_DLV_OK) { |
114 | 0 | dwarf_dealloc_gdbindex(gindexptr); |
115 | 0 | return res; |
116 | 0 | } |
117 | 16.4k | for (i = 0; i < typeslength; ++i) { |
118 | 16.3k | Dwarf_Unsigned cuoffset = 0; |
119 | 16.3k | Dwarf_Unsigned tuoffset = 0; |
120 | 16.3k | Dwarf_Unsigned type_signature = 0; |
121 | 16.3k | res = dwarf_gdbindex_types_culist_entry( |
122 | 16.3k | gindexptr, i, &cuoffset, &tuoffset, &type_signature, error); |
123 | 16.3k | if (res != DW_DLV_OK) { |
124 | 0 | dwarf_dealloc_gdbindex(gindexptr); |
125 | 0 | return res; |
126 | 0 | } |
127 | 16.3k | } |
128 | | |
129 | 161 | res = examplewgdbindex(gindexptr, error); |
130 | 161 | if (res != DW_DLV_OK) { |
131 | 0 | dwarf_dealloc_gdbindex(gindexptr); |
132 | 0 | return res; |
133 | 0 | } |
134 | | |
135 | 161 | res = examplex(gindexptr, error); |
136 | 161 | if (res != DW_DLV_OK) { |
137 | 131 | dwarf_dealloc_gdbindex(gindexptr); |
138 | 131 | return res; |
139 | 131 | } |
140 | | |
141 | 30 | dwarf_dealloc_gdbindex(gindexptr); |
142 | 30 | } |
143 | 30 | return DW_DLV_OK; |
144 | 161 | } |
145 | | |
146 | 161 | int examplewgdbindex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) { |
147 | 161 | Dwarf_Unsigned list_len = 0; |
148 | 161 | Dwarf_Unsigned i = 0; |
149 | 161 | int res = 0; |
150 | | |
151 | 161 | res = dwarf_gdbindex_addressarea(gdbindex, &list_len, error); |
152 | 161 | if (res != DW_DLV_OK) { |
153 | 0 | return res; |
154 | 0 | } |
155 | 72.9k | for (i = 0; i < list_len; i++) { |
156 | 72.7k | Dwarf_Unsigned lowpc = 0; |
157 | 72.7k | Dwarf_Unsigned highpc = 0; |
158 | 72.7k | Dwarf_Unsigned cu_index = 0; |
159 | 72.7k | res = dwarf_gdbindex_addressarea_entry(gdbindex, i, &lowpc, &highpc, |
160 | 72.7k | &cu_index, error); |
161 | 72.7k | if (res != DW_DLV_OK) { |
162 | 0 | return res; |
163 | 0 | } |
164 | 72.7k | } |
165 | 161 | return DW_DLV_OK; |
166 | 161 | } |
167 | | |
168 | 161 | int examplex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) { |
169 | 161 | Dwarf_Unsigned symtab_list_length = 0; |
170 | 161 | Dwarf_Unsigned i = 0; |
171 | 161 | int res = 0; |
172 | | |
173 | 161 | res = dwarf_gdbindex_symboltable_array(gdbindex, &symtab_list_length, error); |
174 | 161 | if (res != DW_DLV_OK) { |
175 | 0 | return res; |
176 | 0 | } |
177 | 1.08k | for (i = 0; i < symtab_list_length; i++) { |
178 | 1.05k | Dwarf_Unsigned symnameoffset = 0; |
179 | 1.05k | Dwarf_Unsigned cuvecoffset = 0; |
180 | 1.05k | Dwarf_Unsigned cuvec_len = 0; |
181 | 1.05k | Dwarf_Unsigned ii = 0; |
182 | 1.05k | const char *name = 0; |
183 | 1.05k | int resl = 0; |
184 | | |
185 | 1.05k | resl = dwarf_gdbindex_symboltable_entry(gdbindex, i, &symnameoffset, |
186 | 1.05k | &cuvecoffset, error); |
187 | 1.05k | if (resl != DW_DLV_OK) { |
188 | 0 | return resl; |
189 | 0 | } |
190 | 1.05k | resl = |
191 | 1.05k | dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset, &name, error); |
192 | 1.05k | if (resl != DW_DLV_OK) { |
193 | 91 | return resl; |
194 | 91 | } |
195 | 966 | resl = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset, &cuvec_len, |
196 | 966 | error); |
197 | 966 | if (resl != DW_DLV_OK) { |
198 | 20 | return resl; |
199 | 20 | } |
200 | 16.9k | for (ii = 0; ii < cuvec_len; ++ii) { |
201 | 16.0k | Dwarf_Unsigned attributes = 0; |
202 | 16.0k | Dwarf_Unsigned cu_index = 0; |
203 | 16.0k | Dwarf_Unsigned symbol_kind = 0; |
204 | 16.0k | Dwarf_Unsigned is_static = 0; |
205 | 16.0k | int res2 = 0; |
206 | | |
207 | 16.0k | res2 = dwarf_gdbindex_cuvector_inner_attributes(gdbindex, cuvecoffset, ii, |
208 | 16.0k | &attributes, error); |
209 | 16.0k | if (res2 != DW_DLV_OK) { |
210 | 20 | return res2; |
211 | 20 | } |
212 | 15.9k | res2 = dwarf_gdbindex_cuvector_instance_expand_value( |
213 | 15.9k | gdbindex, attributes, &cu_index, &symbol_kind, &is_static, error); |
214 | 15.9k | if (res2 != DW_DLV_OK) { |
215 | 0 | return res2; |
216 | 0 | } |
217 | 15.9k | } |
218 | 946 | } |
219 | 30 | return DW_DLV_OK; |
220 | 161 | } |