Coverage Report

Created: 2026-08-13 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libdwarf/fuzz/fuzz_gdbindex.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
29.9k
#define O_BINARY 0 /* So it does nothing in Linux/Unix */
22
#endif
23
24
/*
25
 * Libdwarf library callers can only use these headers.
26
 */
27
#include "dwarf.h"
28
#include "libdwarf.h"
29
30
int examplew(Dwarf_Debug dbg, Dwarf_Error *error);
31
int examplewgdbindex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error);
32
int examplex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error);
33
34
/*
35
 * A fuzzer that simulates a small part of the simplereader.c example.
36
 */
37
29.9k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38
29.9k
  char filename[256];
39
40
#ifdef DWREGRESSIONTEMP
41
  /*  Under msys2, the /tmp/ results in an open fail,
42
      so we discard the /tmp/ here */
43
  sprintf(filename, "junklibfuzzer.%d", getpid());
44
#else
45
29.9k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
46
29.9k
#endif
47
29.9k
  FILE *fp = fopen(filename, "wb");
48
29.9k
  if (!fp) {
49
0
    printf("FAIL libfuzzer cannot open temp as writeable %s\n",
50
0
        filename);
51
0
    return 0;
52
0
  }
53
29.9k
  fwrite(data, size, 1, fp);
54
29.9k
  fclose(fp);
55
56
29.9k
  Dwarf_Debug dbg = 0;
57
29.9k
  int res = DW_DLV_ERROR;
58
29.9k
  Dwarf_Error error = 0;
59
29.9k
  Dwarf_Handler errhand = 0;
60
29.9k
  Dwarf_Ptr errarg = 0;
61
29.9k
  int regtabrulecount = 0;
62
29.9k
  int curopt = 0;
63
64
29.9k
  int fd = open(filename, O_RDONLY | O_BINARY);
65
29.9k
  if (fd < 0) {
66
0
    exit(EXIT_FAILURE);
67
0
  }
68
69
29.9k
  res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error);
70
71
29.9k
  if (res != DW_DLV_OK) {
72
22.8k
    dwarf_dealloc_error(dbg, error);
73
22.8k
  } else {
74
7.15k
    examplew(dbg, &error);
75
7.15k
  }
76
77
29.9k
  dwarf_finish(dbg);
78
29.9k
  close(fd);
79
29.9k
  unlink(filename);
80
29.9k
  return 0;
