diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2022-12-23 19:07:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-23 19:07:13 +0100 |
commit | 560280e6f082d22e6a9de8e537b7876bacf8d072 (patch) | |
tree | a8ed2ea6c43614606cc977fc27050dd41e0c3133 /fuzz/fuzz_config.cpp | |
parent | 3de76812d978060c433864c2f72de113746d70e8 (diff) |
fuzz: add fuzzer testing nDPI (initial) configurations (#1830)
The goal of this fuzzer is to test init and deinit of the library, with
different configurations. In details:
* random memory allocation failures, even during init phase
* random `ndpi_init_prefs` parameter of `ndpi_init_detection_module()`
* random LRU caches sizes
* random bitmask of enabled protocols
* random parameters of `ndpi_set_detection_preferences()`
* random initialization of opportunistic TLS
* random load/don't load of configuration files
This new fuzzer is a C++ file, because it uses `FuzzedDataProvider`
class (see
https://github.com/google/fuzzing/blob/master/docs/split-inputs.md).
Note that the (existing) fuzzers need to be linked with C++ compiler
anyway, so this new fuzzer doesn't add any new requirements.
Diffstat (limited to 'fuzz/fuzz_config.cpp')
-rw-r--r-- | fuzz/fuzz_config.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp new file mode 100644 index 000000000..884e3720e --- /dev/null +++ b/fuzz/fuzz_config.cpp @@ -0,0 +1,113 @@ +#include "ndpi_api.h" +#include "fuzz_common_code.h" + +#include <stdint.h> +#include <stdio.h> +#include <assert.h> +#include "fuzzer/FuzzedDataProvider.h" + + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fuzzed_data(data, size); + struct ndpi_detection_module_struct *ndpi_info_mod; + struct ndpi_flow_struct flow; + u_int8_t protocol_was_guessed; + u_int32_t i, num; + u_int16_t random_proto; + int random_value; + NDPI_PROTOCOL_BITMASK enabled_bitmask; + struct ndpi_lru_cache_stats lru_stats; + struct ndpi_patricia_tree_stats patricia_stats; + struct ndpi_automa_stats automa_stats; + + if(fuzzed_data.remaining_bytes() < 4 + /* ndpi_init_detection_module() */ + NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + + 5 + /* files */ + (NDPI_LRUCACHE_MAX * 3) + /* LRU caches */ + 2 + 1 + 4 + /* ndpi_set_detection_preferences() */ + 7 + /* Opportunistic tls */ + 29 /* Min real data: ip length + udp length + 1 byte */) + return -1; + +#ifdef ENABLE_MEM_ALLOC_FAILURES + set_ndpi_malloc(malloc_wrapper); + set_ndpi_free(free_wrapper); + set_mem_alloc_state(size); +#endif + + ndpi_info_mod = ndpi_init_detection_module(fuzzed_data.ConsumeIntegral<u_int32_t>()); + + NDPI_BITMASK_RESET(enabled_bitmask); + for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS ; i++) { + if(fuzzed_data.ConsumeBool()) + NDPI_BITMASK_ADD(enabled_bitmask, i); + } + if(ndpi_set_protocol_detection_bitmask2(ndpi_info_mod, &enabled_bitmask) == -1) { + ndpi_exit_detection_module(ndpi_info_mod); + ndpi_info_mod = NULL; + } + + if(fuzzed_data.ConsumeBool()) + ndpi_load_protocols_file(ndpi_info_mod, "protos.txt"); + if(fuzzed_data.ConsumeBool()) + ndpi_load_categories_file(ndpi_info_mod, "categories.txt", NULL); + if(fuzzed_data.ConsumeBool()) + ndpi_load_risk_domain_file(ndpi_info_mod, "risky_domains.txt"); + if(fuzzed_data.ConsumeBool()) + ndpi_load_malicious_ja3_file(ndpi_info_mod, "ja3_fingerprints.csv"); + if(fuzzed_data.ConsumeBool()) + ndpi_load_malicious_sha1_file(ndpi_info_mod, "sha1_fingerprints.csv"); + + for(i = 0; i < NDPI_LRUCACHE_MAX; i++) { + ndpi_set_lru_cache_size(ndpi_info_mod, static_cast<lru_cache_type>(i), + fuzzed_data.ConsumeIntegralInRange(0, (1 << 24) - 1)); + ndpi_get_lru_cache_size(ndpi_info_mod, static_cast<lru_cache_type>(i), &num); + } + + if(fuzzed_data.ConsumeBool()) + ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_direction_detect_disable, + fuzzed_data.ConsumeBool()); + if(fuzzed_data.ConsumeBool()) + ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_enable_tls_block_dissection, + 0 /* unused */); + if(fuzzed_data.ConsumeBool()) + ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_max_packets_to_process, + fuzzed_data.ConsumeIntegralInRange(0, (1 << 16))); + + ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP, fuzzed_data.ConsumeBool()); + ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP); + ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_IMAP, fuzzed_data.ConsumeBool()); + ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_IMAP); + ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_POP, fuzzed_data.ConsumeBool()); + ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_POP); + ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_FTP_CONTROL, fuzzed_data.ConsumeBool()); + ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_FTP_CONTROL); + + random_proto = fuzzed_data.ConsumeIntegralInRange(0, (1 << 16) - 1); + random_value = fuzzed_data.ConsumeIntegralInRange(0,2); /* Only 0-1 are valid values */ + ndpi_set_opportunistic_tls(ndpi_info_mod, random_proto, random_value); + ndpi_get_opportunistic_tls(ndpi_info_mod, random_proto); + + ndpi_finalize_initialization(ndpi_info_mod); + + + /* Basic code to try testing this "config" */ + memset(&flow, 0, sizeof(flow)); + std::vector<uint8_t>pkt = fuzzed_data.ConsumeRemainingBytes<uint8_t>(); + assert(pkt.size() >= 29); /* To be sure check on fuzzed_data.remaining_bytes() at the beginning is right */ + ndpi_detection_process_packet(ndpi_info_mod, &flow, pkt.data(), pkt.size(), 0, NULL); + ndpi_detection_giveup(ndpi_info_mod, &flow, 1, &protocol_was_guessed); + ndpi_free_flow_data(&flow); + + /* Get some final stats */ + for(i = 0; i < NDPI_LRUCACHE_MAX; i++) + ndpi_get_lru_cache_stats(ndpi_info_mod, static_cast<lru_cache_type>(i), &lru_stats); + for(i = 0; i < NDPI_PTREE_MAX; i++) + ndpi_get_patricia_stats(ndpi_info_mod, static_cast<ptree_type>(i), &patricia_stats); + for(i = 0; i < NDPI_AUTOMA_MAX; i++) + ndpi_get_automa_stats(ndpi_info_mod, static_cast<automa_type>(i), &automa_stats); + + ndpi_exit_detection_module(ndpi_info_mod); + + return 0; +} |