Coverage Report

Created: 2025-11-09 06:48

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