Coverage Report

Created: 2026-01-09 06:49

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
8.44k
#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
8.44k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38
8.44k
  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
8.44k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
46
8.44k
#endif
47
8.44k
  FILE *fp = fopen(filename, "wb");
48
8.44k
  if (!fp) {
49
0
    printf("FAIL libfuzzer cannot open temp as writeable %s\n",
50
0
        filename);
51
0
    return 0;
52
0
  }
53
8.44k
  fwrite(data, size, 1, fp);
54
8.44k
  fclose(fp);
55
56
8.44k
  Dwarf_Debug dbg = 0;
57
8.44k
  int res = DW_DLV_ERROR;
58
8.44k
  Dwarf_Error error = 0;
59
8.44k
  Dwarf_Handler errhand = 0;
60
8.44k
  Dwarf_Ptr errarg = 0;
61
8.44k
  int regtabrulecount = 0;
62
8.44k
  int curopt = 0;
63
64
8.44k
  int fd = open(filename, O_RDONLY | O_BINARY);
65
8.44k
  if (fd < 0) {
66
0
    exit(EXIT_FAILURE);
67
0
  }
68
69
8.44k
  res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, &error);
70
71
8.44k
  if (res != DW_DLV_OK) {
72
7.61k
    dwarf_dealloc_error(dbg, error);
73
7.61k
  } else {
74
825
    examplew(dbg, &error);
75
825
  }
76
77
8.44k
  dwarf_finish(dbg);
78
8.44k
  close(fd);
79
8.44k
  unlink(filename);
80
8.44k
  return 0;
