/src/libdwarf/fuzz/fuzz_dnames.c
Line | Count | Source |
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.50k | #define O_BINARY 0 /* So it does nothing in Linux/Unix */ |
22 | | #endif |
23 | | |
24 | | |
25 | | /* |
26 | | * Libdwarf library callers can only use these headers. |
27 | | */ |
28 | | #include "dwarf.h" |
29 | | #include "libdwarf.h" |
30 | | |
31 | | /* This now initializes local variables to zero |
32 | | rather than leaving them uninitialized. |
33 | | When uninitialized consistent behavior is |
34 | | unlikely, run-to-run. And |
35 | | crashes are likely. |
36 | | David Anderson 30 May 2023. |
37 | | */ |
38 | | /* |
39 | | * A fuzzer that simulates a small part of the simplereader.c example. |
40 | | */ |
41 | 8.50k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
42 | 8.50k | char filename[256]; |
43 | | #ifdef DWREGRESSIONTEMP |
44 | | /* Under msys2, the /tmp/ results in an open fail */ |
45 | | sprintf(filename, "junklibfuzzer.%d", getpid()); |
46 | | #else |
47 | 8.50k | sprintf(filename, "/tmp/libfuzzer.%d", getpid()); |
48 | 8.50k | #endif |
49 | 8.50k | FILE *fp = fopen(filename, "wb"); |
50 | 8.50k | if (!fp) { |
51 | 0 | printf("FAIL libfuzzer cannot open temp as writeable %s\n", |
52 | 0 | filename); |
53 | 0 | return 0; |
54 | 0 | } |
55 | 8.50k | fwrite(data, size, 1, fp); |
56 | 8.50k | fclose(fp); |
57 | | |
58 | 8.50k | Dwarf_Debug dbg = 0; |
59 | 8.50k | int res = DW_DLV_ERROR; |
60 | 8.50k | Dwarf_Error error = 0; |
61 | 8.50k | Dwarf_Handler errhand = 0; |
62 | 8.50k | Dwarf_Ptr errarg = 0; |
63 | 8.50k | int regtabrulecount = 0; |
64 | 8.50k | int curopt = 0; |
65 | | |
66 | 8.50k | int fd = open(filename, O_RDONLY | O_BINARY); |
67 | 8.50k | if (fd < 0) { |
68 | 0 | exit(EXIT_FAILURE); |
69 | 0 | } |
70 | | |
71 | 8.50k | res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error); |
72 | | |
73 | 8.50k | if (res != DW_DLV_OK) { |
74 | 6.95k | dwarf_dealloc_error(dbg, error); |
75 | 6.95k | } else { |
76 | | |
77 | 1.54k | Dwarf_Dnames_Head dnames_h = 0; |
78 | 1.54k | Dwarf_Off dw_offset_of_next_table = 0; |
79 | 1.54k | res = dwarf_dnames_header(dbg, 0, &dnames_h, &dw_offset_of_next_table, |
80 | 1.54k | &error); |
81 | | |
82 | 1.54k | if (res != DW_DLV_OK) { |
83 | 1.23k | dwarf_dealloc_dnames(dnames_h); |
84 | 1.23k | dwarf_finish(dbg); |
85 | 1.23k | close(fd); |
86 | 1.23k | unlink(filename); |
87 | 1.23k | return 0; |
88 | 1.23k | } |
89 | | |
90 | 305 | Dwarf_Unsigned dw_index = 1; |
91 | 305 | Dwarf_Unsigned dw_abbrev_offset = 0; |
92 | 305 | Dwarf_Unsigned dw_abbrev_code = 0; |
93 | 305 | Dwarf_Unsigned dw_abbrev_tag = 0; |
94 | 305 | Dwarf_Unsigned dw_array_size = 256; |
95 | | /* This test code originally passed in uninitialized |
96 | | pointers dw_idxattr_array and dw_form_array, which |
97 | | we cannot protect against. But we can check for NULL |
98 | | so now the variables are initialilized. |
99 | | In any case this code does not call the function correctly, |
100 | | but we leave that as written. David Anderson 30 May 2023 */ |
101 | 305 | Dwarf_Half *dw_idxattr_array = 0; |
102 | 305 | Dwarf_Half *dw_form_array = 0; |
103 | 305 | Dwarf_Unsigned dw_idxattr_count = 0; |
104 | | |
105 | 305 | res = dwarf_dnames_abbrevtable( |
106 | 305 | dnames_h, dw_index, &dw_abbrev_offset, &dw_abbrev_code, &dw_abbrev_tag, |
107 | 305 | dw_array_size, dw_idxattr_array, dw_form_array, &dw_idxattr_count); |
108 | 305 | if (res == DW_DLV_NO_ENTRY) { |
109 | 305 | } |
110 | | |
111 | 305 | Dwarf_Unsigned dw_comp_unit_count = 0; |
112 | 305 | Dwarf_Unsigned dw_local_type_unit_count = 0; |
113 | 305 | Dwarf_Unsigned dw_foreign_type_unit_count = 0; |
114 | 305 | Dwarf_Unsigned dw_bucket_count = 0; |
115 | 305 | Dwarf_Unsigned dw_name_count = 0; |
116 | 305 | Dwarf_Unsigned dw_abbrev_table_size = 0; |
117 | 305 | Dwarf_Unsigned dw_entry_pool_size = 0; |
118 | 305 | Dwarf_Unsigned dw_augmentation_string_size = 0; |
119 | 305 | char *dw_augmentation_string = 0; |
120 | 305 | Dwarf_Unsigned dw_section_size = 0; |
121 | 305 | Dwarf_Half dw_table_version = 0; |
122 | 305 | Dwarf_Half dw_offset_size = 0; |
123 | 305 | res = dwarf_dnames_sizes( |
124 | 305 | dnames_h, &dw_comp_unit_count, &dw_local_type_unit_count, |
125 | 305 | &dw_foreign_type_unit_count, &dw_bucket_count, &dw_name_count, |
126 | 305 | &dw_abbrev_table_size, &dw_entry_pool_size, |
127 | 305 | &dw_augmentation_string_size, &dw_augmentation_string, &dw_section_size, |
128 | 305 | &dw_table_version, &dw_offset_size, &error); |
129 | 305 | if (res != DW_DLV_OK) { |
130 | 0 | dwarf_dealloc_dnames(dnames_h); |
131 | 0 | dwarf_finish(dbg); |
132 | 0 | close(fd); |
133 | 0 | unlink(filename); |
134 | 0 | return 0; |
135 | 0 | } |
136 | | |
137 | 305 | Dwarf_Unsigned dw_header_offset = 0; |
138 | 305 | Dwarf_Unsigned dw_cu_table_offset = 0; |
139 | 305 | Dwarf_Unsigned dw_tu_local_offset = 0; |
140 | 305 | Dwarf_Unsigned dw_foreign_tu_offset = 0; |
141 | 305 | Dwarf_Unsigned dw_bucket_offset = 0; |
142 | 305 | Dwarf_Unsigned dw_hashes_offset = 0; |
143 | 305 | Dwarf_Unsigned dw_stringoffsets_offset = 0; |
144 | 305 | Dwarf_Unsigned dw_entryoffsets_offset = 0; |
145 | 305 | Dwarf_Unsigned dw_abbrev_table_offset = 0; |
146 | 305 | Dwarf_Unsigned dw_entry_pool_offset = 0; |
147 | 305 | res = dwarf_dnames_offsets( |
148 | 305 | dnames_h, &dw_header_offset, &dw_cu_table_offset, &dw_tu_local_offset, |
149 | 305 | &dw_foreign_tu_offset, &dw_bucket_offset, &dw_hashes_offset, |
150 | 305 | &dw_stringoffsets_offset, &dw_entryoffsets_offset, |
151 | 305 | &dw_abbrev_table_offset, &dw_entry_pool_offset, &error); |
152 | 305 | if (res != DW_DLV_OK) { |
153 | 0 | dwarf_dealloc_dnames(dnames_h); |
154 | 0 | dwarf_finish(dbg); |
155 | 0 | close(fd); |
156 | 0 | unlink(filename); |
157 | 0 | return 0; |
158 | 0 | } |
159 | | |
160 | 305 | Dwarf_Unsigned dw_offset = 0; |
161 | 305 | Dwarf_Sig8 dw_sig; |
162 | 305 | res = dwarf_dnames_cu_table(dnames_h, "cu", 0, &dw_offset, &dw_sig, &error); |
163 | 305 | if (res != DW_DLV_OK) { |
164 | 34 | dwarf_dealloc_dnames(dnames_h); |
165 | 34 | dwarf_finish(dbg); |
166 | 34 | close(fd); |
167 | 34 | unlink(filename); |
168 | 34 | return 0; |
169 | 34 | } |
170 | | |
171 | 271 | dw_index = 0; |
172 | 271 | Dwarf_Unsigned dw_indexcount; |
173 | 271 | res = dwarf_dnames_bucket(dnames_h, 0, &dw_index, &dw_indexcount, &error); |
174 | 271 | if (res != DW_DLV_OK) { |
175 | 1 | dwarf_dealloc_dnames(dnames_h); |
176 | 1 | dwarf_finish(dbg); |
177 | 1 | close(fd); |
178 | 1 | unlink(filename); |
179 | 1 | return 0; |
180 | 1 | } |
181 | | |
182 | 270 | Dwarf_Unsigned dw_bucket_number = 0; |
183 | 270 | Dwarf_Unsigned dw_hash_value = 0; |
184 | 270 | Dwarf_Unsigned dw_offset_to_debug_str = 0; |
185 | 270 | char *dw_ptrtostr = 0; |
186 | 270 | Dwarf_Unsigned dw_offset_in_entrypool = 0; |
187 | 270 | Dwarf_Unsigned dw_abbrev_number = 0; |
188 | 270 | Dwarf_Half abbrev_tg = 0; |
189 | 270 | dw_array_size = 10; |
190 | 270 | Dwarf_Half idxattr_array[10]; |
191 | 270 | Dwarf_Half form_array[10]; |
192 | 270 | res = dwarf_dnames_name( |
193 | 270 | dnames_h, 1, &dw_bucket_number, &dw_hash_value, &dw_offset_to_debug_str, |
194 | 270 | &dw_ptrtostr, &dw_offset_in_entrypool, &dw_abbrev_number, &abbrev_tg, |
195 | 270 | dw_array_size, idxattr_array, form_array, &dw_idxattr_count, &error); |
196 | 270 | if (res != DW_DLV_OK) { |
197 | 262 | dwarf_dealloc_dnames(dnames_h); |
198 | 262 | dwarf_finish(dbg); |
199 | 262 | close(fd); |
200 | 262 | unlink(filename); |
201 | 262 | return 0; |
202 | 262 | } |
203 | | |
204 | 8 | dwarf_dealloc_dnames(dnames_h); |
205 | 8 | } |
206 | | |
207 | 6.96k | dwarf_finish(dbg); |
208 | 6.96k | close(fd); |
209 | 6.96k | unlink(filename); |
210 | 6.96k | return 0; |
211 | 8.50k | } |