Coverage Report

Created: 2025-08-03 06:26

/src/libdwarf/fuzz/fuzz_dnames.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
9.28k
#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
9.28k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
42
9.28k
  char filename[256];
43
9.28k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
44
45
9.28k
  FILE *fp = fopen(filename, "wb");
46
9.28k
  if (!fp) {
47
0
    return 0;
48
0
  }
49
9.28k
  fwrite(data, size, 1, fp);
50
9.28k
  fclose(fp);
51
52
9.28k
  Dwarf_Debug dbg = 0;
53
9.28k
  int res = DW_DLV_ERROR;
54
9.28k
  Dwarf_Error error = 0;
55
9.28k
  Dwarf_Handler errhand = 0;
56
9.28k
  Dwarf_Ptr errarg = 0;
57
9.28k
  int regtabrulecount = 0;
58
9.28k
  int curopt = 0;
59
60
9.28k
  int fd = open(filename, O_RDONLY | O_BINARY);
61
9.28k
  if (fd < 0) {
62
0
    exit(EXIT_FAILURE);
63
0
  }
64
65
9.28k
  res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error);
66
67
9.28k
  if (res != DW_DLV_OK) {
68
7.45k
    dwarf_dealloc_error(dbg, error);
69
7.45k
  } else {
70
71
1.82k
    Dwarf_Dnames_Head dnames_h = 0;
72
1.82k
    Dwarf_Off dw_offset_of_next_table = 0;
73
1.82k
    res = dwarf_dnames_header(dbg, 0, &dnames_h, &dw_offset_of_next_table,
74
1.82k
                              &error);
75
76
1.82k
    if (res != DW_DLV_OK) {
77
1.42k
      dwarf_dealloc_dnames(dnames_h);
78
1.42k
      dwarf_finish(dbg);
79
1.42k
      close(fd);
80
1.42k
      unlink(filename);
81
1.42k
      return 0;
82
1.42k
    }
83
84
396
    Dwarf_Unsigned dw_index = 1;
85
396
    Dwarf_Unsigned dw_abbrev_offset = 0;
86
396
    Dwarf_Unsigned dw_abbrev_code = 0;
87
396
    Dwarf_Unsigned dw_abbrev_tag = 0;
88
396
    Dwarf_Unsigned dw_array_size = 256;
89
    /*  This test code originally passed in uninitialized
90
        pointers dw_idxattr_array and dw_form_array, which
91
        we cannot protect against. But we can check for NULL
92
        so now the variables are initialilized.
93
        In any case this code does not call the function correctly,
94
        but we leave that as written. David Anderson 30 May 2023 */
95
396
    Dwarf_Half *dw_idxattr_array = 0;
96
396
    Dwarf_Half *dw_form_array = 0;
97
396
    Dwarf_Unsigned dw_idxattr_count = 0;
98
99
396
    res = dwarf_dnames_abbrevtable(
100
396
        dnames_h, dw_index, &dw_abbrev_offset, &dw_abbrev_code, &dw_abbrev_tag,
101
396
        dw_array_size, dw_idxattr_array, dw_form_array, &dw_idxattr_count);
102
396
    if (res == DW_DLV_NO_ENTRY) {
103
396
    }
104
105
396
    Dwarf_Unsigned dw_comp_unit_count = 0;
106
396
    Dwarf_Unsigned dw_local_type_unit_count = 0;
107
396
    Dwarf_Unsigned dw_foreign_type_unit_count = 0;
108
396
    Dwarf_Unsigned dw_bucket_count = 0;
109
396
    Dwarf_Unsigned dw_name_count = 0;
110
396
    Dwarf_Unsigned dw_abbrev_table_size = 0;
111
396
    Dwarf_Unsigned dw_entry_pool_size = 0;
112
396
    Dwarf_Unsigned dw_augmentation_string_size = 0;
113
396
    char *dw_augmentation_string = 0;
114
396
    Dwarf_Unsigned dw_section_size = 0;
115
396
    Dwarf_Half dw_table_version = 0;
116
396
    Dwarf_Half dw_offset_size = 0;
117
396
    res = dwarf_dnames_sizes(
118
396
        dnames_h, &dw_comp_unit_count, &dw_local_type_unit_count,
119
396
        &dw_foreign_type_unit_count, &dw_bucket_count, &dw_name_count,
120
396
        &dw_abbrev_table_size, &dw_entry_pool_size,
121
396
        &dw_augmentation_string_size, &dw_augmentation_string, &dw_section_size,
122
396
        &dw_table_version, &dw_offset_size, &error);
123
396
    if (res != DW_DLV_OK) {
124
0
      dwarf_dealloc_dnames(dnames_h);
125
0
      dwarf_finish(dbg);
126
0
      close(fd);
127
0
      unlink(filename);
128
0
      return 0;
129
0
    }
130
131
396
    Dwarf_Unsigned dw_header_offset = 0;
132
396
    Dwarf_Unsigned dw_cu_table_offset = 0;
133
396
    Dwarf_Unsigned dw_tu_local_offset = 0;
134
396
    Dwarf_Unsigned dw_foreign_tu_offset = 0;
135
396
    Dwarf_Unsigned dw_bucket_offset = 0;
136
396
    Dwarf_Unsigned dw_hashes_offset = 0;
137
396
    Dwarf_Unsigned dw_stringoffsets_offset = 0;
138
396
    Dwarf_Unsigned dw_entryoffsets_offset = 0;
139
396
    Dwarf_Unsigned dw_abbrev_table_offset = 0;
140
396
    Dwarf_Unsigned dw_entry_pool_offset = 0;
141
396
    res = dwarf_dnames_offsets(
142
396
        dnames_h, &dw_header_offset, &dw_cu_table_offset, &dw_tu_local_offset,
143
396
        &dw_foreign_tu_offset, &dw_bucket_offset, &dw_hashes_offset,
144
396
        &dw_stringoffsets_offset, &dw_entryoffsets_offset,
145
396
        &dw_abbrev_table_offset, &dw_entry_pool_offset, &error);
146
396
    if (res != DW_DLV_OK) {
147
0
      dwarf_dealloc_dnames(dnames_h);
148
0
      dwarf_finish(dbg);
149
0
      close(fd);
150
0
      unlink(filename);
151
0
      return 0;
152
0
    }
153
154
396
    Dwarf_Unsigned dw_offset = 0;
155
396
    Dwarf_Sig8 dw_sig;
156
396
    res = dwarf_dnames_cu_table(dnames_h, "cu", 0, &dw_offset, &dw_sig, &error);
157
396
    if (res != DW_DLV_OK) {
158
39
      dwarf_dealloc_dnames(dnames_h);
159
39
      dwarf_finish(dbg);
160
39
      close(fd);
161
39
      unlink(filename);
162
39
      return 0;
163
39
    }
164
165
357
    dw_index = 0;
166
357
    Dwarf_Unsigned dw_indexcount;
167
357
    res = dwarf_dnames_bucket(dnames_h, 0, &dw_index, &dw_indexcount, &error);
168
357
    if (res != DW_DLV_OK) {
169
5
      dwarf_dealloc_dnames(dnames_h);
170
5
      dwarf_finish(dbg);
171
5
      close(fd);
172
5
      unlink(filename);
173
5
      return 0;
174
5
    }
175
176
352
    Dwarf_Unsigned dw_bucket_number = 0;
177
352
    Dwarf_Unsigned dw_hash_value = 0;
178
352
    Dwarf_Unsigned dw_offset_to_debug_str = 0;
179
352
    char *dw_ptrtostr = 0;
180
352
    Dwarf_Unsigned dw_offset_in_entrypool = 0;
181
352
    Dwarf_Unsigned dw_abbrev_number = 0;
182
352
    Dwarf_Half abbrev_tg = 0;
183
352
    dw_array_size = 10;
184
352
    Dwarf_Half idxattr_array[10];
185
352
    Dwarf_Half form_array[10];
186
352
    res = dwarf_dnames_name(
187
352
        dnames_h, 1, &dw_bucket_number, &dw_hash_value, &dw_offset_to_debug_str,
188
352
        &dw_ptrtostr, &dw_offset_in_entrypool, &dw_abbrev_number, &abbrev_tg,
189
352
        dw_array_size, idxattr_array, form_array, &dw_idxattr_count, &error);
190
352
    if (res != DW_DLV_OK) {
191
342
      dwarf_dealloc_dnames(dnames_h);
192
342
      dwarf_finish(dbg);
193
342
      close(fd);
194
342
      unlink(filename);
195
342
      return 0;
196
342
    }
197
198
10
    dwarf_dealloc_dnames(dnames_h);
199
10
  }
200
201
7.46k
  dwarf_finish(dbg);
202
7.46k
  close(fd);
203
7.46k
  unlink(filename);
204
7.46k
  return 0;
205
9.28k
}