/src/binutils-gdb/binutils/fuzz_readelf.c
Line | Count | Source |
1 | | /* Copyright 2020 Google Inc. |
2 | | |
3 | | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | you may not use this file except in compliance with the License. |
5 | | You may obtain a copy of the License at |
6 | | |
7 | | http://www.apache.org/licenses/LICENSE-2.0 |
8 | | |
9 | | Unless required by applicable law or agreed to in writing, software |
10 | | distributed under the License is distributed on an "AS IS" BASIS, |
11 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | See the License for the specific language governing permissions and |
13 | | limitations under the License. |
14 | | */ |
15 | | |
16 | | /* |
17 | | * We convert readelf.c into a header file to make convenient for fuzzing. |
18 | | * We do this for several of the binutils applications when creating |
19 | | * the binutils fuzzers. |
20 | | */ |
21 | | #include "readelf.h" |
22 | | |
23 | | #include "bfd.h" |
24 | | #include "libbfd.h" |
25 | | |
26 | 139 | int check_architecture(char *tmpfilename, char *arch_string) { |
27 | 139 | bfd_cleanup cleanup = NULL; |
28 | 139 | bfd *file = bfd_openr(tmpfilename, arch_string); |
29 | 139 | if (file == NULL) { |
30 | 27 | remove(tmpfilename); |
31 | 27 | return 0; |
32 | 27 | } |
33 | | |
34 | 112 | if (!bfd_read_p(file) || |
35 | 112 | (unsigned int)file->format >= (unsigned int)bfd_type_end) { |
36 | 0 | bfd_close(file); |
37 | 0 | return 0; |
38 | 0 | } |
39 | | |
40 | 112 | bool doAnalysis = false; |
41 | 112 | if (bfd_seek(file, (file_ptr)0, SEEK_SET) == 0) { |
42 | 112 | file->format = bfd_object; |
43 | 112 | cleanup = BFD_SEND_FMT(file, _bfd_check_format, (file)); |
44 | 112 | if (cleanup) { |
45 | 0 | doAnalysis = true; |
46 | 0 | cleanup(file); |
47 | 0 | } |
48 | 112 | file->format = bfd_unknown; |
49 | 112 | } |
50 | | |
51 | 112 | if (file != NULL) { |
52 | 112 | bfd_close(file); |
53 | 112 | } |
54 | | |
55 | | // return 1 if the architecture matches. |
56 | 112 | if (doAnalysis) { |
57 | 0 | return 1; |
58 | 0 | } |
59 | 112 | return 0; |
60 | 112 | } |
61 | | |
62 | | // int gb=0; |
63 | | |
64 | | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); |
65 | 174 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
66 | 174 | if (size > 16384) |
67 | 35 | return 0; |
68 | 139 | char filename[256]; |
69 | 139 | sprintf(filename, "/tmp/libfuzzer.%d", getpid()); |
70 | | |
71 | 139 | FILE *fp = fopen(filename, "wb"); |
72 | 139 | if (!fp) |
73 | 0 | return 0; |
74 | | |
75 | | /* Code to quickly extract target list. |
76 | | * This is used to identify new targets but should |
77 | | * not be in the fuzz code. |
78 | | if (gb == 0) { |
79 | | char **doublel = bfd_target_list(); |
80 | | while (*doublel != NULL) { |
81 | | printf("Target: %s\n", *doublel); |
82 | | doublel++; |
83 | | } |
84 | | gb=1; |
85 | | } |
86 | | exit(0); |
87 | | */ |
88 | | |
89 | 139 | #ifdef READELF_TARGETED |
90 | 139 | if (check_architecture(filename, READELF_TARGETED) == 0) { |
91 | 139 | unlink(filename); |
92 | 139 | return 0; |
93 | 139 | } |
94 | 0 | #endif |
95 | | |
96 | 0 | fwrite(data, size, 1, fp); |
97 | 0 | fclose(fp); |
98 | 0 | do_syms = true; |
99 | 0 | do_reloc = true; |
100 | 0 | do_unwind = true; |
101 | 0 | do_dynamic = true; |
102 | 0 | do_header = true; |
103 | 0 | do_sections = true; |
104 | 0 | do_section_groups = true; |
105 | 0 | do_segments = true; |
106 | 0 | do_version = true; |
107 | 0 | do_histogram = true; |
108 | 0 | do_arch = true; |
109 | 0 | do_notes = true; |
110 | | |
111 | | // Enable DWARF analysis |
112 | | // We must call both dwarf_select_sections_by_letters and |
113 | | // dwarf_select_sections_all since dwarf_select_sections_all does not set |
114 | | // do_debug_lines |= FLAG_DEBUG_LINES_DECODED; |
115 | 0 | dwarf_select_sections_by_letters("L"); |
116 | 0 | dwarf_select_sections_all(); |
117 | | |
118 | | // Main fuzz entrypoint |
119 | 0 | process_file(filename); |
120 | |
|
121 | 0 | unlink(filename); |
122 | |
|
123 | 0 | free(dump_ctf_symtab_name); |
124 | 0 | dump_ctf_symtab_name = NULL; |
125 | 0 | free(dump_ctf_strtab_name); |
126 | 0 | dump_ctf_strtab_name = NULL; |
127 | 0 | free(dump_ctf_parent_name); |
128 | 0 | dump_ctf_parent_name = NULL; |
129 | |
|
130 | 0 | return 0; |
131 | 139 | } |