/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 | } |