Coverage Report

Created: 2024-01-13 07:07

/src/ndpi/fuzz/fuzz_config.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "ndpi_api.h"
2
#include "ndpi_private.h"
3
#include "ndpi_classify.h"
4
#include "fuzz_common_code.h"
5
6
#include <stdint.h>
7
#include <stdio.h>
8
#include <assert.h>
9
#include "fuzzer/FuzzedDataProvider.h"
10
11
6.05k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
12
6.05k
  FuzzedDataProvider fuzzed_data(data, size);
13
6.05k
  struct ndpi_detection_module_struct *ndpi_info_mod;
14
6.05k
  struct ndpi_flow_struct flow;
15
6.05k
  u_int8_t protocol_was_guessed;
16
6.05k
  u_int32_t i, num;
17
6.05k
  u_int16_t random_proto, bool_value;
18
6.05k
  int random_value;
19
6.05k
  NDPI_PROTOCOL_BITMASK enabled_bitmask;
20
6.05k
  struct ndpi_lru_cache_stats lru_stats;
21
6.05k
  struct ndpi_patricia_tree_stats patricia_stats;
22
6.05k
  struct ndpi_automa_stats automa_stats;
23
6.05k
  int cat;
24
6.05k
  u_int16_t pid;
25
6.05k
  char *protoname;
26
6.05k
  char catname[] = "name";
27
6.05k
  struct ndpi_flow_input_info input_info;
28
6.05k
  ndpi_proto p, p2;
29
6.05k
  char out[128];
30
6.05k
  char log_ts[32];
31
32
33
6.05k
  if(fuzzed_data.remaining_bytes() < 4 + /* ndpi_init_detection_module() */
34
6.05k
             NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS +
35
6.05k
             1 + /* TLS cert expire */
36
6.05k
             6 + /* files */
37
6.05k
             ((NDPI_LRUCACHE_MAX + 1) * 5) + /* LRU caches */
38
6.05k
             2 + 1 + 4 + /* ndpi_set_detection_preferences() */
39
6.05k
             7 + /* Opportunistic tls */
40
6.05k
             2 + /* Pid */
41
6.05k
             2 + /* Category */
42
6.05k
             1 + /* Tunnel */
43
6.05k
             1 + /* Bool value */
44
6.05k
             2 + /* input_info */
45
6.05k
             21 /* Min real data: ip length + 1 byte of L4 header */)
46
19
    return -1;
47
48
  /* To allow memory allocation failures */
49
6.03k
  fuzz_set_alloc_callbacks_and_seed(size);
50
51
6.03k
  ndpi_info_mod = ndpi_init_detection_module(fuzzed_data.ConsumeIntegral<u_int32_t>());
52
53
6.03k
  set_ndpi_debug_function(ndpi_info_mod, NULL);
54
55
6.03k
  NDPI_BITMASK_RESET(enabled_bitmask);
56
3.09M
  for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS ; i++) {
57
3.09M
    if(fuzzed_data.ConsumeBool())
58
3.09M
      NDPI_BITMASK_ADD(enabled_bitmask, i);
59
3.09M
  }
60
6.03k
  if(ndpi_set_protocol_detection_bitmask2(ndpi_info_mod, &enabled_bitmask) == -1) {
61
575
    ndpi_exit_detection_module(ndpi_info_mod);
62
575
    ndpi_info_mod = NULL;
63
575
  }
64
65
6.03k
  ndpi_set_user_data(ndpi_info_mod, (void *)0xabcdabcd); /* Random pointer */
66
6.03k
  ndpi_set_user_data(ndpi_info_mod, (void *)0xabcdabcd); /* Twice to trigger overwriting */
67
6.03k
  ndpi_get_user_data(ndpi_info_mod);
68
69
6.03k
  ndpi_set_tls_cert_expire_days(ndpi_info_mod, fuzzed_data.ConsumeIntegral<u_int8_t>());
70
71
6.03k
  if(fuzzed_data.ConsumeBool())
72
2.73k
    ndpi_load_protocols_file(ndpi_info_mod, "protos.txt");
73
6.03k
  if(fuzzed_data.ConsumeBool())
74
2.72k
    ndpi_load_categories_file(ndpi_info_mod, "categories.txt", NULL);
75
6.03k
  if(fuzzed_data.ConsumeBool())
76
2.73k
    ndpi_load_risk_domain_file(ndpi_info_mod, "risky_domains.txt");
77
6.03k
  if(fuzzed_data.ConsumeBool())
78
2.70k
    ndpi_load_malicious_ja3_file(ndpi_info_mod, "ja3_fingerprints.csv");
