Coverage Report

Created: 2025-10-10 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}