Coverage Report

Created: 2025-07-18 06:39

/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.32k
#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.32k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
42
9.32k
  char filename[256];
43
9.32k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
44
45
9.32k
  FILE *fp = fopen(filename, "wb");
46
9.32k
  if (!fp) {
47
0
    return 0;
48
0
  }
49
9.32k
  fwrite(data, size, 1, fp);
50
9.32k
  fclose(fp);
51
52
9.32k
  Dwarf_Debug dbg = 0;
53
9.32k
  int res = DW_DLV_ERROR;
54
9.32k
  Dwarf_Error error = 0;
55
9.32k
  Dwarf_Handler errhand = 0;
56
9.32k
  Dwarf_Ptr errarg = 0;
57
9.32k
  int regtabrulecount = 0;
58
9.32k
  int curopt = 0;
59
60
9.32k
  int fd = open(filename, O_RDONLY | O_BINARY);
61
9.32k
  if (fd < 0) {
62
0
    exit(EXIT_FAILURE);
63
0
  }
64
65
9.32k
  res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error);
66
67
9.32k
  if (res != DW_DLV_OK) {
68
7.57k
    dwarf_dealloc_error(dbg, error);
69
7.57k
  } else {
70
71
1.75k
    Dwarf_Dnames_Head dnames_h = 0;
72
1.75k
    Dwarf_Off dw_offset_of_next_table = 0;
73
1.75k
    res = dwarf_dnames_header(dbg, 0, &dnames_h, &dw_offset_of_next_table,
74
1.75k
                              &error);
75
76
1.75k
    if (res != DW_DLV_OK) {
77
1.35k
      dwarf_dealloc_dnames(dnames_h);
78
1.35k
      dwarf_finish(dbg);
79
1.35k
      close(fd);
80
1.35k
      unlink(filename);
81
1.35k
      return 0;
82
1.35k
    }
83
84
395
    Dwarf_Unsigned dw_index = 1;
85
395
    Dwarf_Unsigned dw_abbrev_offset = 0;
86
395
    Dwarf_Unsigned dw_abbrev_code = 0;
87
395
    Dwarf_Unsigned dw_abbrev_tag = 0;
88
395
    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
395
    Dwarf_Half *dw_idxattr_array = 0;
96
395
    Dwarf_Half *dw_form_array = 0;
97
395
    Dwarf_Unsigned dw_idxattr_count = 0;
98
99
395
    res = dwarf_dnames_abbrevtable(
100
395
        dnames_h, dw_index, &dw_abbrev_offset, &dw_abbrev_code, &dw_abbrev_tag,
101
395
        dw_array_size, dw_idxattr_array, dw_form_array, &dw_idxattr_count);
102
395
    if (res == DW_DLV_NO_ENTRY) {
103
395
    }
104
105
395
    Dwarf_Unsigned dw_comp_unit_count = 0;
106
395
    Dwarf_Unsigned dw_local_type_unit_count = 0;
107
395
    Dwarf_Unsigned dw_foreign_type_unit_count = 0;
108
395
    Dwarf_Unsigned dw_bucket_count = 0;
109
395
    Dwarf_Unsigned dw_name_count = 0;
110
395
    Dwarf_Unsigned dw_abbrev_table_size = 0;
111
395
    Dwarf_Unsigned dw_entry_pool_size = 0;
112
395
    Dwarf_Unsigned dw_augmentation_string_size = 0;
113
395
    char *dw_augmentation_string = 0;
114
395
    Dwarf_Unsigned dw_section_size = 0;
115
395
    Dwarf_Half dw_table_version = 0;
116
395
    Dwarf_Half dw_offset_size = 0;
117
395
    res = dwarf_dnames_sizes(
118
395
        dnames_h, &dw_comp_unit_count, &dw_local_type_unit_count,
119
395
        &dw_foreign_type_unit_count, &dw_bucket_count, &dw_name_count,
120
395
        &dw_abbrev_table_size, &dw_entry_pool_size,
121
395
        &dw_augmentation_string_size, &dw_augmentation_string, &dw_section_size,
122
395
        &dw_table_version, &dw_offset_size, &error);
123
395
    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
395
    Dwarf_Unsigned dw_header_offset = 0;
132
395
    Dwarf_Unsigned dw_cu_table_offset = 0;
133
395
    Dwarf_Unsigned dw_tu_local_offset = 0;
134
395
    Dwarf_Unsigned dw_foreign_tu_offset = 0;
135
395
    Dwarf_Unsigned dw_bucket_offset = 0;
136
395
    Dwarf_Unsigned dw_hashes_offset = 0;
137
395
    Dwarf_Unsigned dw_stringoffsets_offset = 0;
138
395
    Dwarf_Unsigned dw_entryoffsets_offset = 0;
139
395
    Dwarf_Unsigned dw_abbrev_table_offset = 0;
140
395
    Dwarf_Unsigned dw_entry_pool_offset = 0;
141
395
    res = dwarf_dnames_offsets(
142
395
        dnames_h, &dw_header_offset, &dw_cu_table_offset, &dw_tu_local_offset,
143
395
        &dw_foreign_tu_offset, &dw_bucket_offset, &dw_hashes_offset,
144
395
        &dw_stringoffsets_offset, &dw_entryoffsets_offset,
145
395
        &dw_abbrev_table_offset, &dw_entry_pool_offset, &error);
146
395
    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
395
    Dwarf_Unsigned dw_offset = 0;
155
395
    Dwarf_Sig8 dw_sig;
156
395
    res = dwarf_dnames_cu_table(dnames_h, "cu", 0, &dw_offset, &dw_sig, &error);
157
395
    if (res != DW_DLV_OK) {
158
32
      dwarf_dealloc_dnames(dnames_h);
159
32
      dwarf_finish(dbg);
160
32
      close(fd);
161
32
      unlink(filename);
162
32
      return 0;
163
32
    }
164
165
363
    dw_index = 0;
166
363
    Dwarf_Unsigned dw_indexcount;
167
363
    res = dwarf_dnames_bucket(dnames_h, 0, &dw_index, &dw_indexcount, &error);
168
363
    if (res != DW_DLV_OK) {
169
3
      dwarf_dealloc_dnames(dnames_h);
170
3
      dwarf_finish(dbg);
171
3
      close(fd);
172
3
      unlink(filename);
173
3
      return 0;
174
3
    }
175
176
360
    Dwarf_Unsigned dw_bucket_number = 0;
177
360
    Dwarf_Unsigned dw_hash_value = 0;
178
360
    Dwarf_Unsigned dw_offset_to_debug_str = 0;
179
360
    char *dw_ptrtostr = 0;
180
360
    Dwarf_Unsigned dw_offset_in_entrypool = 0;
181
360
    Dwarf_Unsigned dw_abbrev_number = 0;
182
360
    Dwarf_Half abbrev_tg = 0;
183
360
    dw_array_size = 10;
184
360
    Dwarf_Half idxattr_array[10];
185
360
    Dwarf_Half form_array[10];
186
360
    res = dwarf_dnames_name(
187
360
        dnames_h, 1, &dw_bucket_number, &dw_hash_value, &dw_offset_to_debug_str,
188
360
        &dw_ptrtostr, &dw_offset_in_entrypool, &dw_abbrev_number, &abbrev_tg,
189
360
        dw_array_size, idxattr_array, form_array, &dw_idxattr_count, &error);
190
360
    if (res != DW_DLV_OK) {
191
350
      dwarf_dealloc_dnames(dnames_h);
192
350
      dwarf_finish(dbg);
193
350
      close(fd);
194
350
      unlink(filename);
195
350
      return 0;
196
350
    }
197
198
10
    dwarf_dealloc_dnames(dnames_h);
199
10
  }
200
201
7.58k
  dwarf_finish(dbg);
202
7.58k
  close(fd);
203
7.58k
  unlink(filename);
204
7.58k
  return 0;
205
9.32k
}