79
6.03k
  if(fuzzed_data.ConsumeBool())
80
2.71k
    ndpi_load_malicious_sha1_file(ndpi_info_mod, "sha1_fingerprints.csv");
81
  /* Note that this function is not used by ndpiReader */
82
6.03k
  if(fuzzed_data.ConsumeBool())
83
2.70k
    ndpi_load_ipv4_ptree(ndpi_info_mod, "ipv4_addresses.txt", NDPI_PROTOCOL_TLS);
84
85
60.3k
  for(i = 0; i < NDPI_LRUCACHE_MAX + 1; i++) { /* + 1 to test invalid type */
86
54.3k
    ndpi_set_lru_cache_size(ndpi_info_mod, static_cast<lru_cache_type>(i),
87
54.3k
          fuzzed_data.ConsumeIntegralInRange(0, (1 << 16) - 1));
88
54.3k
    ndpi_get_lru_cache_size(ndpi_info_mod, static_cast<lru_cache_type>(i), &num);
89
90
54.3k
    ndpi_set_lru_cache_ttl(ndpi_info_mod, static_cast<lru_cache_type>(i),
91
54.3k
         fuzzed_data.ConsumeIntegralInRange(0, (1 << 24) - 1));
92
54.3k
    ndpi_get_lru_cache_ttl(ndpi_info_mod, static_cast<lru_cache_type>(i), &num);
93
54.3k
  }
94
95
  /* TODO: stub for geo stuff */
96
6.03k
  ndpi_load_geoip(ndpi_info_mod, NULL, NULL);
97
98
6.03k
  if(fuzzed_data.ConsumeBool())
99
2.55k
    ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_direction_detect_disable,
100
2.55k
                                   fuzzed_data.ConsumeBool());
101
6.03k
  if(fuzzed_data.ConsumeBool())
102
2.54k
    ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_enable_tls_block_dissection,
103
2.54k
                                   0 /* unused */);
104
6.03k
  if(fuzzed_data.ConsumeBool())
105
2.38k
    ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_max_packets_to_process,
106
2.38k
                                   fuzzed_data.ConsumeIntegralInRange(0, (1 << 16)));
107
108
6.03k
  ndpi_set_detection_preferences(ndpi_info_mod, static_cast<ndpi_detection_preference>(0xFF), 0xFF); /* Invalid preference */
109
110
6.03k
  ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP, fuzzed_data.ConsumeBool());
111
6.03k
  ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP);
112
6.03k
  ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_IMAP, fuzzed_data.ConsumeBool());
113
6.03k
  ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_IMAP);
114
6.03k
  ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_POP, fuzzed_data.ConsumeBool());
115
6.03k
  ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_POP);
116
6.03k
  ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_FTP_CONTROL, fuzzed_data.ConsumeBool());
117
6.03k
  ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_FTP_CONTROL);
118
119
6.03k
  random_proto = fuzzed_data.ConsumeIntegralInRange(0, (1 << 16) - 1);
120
6.03k
  random_value = fuzzed_data.ConsumeIntegralInRange(0,2); /* Only 0-1 are valid values */
121
6.03k
  ndpi_set_opportunistic_tls(ndpi_info_mod, random_proto, random_value);
122
6.03k
  ndpi_get_opportunistic_tls(ndpi_info_mod, random_proto);
123
124
2.33M
  for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS; i++) {
125
2.32M
    ndpi_set_protocol_aggressiveness(ndpi_info_mod, i, random_value);
126
2.32M
    ndpi_get_protocol_aggressiveness(ndpi_info_mod, i);
127
2.32M
  }
128
129
6.03k
  ndpi_finalize_initialization(ndpi_info_mod);
130
131
  /* Random protocol configuration */
132
6.03k
  pid = fuzzed_data.ConsumeIntegralInRange<u_int16_t>(0, NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1); /* + 1 to trigger invalid pid */
133
6.03k
  protoname = ndpi_get_proto_by_id(ndpi_info_mod, pid);
134
6.03k
  if (protoname) {
135
4.67k
    assert(ndpi_get_proto_by_name(ndpi_info_mod, protoname) == pid);
136
4.67k
  }
137
0
  ndpi_map_user_proto_id_to_ndpi_id(ndpi_info_mod, pid);
138
6.03k
  ndpi_map_ndpi_id_to_user_proto_id(ndpi_info_mod, pid);
139
6.03k
  ndpi_set_proto_breed(ndpi_info_mod, pid, NDPI_PROTOCOL_SAFE);
140
6.03k
  ndpi_set_proto_category(ndpi_info_mod, pid, NDPI_PROTOCOL_CATEGORY_MEDIA);
