Coverage Report

Created: 2026-05-11 07:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/fuzz/fuzz_bfd_ext.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
13
14
/*
15
 * This is an example fuzzer targeted a given architecture. The point of this is
16
 * that the general fuzz_bfd fuzzer has too large reacability which makes it
17
 * difficult to reach the entire codebase in practice. The goal is to create
18
 * more targeted fuzzers that are more likely to explore a given code area.
19
 *
20
 */
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libbfd.h"
24
25
#include <stdint.h>
26
#include <stdio.h>
27
#include <unistd.h>
28
29
590
static int bufferToFile(char *name, const uint8_t *Data, size_t Size) {
30
590
  int fd = mkstemp(name);
31
590
  if (fd < 0) {
32
0
    printf("failed mkstemp, errno=%d\n", errno);
33
0
    return -2;
34
0
  }
35
590
  if (write(fd, Data, Size) != Size) {
36
0
    printf("failed write, errno=%d\n", errno);
37
0
    close(fd);
38
0
    return -3;
39
0
  }
40
590
  close(fd);
41
590
  return 0;
42
590
}
43
44
597
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
45
597
  if (Size > 16384)
46
7
    return 0;
47
590
  char tmpfilename[32];
48
49
590
  if (bfd_init() != BFD_INIT_MAGIC)
50
0
    abort();
51
52
  /*
53
      char **names = bfd_target_list();
54
      while (*names != NULL) {
55
        printf("Name: %s\n", *names);
56
        names++;
57
      }
58
  */
59
60
590
  bfd_cleanup cleanup = NULL;
61
62
590
  strncpy(tmpfilename, "/tmp/fuzz.bfd-XXXXXX", 31);
63
590
  if (bufferToFile(tmpfilename, Data, Size) < 0) {
64
0
    return 0;
65
0
  }
66
  // bfd *file = bfd_openr (tmpfilename, "elf32-frv");
67
590
  bfd *file = bfd_openr(tmpfilename, "pef");
68
590
  if (file == NULL) {
69
0
    remove(tmpfilename);
70
0
    return 0;
71
0
  }
72
73
590
  if (!bfd_read_p(file) ||
74
590
      (unsigned int)file->format >= (unsigned int)bfd_type_end) {
75
0
    bfd_close(file);
76
0
    return 0;
77
0
  }
78
79
590
  bool doAnalysis = false;
80
590
  if (bfd_seek(file, (file_ptr)0, SEEK_SET) == 0) {
81
590
    file->format = bfd_object;
82
590
    cleanup = BFD_SEND_FMT(file, _bfd_check_format, (file));
83
590
    if (cleanup) {
84
37
      doAnalysis = true;
85
37
      cleanup(file);
86
37
    }
87
590
    file->format = bfd_unknown;
88
590
  }
89
90
590
  if (file != NULL) {
91
590
    bfd_close(file);
92
590
  }
93
94
590
  if (doAnalysis) {
95
    // We have a file with the target data we want.
96
    // Let's open as a write file this time, which should trigger
97
    // more actions on the code when calling bfd_close.
98
    // TODO: do more processing on this, e.g. use the file as
99
    // input to some of the other utilities.
100
37
    bfd *wFile = bfd_openw(tmpfilename, "pef");
101
37
    if (file != NULL) {
102
37
      bfd_close(wFile);
103
37
    }
104
37
  }
105
106
590
  remove(tmpfilename);
107
590
  return 0;
108
590
}