Coverage Report

Created: 2025-07-23 06:45

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