141
6.03k
  ndpi_is_subprotocol_informative(ndpi_info_mod, pid);
142
6.03k
  ndpi_get_proto_breed(ndpi_info_mod, pid);
143
144
6.03k
  ndpi_get_proto_by_name(ndpi_info_mod, NULL); /* Error */
145
6.03k
  ndpi_get_proto_by_name(ndpi_info_mod, "foo"); /* Invalid protocol */
146
147
  /* Custom category configuration */
148
6.03k
  cat = fuzzed_data.ConsumeIntegralInRange(static_cast<int>(NDPI_PROTOCOL_CATEGORY_CUSTOM_1),
149
6.03k
                                           static_cast<int>(NDPI_PROTOCOL_NUM_CATEGORIES + 1)); /* + 1 to trigger invalid cat */
150
6.03k
  ndpi_category_set_name(ndpi_info_mod, static_cast<ndpi_protocol_category_t>(cat), catname);
151
6.03k
  ndpi_is_custom_category(static_cast<ndpi_protocol_category_t>(cat));
152
6.03k
  ndpi_category_get_name(ndpi_info_mod, static_cast<ndpi_protocol_category_t>(cat));
153
6.03k
  ndpi_get_category_id(ndpi_info_mod, catname);
154
155
6.03k
  ndpi_tunnel2str(static_cast<ndpi_packet_tunnel>(fuzzed_data.ConsumeIntegralInRange(static_cast<int>(ndpi_no_tunnel),
156
6.03k
                                                                                     static_cast<int>(ndpi_gre_tunnel + 1)))); /* + 1 to trigger invalid value */
157
158
6.03k
  ndpi_get_num_supported_protocols(ndpi_info_mod);
159
6.03k
  ndpi_get_proto_defaults(ndpi_info_mod);
160
6.03k
  ndpi_get_ndpi_num_custom_protocols(ndpi_info_mod);
161
6.03k
  ndpi_get_ndpi_num_supported_protocols(ndpi_info_mod);
162
163
6.03k
  ndpi_self_check_host_match(stdout);
164
165
6.03k
  ndpi_dump_protocols(ndpi_info_mod, stdout);
166
6.03k
  ndpi_generate_options(fuzzed_data.ConsumeIntegralInRange(0, 4), stdout);
167
6.03k
  ndpi_dump_risks_score(stdout);
168
169
  /* Basic code to try testing this "config" */
170
6.03k
  bool_value = fuzzed_data.ConsumeBool();
171
6.03k
  input_info.in_pkt_dir = fuzzed_data.ConsumeIntegralInRange(0,2);
172
6.03k
  input_info.seen_flow_beginning = !!fuzzed_data.ConsumeBool();
173
6.03k
  memset(&flow, 0, sizeof(flow));
174
6.03k
  std::vector<uint8_t>pkt = fuzzed_data.ConsumeRemainingBytes<uint8_t>();
175
6.03k
  assert(pkt.size() >= 21); /* To be sure check on fuzzed_data.remaining_bytes() at the beginning is right */
176
177
0
  ndpi_detection_process_packet(ndpi_info_mod, &flow, pkt.data(), pkt.size(), 0, &input_info);
178
6.03k
  p = ndpi_detection_giveup(ndpi_info_mod, &flow, 1, &protocol_was_guessed);
179
180
6.03k
  assert(p.master_protocol == ndpi_get_flow_masterprotocol(ndpi_info_mod, &flow));
181
0
  assert(p.app_protocol == ndpi_get_flow_appprotocol(ndpi_info_mod, &flow));
182
0
  assert(p.category == ndpi_get_flow_category(ndpi_info_mod, &flow));
183
0
  ndpi_get_lower_proto(p);
184
6.03k
  ndpi_get_upper_proto(p);
185
6.03k
  ndpi_get_flow_error_code(&flow);
186
6.03k
  ndpi_get_flow_risk_info(&flow, out, sizeof(out), 1);
187
6.03k
  ndpi_get_flow_ndpi_proto(ndpi_info_mod, &flow, &p2);
188
6.03k
  ndpi_is_proto(p, NDPI_PROTOCOL_TLS);
189
6.03k
  ndpi_http_method2str(flow.http.method);
190
6.03k
  ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_info_mod, p.app_protocol));
191
6.03k
  ndpi_is_subprotocol_informative(ndpi_info_mod, p.app_protocol);
192
6.03k
  ndpi_get_http_method(ndpi_info_mod, bool_value ? &flow : NULL);
193
6.03k
  ndpi_get_http_url(ndpi_info_mod, &flow);
