Coverage Report

Created: 2026-10-13 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/barebox/commands/fuzz.c
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-2.0 */
2
3
#define pr_fmt(fmt) "fuzz: " fmt
4
5
#include <common.h>
6
#include <command.h>
7
#include <getopt.h>
8
#include <fuzz.h>
9
#include <libfile.h>
10
#include <fs.h>
11
12
struct fuzz_process {
13
  bool print;
14
  const char *match;
15
  unsigned nmatches;
16
  const struct fuzz_test *test;
17
};
18
19
static int process_fuzz_test(const struct fuzz_test *test,
20
           void *_ctx)
21
0
{
22
0
  struct fuzz_process *ctx = _ctx;
23
24
0
  if (ctx->print) {
25
0
    printf("%s\n", test->name);
26
0
    ctx->nmatches++;
27
0
  }
28
29
0
  if (ctx->match && !strcmp(test->name, ctx->match)) {
30
0
    ctx->test = test;
31
0
    return true;
32
0
  }
33
34
0
  return false;
35
0
}
36
37
static const struct fuzz_test *get_fuzz_test(const char *match, bool print)
38
0
{
39
0
  struct fuzz_process ctx = {
40
0
    .match = match, .print = print
41
0
  };
42
43
0
  if (call_for_each_fuzz_test(process_fuzz_test, &ctx))
44
0
    return ctx.test;
45
46
0
  if (!ctx.nmatches) {
47
0
    if (match)
48
0
      printf("No fuzz tests matching '%s' found.\n", match);
49
0
    else
50
0
      printf("No fuzz tests registered.\n");
51
0
  }
52
53
0
  return NULL;
54
0
}
55
56
static int run_fuzz_test(const char *match, bool list, const u8 *buf, size_t len)
57
0
{
58
0
  const struct fuzz_test *test;
59
60
0
  test = get_fuzz_test(match, list);
61
0
  if (list)
62
0
    return 0;
63
0
  else if (!test)
64
0
    return COMMAND_ERROR;
65
66
0
  fuzz_test_setup(test);
67
68
0
  return fuzz_test_once(test, buf, len);
69
0
}
70
71
static int do_fuzz(int argc, char *argv[])
72
0
{
73
0
  const char *file = NULL;
74
0
  u64 max_size = FILESIZE_MAX;
75
0
  size_t size = 0;
76
0
  const u8 *buf = NULL;
77
0
  void *contents = NULL;
78
0
  bool list = false;
79
0
  int err = 0, opt;
80
81
0
  while((opt = getopt(argc, argv, "ls:f:")) > 0) {
82
0
    switch(opt) {
83
0
    case 'l':
84
0
      list = true;
85
0
      break;
86
0
    case 's':
87
0
      err = kstrtou64(optarg, 0, &max_size);
88
0
      if (err || max_size > SIZE_MAX) {
89
0
        printf("invalid max size\n");
90
0
        return COMMAND_ERROR;
91
0
      }
92
0
      break;
93
0
    case 'f':
94
0
      file = optarg;
95
0
      break;
96
0
    default:
97
0
      return COMMAND_ERROR_USAGE;
98
0
    }
99
0
  }
100
101
0
  argv += optind;
102
0
  argc -= optind;
103
104
0
  if ((list && argc) || (!list && argc != 1) || (!file && !list))
105
0
    return COMMAND_ERROR_USAGE;
106
107
0
  if (file) {
108
0
    err = read_file_2(file, &size, &contents, max_size);
109
0
    if (err && err != -EFBIG) {
110
0
      printf("error reading file: %m\n");
111
0
      return COMMAND_ERROR;
112
0
    }
113
114
0
    buf = contents;
115
0
  }
116
117
0
  err = run_fuzz_test(argv[0], list, buf, size);
118
119
0
  free(contents);
120
0
  return err;
121
0
}
122
123
BAREBOX_CMD_HELP_START(fuzz)
124
BAREBOX_CMD_HELP_TEXT("Run barebox fuzz test on fixed input")
125
BAREBOX_CMD_HELP_TEXT("")
126
BAREBOX_CMD_HELP_TEXT("Options:")
127
BAREBOX_CMD_HELP_OPT ("-l",      "list registered fuzz tests")
128
BAREBOX_CMD_HELP_OPT ("-f FILE", "use FILE as fuzz input")
129
BAREBOX_CMD_HELP_OPT ("-s SIZE", "read only SIZE bytes from file")
130
BAREBOX_CMD_HELP_END
131
132
BAREBOX_CMD_START(fuzz)
133
  .cmd    = do_fuzz,
134
  BAREBOX_CMD_DESC("Run fuzz test")
135
  BAREBOX_CMD_OPTS("[-ls] -f FILE [test]")
136
  BAREBOX_CMD_GROUP(CMD_GRP_MISC)
137
  BAREBOX_CMD_HELP(cmd_fuzz_help)
138
BAREBOX_CMD_END