81
8.44k
}
82
83
825
int examplew(Dwarf_Debug dbg, Dwarf_Error *error) {
84
825
  Dwarf_Gdbindex gindexptr = 0;
85
825
  Dwarf_Unsigned version = 0;
86
825
  Dwarf_Unsigned cu_list_offset = 0;
87
825
  Dwarf_Unsigned types_cu_list_offset = 0;
88
825
  Dwarf_Unsigned address_area_offset = 0;
89
825
  Dwarf_Unsigned symbol_table_offset = 0;
90
825
  Dwarf_Unsigned constant_pool_offset = 0;
91
825
  Dwarf_Unsigned section_size = 0;
92
825
  const char *section_name = 0;
93
825
  int res = 0;
94
95
825
  res = dwarf_gdbindex_header(dbg, &gindexptr, &version, &cu_list_offset,
96
825
                              &types_cu_list_offset, &address_area_offset,
97
825
                              &symbol_table_offset, &constant_pool_offset,
98
825
                              &section_size, &section_name, error);
99
825
  if (res != DW_DLV_OK) {
100
661
    return res;
101
661
  }
102
164
  {
103
164
    Dwarf_Unsigned length = 0;
104
164
    Dwarf_Unsigned typeslength = 0;
105
164
    Dwarf_Unsigned i = 0;
106
164
    res = dwarf_gdbindex_culist_array(gindexptr, &length, error);
107
164
    if (res != DW_DLV_OK) {
108
0
      dwarf_dealloc_gdbindex(gindexptr);
109
0
      return res;
110
0
    }
111
17.4k
    for (i = 0; i < length; ++i) {
112
17.3k
      Dwarf_Unsigned cuoffset = 0;
113
17.3k
      Dwarf_Unsigned culength = 0;
114
17.3k
      res = dwarf_gdbindex_culist_entry(gindexptr, i, &cuoffset, &culength,
115
17.3k
                                        error);
116
17.3k
      if (res != DW_DLV_OK) {
117
0
        return res;
118
0
      }
119
17.3k
    }
120
164
    res = dwarf_gdbindex_types_culist_array(gindexptr, &typeslength, error);
121
164
    if (res != DW_DLV_OK) {
122
0
      dwarf_dealloc_gdbindex(gindexptr);
123
0
      return res;
124
0
    }
125
23.8k
    for (i = 0; i < typeslength; ++i) {
126
23.7k
      Dwarf_Unsigned cuoffset = 0;
127
23.7k
      Dwarf_Unsigned tuoffset = 0;
128
23.7k
      Dwarf_Unsigned type_signature = 0;
129
23.7k
      res = dwarf_gdbindex_types_culist_entry(
130
23.7k
          gindexptr, i, &cuoffset, &tuoffset, &type_signature, error);
131
23.7k
      if (res != DW_DLV_OK) {
132
0
        dwarf_dealloc_gdbindex(gindexptr);
133
0
        return res;
134
0
      }
135
23.7k
    }
136
137
164
    res = examplewgdbindex(gindexptr, error);
138
164
    if (res != DW_DLV_OK) {
139
0
      dwarf_dealloc_gdbindex(gindexptr);
140
0
      return res;
141
0
    }
142
143
164
    res = examplex(gindexptr, error);
144
164
    if (res != DW_DLV_OK) {
145
130
      dwarf_dealloc_gdbindex(gindexptr);
146
130
      return res;
147
130
    }
148
149
34
    dwarf_dealloc_gdbindex(gindexptr);
150
34
  }
151
34
  return DW_DLV_OK;
152
164
}
153
154
164
int examplewgdbindex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) {
155
164
  Dwarf_Unsigned list_len = 0;
156
164
  Dwarf_Unsigned i = 0;
157
164
  int res = 0;
158
159
164
  res = dwarf_gdbindex_addressarea(gdbindex, &list_len, error);
160
164
  if (res != DW_DLV_OK) {
161
0
    return res;
162
0
  }
163
71.4k
  for (i = 0; i < list_len; i++) {
164
71.2k
    Dwarf_Unsigned lowpc = 0;
165
71.2k
    Dwarf_Unsigned highpc = 0;
166
71.2k
    Dwarf_Unsigned cu_index = 0;
167
71.2k
    res = dwarf_gdbindex_addressarea_entry(gdbindex, i, &lowpc, &highpc,
168
71.2k
                                           &cu_index, error);
169
71.2k
    if (res != DW_DLV_OK) {
170
0
      return res;
171
0
    }
172
71.2k
  }
173
164
  return DW_DLV_OK;
174
164
}
175
176
164
int examplex(Dwarf_Gdbindex gdbindex, Dwarf_Error *error) {
177
164
  Dwarf_Unsigned symtab_list_length = 0;
178
164
  Dwarf_Unsigned i = 0;
179
164
  int res = 0;
180
181
164
  res = dwarf_gdbindex_symboltable_array(gdbindex, &symtab_list_length, error);
182
164
  if (res != DW_DLV_OK) {
183
0
    return res;
184
0
  }
185
671
  for (i = 0; i < symtab_list_length; i++) {
186
637
    Dwarf_Unsigned symnameoffset = 0;
187
637
    Dwarf_Unsigned cuvecoffset = 0;
188
637
    Dwarf_Unsigned cuvec_len = 0;
189
637
    Dwarf_Unsigned ii = 0;
190
637
    const char *name = 0;
191
637
    int resl = 0;
192
193
637
    resl = dwarf_gdbindex_symboltable_entry(gdbindex, i, &symnameoffset,
194
637
                                            &cuvecoffset, error);
195
637
    if (resl != DW_DLV_OK) {
196
0
      return resl;
197
0
    }
198
637
    resl =
199
637
        dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset, &name, error);
200
637
    if (resl != DW_DLV_OK) {
201
92
      return resl;
202
92
    }
203
545
    resl = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset, &cuvec_len,
204
545
                                          error);
205
545
    if (resl != DW_DLV_OK) {
206
17
      return resl;
207
17
    }
208
74.2k
    for (ii = 0; ii < cuvec_len; ++ii) {
209
73.6k
      Dwarf_Unsigned attributes = 0;
210
73.6k
      Dwarf_Unsigned cu_index = 0;
211
73.6k
      Dwarf_Unsigned symbol_kind = 0;
212
73.6k
      Dwarf_Unsigned is_static = 0;
213
73.6k
      int res2 = 0;
214
215
73.6k
      res2 = dwarf_gdbindex_cuvector_inner_attributes(gdbindex, cuvecoffset, ii,
216
73.6k
                                                      &attributes, error);
217
73.6k
      if (res2 != DW_DLV_OK) {
218
21
        return res2;
219
21
      }
220
73.6k
      res2 = dwarf_gdbindex_cuvector_instance_expand_value(
221
73.6k
          gdbindex, attributes, &cu_index, &symbol_kind, &is_static, error);
222
73.6k
      if (res2 != DW_DLV_OK) {
223
0
        return res2;
224
0
      }
225
73.6k
    }
226
528
  }
227
34
  return DW_DLV_OK;
228
164
}