194
6.03k
  ndpi_get_http_content_type(ndpi_info_mod, &flow);
195
6.03k
  check_for_email_address(ndpi_info_mod, 0);
196
6.03k
  ndpi_get_flow_name(bool_value ? &flow : NULL);
197
  /* ndpi_guess_undetected_protocol() is a "strange" function. Try fuzzing it, here */
198
6.03k
  if(!ndpi_is_protocol_detected(ndpi_info_mod, p)) {
199
3.51k
    ndpi_guess_undetected_protocol(ndpi_info_mod, bool_value ? &flow : NULL,
200
3.51k
                                   flow.l4_proto);
201
3.51k
    if(!flow.is_ipv6) {
202
      /* Another "strange" function (ipv4 only): fuzz it here, for lack of a better alternative */
203
3.00k
      ndpi_find_ipv4_category_userdata(ndpi_info_mod, flow.c_address.v4);
204
205
3.00k
      ndpi_search_tcp_or_udp_raw(ndpi_info_mod, NULL, 0, ntohl(flow.c_address.v4), ntohl(flow.s_address.v4));
206
207
3.00k
      ndpi_guess_undetected_protocol_v4(ndpi_info_mod, bool_value ? &flow : NULL,
208
3.00k
                                        flow.l4_proto,
209
3.00k
                                        flow.c_address.v4, flow.c_port,
210
3.00k
                                        flow.s_address.v4, flow.s_port);
211
3.00k
    } else {
212
516
      ndpi_find_ipv6_category_userdata(ndpi_info_mod, (struct in6_addr *)flow.c_address.v6);
213
516
    }
214
    /* Another "strange" function: fuzz it here, for lack of a better alternative */
215
3.51k
    ndpi_search_tcp_or_udp(ndpi_info_mod, &flow);
216
3.51k
  }
217
6.03k
  if(!flow.is_ipv6) {
218
5.34k
    ndpi_network_ptree_match(ndpi_info_mod, (struct in_addr *)&flow.c_address.v4);
219
220
5.34k
    ndpi_risk_params params[] = { { NDPI_PARAM_HOSTNAME, flow.host_server_name},
221
5.34k
                                  { NDPI_PARAM_ISSUER_DN, flow.host_server_name},
222
5.34k
                                  { NDPI_PARAM_HOST_IPV4, &flow.c_address.v4} };
223
5.34k
    ndpi_check_flow_risk_exceptions(ndpi_info_mod, 3, params);
224
5.34k
  }
225
  /* TODO: stub for geo stuff */
226
6.03k
  ndpi_get_geoip_asn(ndpi_info_mod, NULL, NULL);
227
6.03k
  ndpi_get_geoip_country_continent(ndpi_info_mod, NULL, NULL, 0, NULL, 0);
228
229
6.03k
  ndpi_free_flow_data(&flow);
230
231
  /* Get some final stats */
232
60.3k
  for(i = 0; i < NDPI_LRUCACHE_MAX + 1; i++) /* + 1 to test invalid type */
233
54.3k
    ndpi_get_lru_cache_stats(ndpi_info_mod, static_cast<lru_cache_type>(i), &lru_stats);
234
48.2k
  for(i = 0; i < NDPI_PTREE_MAX + 1; i++) /* + 1 to test invalid type */
235
42.2k
    ndpi_get_patricia_stats(ndpi_info_mod, static_cast<ptree_type>(i), &patricia_stats);
236
42.2k
  for(i = 0; i < NDPI_AUTOMA_MAX + 1; i++) /* + 1 to test invalid type */
237
36.2k
    ndpi_get_automa_stats(ndpi_info_mod, static_cast<automa_type>(i), &automa_stats);
238
239
240
6.03k
  ndpi_revision();
241
6.03k
  ndpi_get_api_version();
242
6.03k
  ndpi_get_gcrypt_version();
243
244
6.03k
  ndpi_get_ndpi_detection_module_size();
245
6.03k
  ndpi_detection_get_sizeof_ndpi_flow_struct();
246
6.03k
  ndpi_detection_get_sizeof_ndpi_flow_tcp_struct();
247
6.03k
  ndpi_detection_get_sizeof_ndpi_flow_udp_struct();
248
249
6.03k
  ndpi_get_tot_allocated_memory();
250
6.03k
  ndpi_log_timestamp(log_ts, sizeof(log_ts));
251
252
6.03k
  ndpi_free_geoip(ndpi_info_mod);
253
254
6.03k
  ndpi_exit_detection_module(ndpi_info_mod);
255
256
6.03k
  return 0;
257
6.05k
}