Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/test/fuzz/fuzz_cmp_tool.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file fuzz_cmp_tool.c
3
 * @date 2025
4
 *
5
 * @copyright GPLv2
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms and conditions of the GNU General Public License,
8
 * version 2, as published by the Free Software Foundation.
9
 *
10
 * This program is distributed in the hope it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13
 * more details.
14
 *
15
 * @brief chunk compression fuzz target
16
 *
17
 * This fuzzer tests the compression functionality with random data/model and
18
 * parameters. It uses a random portion of the input data for parameter
19
 * generation, while the rest is used for compression.
20
 */
21
22
23
#include <stdint.h>
24
#include <limits.h>
25
#include <stdint.h>
26
#include <stdint.h>
27
#include <stddef.h>
28
#include <string.h>
29
30
#include "fuzz_helpers.h"
31
#include "fuzz_data_producer.h"
32
33
1.79k
#define MAX_ARG_COUNT  32
34
3.51k
#define MAX_ARG_SIZE  64
35
36
37
int testable_cmp_tool_main(int argc, char **argv);
38
39
40
static void add_argument_with_file(char **argv, int index, const char *flag, const char *file)
41
6.27k
{
42
6.27k
  if (index > 0) { /* zero is revert for program name */
43
6.01k
    size_t flag_len = strlen(flag);
44
6.01k
    size_t file_len = strlen(file);
45
46
6.01k
    FUZZ_ASSERT(flag_len + file_len < MAX_ARG_SIZE);
47
6.01k
    memcpy(argv[index], flag, flag_len);
48
6.01k
    memcpy(argv[index]+flag_len, file, file_len + 1);
49
6.01k
  }
50
6.27k
}
51
52
53
static int gen_argv(FUZZ_dataProducer_t *producer, char **argv, const char *data_file,
54
           const char *model_file, const char *cfg_file, const char *info_file,
55
           const uint8_t *other_arguments, size_t o_args_size)
56
1.75k
{
57
1.75k
  int argc = FUZZ_dataProducer_int32Range(producer, 1, MAX_ARG_COUNT);
58
1.75k
  int i, end;
59
60
  /* Add optional arguments no the end so they have higher priority */
61
1.75k
  end = argc-1;
62
  /* TODO: How to clean up written stuff by the cmp_tool? */
63
1.75k
  add_argument_with_file(argv, end--, "-o", FUZZ_TMP_DIR "/fuzz-output-cmp_tool");
64
1.75k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
65
1.55k
    add_argument_with_file(argv, end--, "-d", data_file);
66
1.75k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
67
848
    add_argument_with_file(argv, end--, "-m", model_file);
68
1.75k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
69
1.14k
    add_argument_with_file(argv, end--, "-c", cfg_file);
70
1.75k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
71
963
    add_argument_with_file(argv, end--, "-i", info_file);
72
73
5.24k
  for (i = 0; i < end; i++) {
74
3.48k
    size_t s = FUZZ_dataProducer_uint32Range(producer, 0, MAX_ARG_SIZE-1);
75
76
3.48k
    if (s > o_args_size)
77
866
      s = o_args_size;
78
3.48k
    memcpy(argv[i], other_arguments, s);
79
3.48k
    argv[i][s] = '\0';
80
3.48k
    other_arguments += s;
81
3.48k
    o_args_size -= s;
82
3.48k
  }
83
84
1.75k
  return argc;
85
1.75k
}
86
87
88
89
static char *get_file(FUZZ_dataProducer_t *producer, const uint8_t **src, uint32_t *size)
90
7.02k
{
91
7.02k
  uint32_t file_size = FUZZ_dataProducer_uint32Range(producer, 0, *size);
92
7.02k
  char *file = FUZZ_buf_to_file(*src, file_size);
93
7.02k
  *src += file_size;
94
7.02k
  *size -= file_size;
95
7.02k
  return file;
96
7.02k
}
97
98
99
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
100
1.75k
{
101
1.75k
  static char **argv;
102
  /*
103
   * Give a random portion of src data to the producer, to use for
104
   * parameter generation. The rest will be used for the file content and
105
   * arguments
106
   */
107
1.75k
  FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
108
1.75k
  uint32_t size32 = (uint32_t)FUZZ_dataProducer_reserveDataPrefix(producer);
109
1.75k
  const char *data_file = get_file(producer, &src, &size32);
110
1.75k
  const char *model_file = get_file(producer, &src, &size32);
111
1.75k
  const char *info_file = get_file(producer, &src, &size32);
112
1.75k
  const char *cfg_file = get_file(producer, &src, &size32);
113
1.75k
  const uint8_t *other_arguments = src;
114
115
1.75k
  int argc;
116
117
1.75k
  FUZZ_ASSERT(size < UINT32_MAX);
118
119
1.75k
  if (argv == NULL) {
120
1
    static const char program_name[] = "cmp_tool_fuzz";
121
1
    char *data;
122
1
    size_t i;
123
124
1
    argv = FUZZ_malloc(sizeof(*argv) * MAX_ARG_COUNT);
125
1
    data = FUZZ_malloc(sizeof(*data) * MAX_ARG_COUNT * MAX_ARG_SIZE);
126
1
    memset(data, 0, sizeof(*data) * MAX_ARG_COUNT * MAX_ARG_SIZE);
127
33
    for (i = 0; i < MAX_ARG_COUNT; i++)
128
32
      argv[i] = &data[i*MAX_ARG_SIZE];
129
130
1
    FUZZ_ASSERT(sizeof(program_name) <= MAX_ARG_SIZE);
131
1
    memcpy(argv[0], program_name, sizeof(program_name));
132
1
  }
133
134
0
  argc = gen_argv(producer, argv, data_file, model_file, cfg_file,
135
1.75k
      info_file, other_arguments, size32);
136
137
  /* for(int i = 1; i < argc; i++) */
138
  /*  printf("%s\n", argv[i]); */
139
140
1.75k
  testable_cmp_tool_main(argc, argv);
141
142
1.75k
  FUZZ_delete_file(data_file);
143
1.75k
  FUZZ_delete_file(model_file);
144
1.75k
  FUZZ_delete_file(info_file);
145
1.75k
  FUZZ_delete_file(cfg_file);
146
147
1.75k
  FUZZ_dataProducer_free(producer);
148
149
1.75k
  return 0;
150
1.75k
}