81
29.9k
}
82
83
910
int examplew(Dwarf_Debug dbg, Dwarf_Error *error) {
84
910
  Dwarf_Gdbindex gindexptr = 0;
85
910
  Dwarf_Unsigned version = 0;
86
910
  Dwarf_Unsigned cu_list_offset = 0;
87
910
  Dwarf_Unsigned types_cu_list_offset = 0;
88
910
  Dwarf_Unsigned address_area_offset = 0;
89
910
  Dwarf_Unsigned symbol_table_offset = 0;
90
910
  Dwarf_Unsigned constant_pool_offset = 0;
91
910
  Dwarf_Unsigned section_size = 0;
92
910
  const char *section_name = 0;
93
910
  int res = 0;
94
95
910
  res = dwarf_gdbindex_header(dbg, &gindexptr, &version, &cu_list_offset,
96
910
                              &types_cu_list_offset, &address_area_offset,
97
910
                              &symbol_table_offset, &constant_pool_offset,
98
910
                              &section_size, &section_name, error);
99
910
  if (res != DW_DLV_OK) {
100
747
    return res;
101
747
  }
102
163
  {
103
163
    Dwarf_Unsigned length = 0;
104
163
    Dwarf_Unsigned typeslength = 0;
105
163
    Dwarf_Unsigned i = 0;
106
163
    res = dwarf_gdbindex_culist_array(gindexptr, &length, error);
107
163
    if (res != DW_DLV_OK) {
108
0
      dwarf_dealloc_gdbindex(gindexptr);
109
0
      return res;
110
0
    }
111
19.1k
    for (i = 0; i < length; ++i) {
112
18.9k
      Dwarf_Unsigned cuoffset = 0;
113
18.9k
      Dwarf_Unsigned culength = 0;
114
18.9k
      res = dwarf_gdbindex_culist_entry(gindexptr, i, &cuoffset, &culength,
115
18.9k
                                        error);
116
18.9k
      if (res != DW_DLV_OK) {
117
0
        return res;
118
0
      }
119
18.9k
    }
120
163
    res = dwarf_gdbindex_types_culist_array(gindexptr, &typeslength, error);
121
163
    if (res != DW_DLV_OK) {
122
0
      dwarf_dealloc_gdbindex(gindexptr);
123
0
      return res;
124
0
    }
125
19.1k
    for (i = 0; i < typeslength; ++i) {
126
19.0k
      Dwarf_Unsigned cuoffset = 0;
127
19.0k
      Dwarf_Unsigned tuoffset = 0;
128
19.0k
      Dwarf_Unsigned type_signature = 0;
129
19.0k
      res = dwarf_gdbindex_types_culist_entry(
130
19.0k
          gindexptr, i, &cuoffset, &tuoffset, &type_signature, error);
131
19.0k
      if (res != DW_DLV_OK) {
132
0
        dwarf_dealloc_gdbindex(gindexptr);
133
0
        return res;
134
0
      }
135
19.0k
    }
136
137
163
    res = examplewgdbindex(gindexptr, error);
138
163
    if (res != DW_DLV_OK) {
139
0
      dwarf_dealloc_gdbindex(gindexptr);
140
0
      return res;
141
0
    }
142
143
163
    res = examplex(gindexptr, error);
144
163
    if (res != DW_DLV_OK) {
145
130
      dwarf_dealloc_gdbindex(gindexptr);
146
130
      return res;
147
130
    }
148
149
33
    dwarf_dealloc_gdbindex(gindexptr);
150
33
  }
151
33
  return DW_DLV_OK;
152
163
}
153
154
163
int examplewgdbindex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) {
155
163
  Dwarf_Unsigned list_len = 0;
156
163
  Dwarf_Unsigned i = 0;
157
163
  int res = 0;
158
159
163
  res = dwarf_gdbindex_addressarea(gdbindex, &list_len, error);
160
163
  if (res != DW_DLV_OK) {
161
0
    return res;
162
0
  }
163
59.3k
  for (i = 0; i < list_len; i++) {
164
59.1k
    Dwarf_Unsigned lowpc = 0;
165
59.1k
    Dwarf_Unsigned highpc = 0;
166
59.1k
    Dwarf_Unsigned cu_index = 0;
167
59.1k
    res = dwarf_gdbindex_addressarea_entry(gdbindex, i, &lowpc, &highpc,
168
59.1k
                                           &cu_index, error);
169
59.1k
    if (res != DW_DLV_OK) {
170
0
      return res;
171
0
    }
172
59.1k
  }
173
163
  return DW_DLV_OK;
174
163
}
175
176
163
int examplex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) {
177
163
  Dwarf_Unsigned symtab_list_length = 0;
178
163
  Dwarf_Unsigned i = 0;
179
163
  int res = 0;
180
181
163
  res = dwarf_gdbindex_symboltable_array(gdbindex, &symtab_list_length, error);
182
163
  if (res != DW_DLV_OK) {
183
0
    return res;
184
0
  }
185
776
  for (i = 0; i < symtab_list_length; i++) {
186
743
    Dwarf_Unsigned symnameoffset = 0;
187
743
    Dwarf_Unsigned cuvecoffset = 0;
188
743
    Dwarf_Unsigned cuvec_len = 0;
189
743
    Dwarf_Unsigned ii = 0;
190
743
    const char *name = 0;
191
743
    int resl = 0;
192
193
743
    resl = dwarf_gdbindex_symboltable_entry(gdbindex, i, &symnameoffset,
194
743
                                            &cuvecoffset, error);
195
743
    if (resl != DW_DLV_OK) {
196
0
      return resl;
197
0
    }
198
743
    resl =
199
743
        dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset, &name, error);
200
743
    if (resl != DW_DLV_OK) {
201
81
      return resl;
202
81
    }
203
662
    resl = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset, &cuvec_len,
204
662
                                          error);
205
662
    if (resl != DW_DLV_OK) {
206
23
      return resl;
207
23
    }
208
66.2k
    for (ii = 0; ii < cuvec_len; ++ii) {
209
65.6k
      Dwarf_Unsigned attributes = 0;
210
65.6k
      Dwarf_Unsigned cu_index = 0;
211
65.6k
      Dwarf_Unsigned symbol_kind = 0;
212
65.6k
      Dwarf_Unsigned is_static = 0;
213
65.6k
      int res2 = 0;
214
215
65.6k
      res2 = dwarf_gdbindex_cuvector_inner_attributes(gdbindex, cuvecoffset, ii,
216
65.6k
                                                      &attributes, error);
217
65.6k
      if (res2 != DW_DLV_OK) {
218
26
        return res2;
219
26
      }
220
65.6k
      res2 = dwarf_gdbindex_cuvector_instance_expand_value(
221
65.6k
          gdbindex, attributes, &cu_index, &symbol_kind, &is_static, error);
222
65.6k
      if (res2 != DW_DLV_OK) {
223
0
        return res2;
224
0
      }
225
65.6k
    }
226
639
  }
227
33
  return DW_DLV_OK;
228
163
}