From bc4db26fe4aafd6e8a7e88dfdf21f50d227f2168 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Wed, 23 Sep 2026 22:57:02 +0200 Subject: [PATCH] Fixed potential DF and extend packet fuzzer Signed-off-by: Toni Uhlig --- CMakePresets.json | 17 ++++++++++++++++ nDPId.c | 11 +++++++--- test/fuzz_ndpi_process_packet.c | 36 +++++++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 146ec5132..3900cdea0 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -25,6 +25,7 @@ { "name": "all-unix", "inherits": "default-unix", + "binaryDir": "${sourceDir}/build-all", "cacheVariables": { "BUILD_RUST_EXAMPLES": "ON", "ENABLE_CONNTRACK": "ON", @@ -35,9 +36,22 @@ "ENABLE_ZLIB": "ON" } }, + { + "name": "all-unix-local-ndpi", + "inherits": "all-unix", + "binaryDir": "${sourceDir}/build-all-local-ndpi", + "cacheVariables": { + "BUILD_NDPI": "OFF", + "NDPI_WITH_GCRYPT": "ON", + "NDPI_WITH_MAXMINDDB": "ON", + "NDPI_WITH_PCRE": "ON", + "NDPI_WITH_PLUGIN_SYSTEM": "ON" + } + }, { "name": "all-unix-asan", "inherits": "all-unix", + "binaryDir": "${sourceDir}/build-asan", "cacheVariables": { "ENABLE_SANITIZER": "ON" } @@ -45,6 +59,7 @@ { "name": "all-unix-tsan", "inherits": "all-unix", + "binaryDir": "${sourceDir}/build-tsan", "cacheVariables": { "ENABLE_SANITIZER_THREAD": "ON" } @@ -52,7 +67,9 @@ { "name": "all-unix-profiler", "inherits": "all-unix", + "binaryDir": "${sourceDir}/build-memprof", "cacheVariables": { + "ENABLE_MEMORY_STATUS": "ON", "ENABLE_MEMORY_PROFILING": "ON" } } diff --git a/nDPId.c b/nDPId.c index b10168957..7fb26d4ba 100644 --- a/nDPId.c +++ b/nDPId.c @@ -2248,7 +2248,7 @@ static void process_idle_flow(struct nDPId_reader_thread * const reader_thread, while (workflow->cur_idle_flows > 0) { - struct nDPId_flow_basic * const flow_basic = + struct nDPId_flow_basic * flow_basic = (struct nDPId_flow_basic *)workflow->ndpi_flows_idle[--workflow->cur_idle_flows]; switch (flow_basic->state) @@ -2326,8 +2326,13 @@ static void process_idle_flow(struct nDPId_reader_thread * const reader_thread, } } - ndpi_tdelete(flow_basic, &workflow->ndpi_flows_active[idle_scan_index], ndpi_workflow_node_cmp); - ndpi_flow_info_free(flow_basic); + flow_basic = (struct nDPId_flow_basic *)ndpi_tdelete( + flow_basic, &workflow->ndpi_flows_active[idle_scan_index], + ndpi_workflow_node_cmp + ); + if (flow_basic != NULL) { + ndpi_flow_info_free(flow_basic); + } workflow->cur_active_flows--; } } diff --git a/test/fuzz_ndpi_process_packet.c b/test/fuzz_ndpi_process_packet.c index a56455efa..cbeab6b5e 100644 --- a/test/fuzz_ndpi_process_packet.c +++ b/test/fuzz_ndpi_process_packet.c @@ -1,3 +1,5 @@ +#include // memfd_create() + #define NO_MAIN 1 #include "../utils.c" #include "../nio.c" @@ -15,10 +17,18 @@ int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) init_logging("fuzz_ndpi_process_packet"); log_app_info(); + enable_console_logger(); set_cmdarg_string(&nDPId_options.instance_alias, "fuzz_ndpi_process_packet"); - set_cmdarg_ull(&nDPId_options.max_flows_per_thread, 1024); - set_cmdarg_ull(&nDPId_options.max_idle_flows_per_thread, 16); + set_cmdarg_ull(&nDPId_options.error_event_threshold_n, 0u); + set_cmdarg_ull(&nDPId_options.error_event_threshold_time, 0u); + set_cmdarg_ull(&nDPId_options.generic_max_idle_time, 5u); + set_cmdarg_ull(&nDPId_options.icmp_max_idle_time, 2u); + set_cmdarg_ull(&nDPId_options.tcp_max_idle_time, 5u); + set_cmdarg_ull(&nDPId_options.udp_max_idle_time, 2u); + set_cmdarg_ull(&nDPId_options.tcp_max_post_end_flow_time, 1u); + set_cmdarg_ull(&nDPId_options.max_flows_per_thread, 65535); + set_cmdarg_ull(&nDPId_options.max_idle_flows_per_thread, 1024); set_cmdarg_ull(&nDPId_options.reader_thread_count, 1); set_cmdarg_boolean(&nDPId_options.enable_data_analysis, 1); set_cmdarg_ull(&nDPId_options.max_packets_per_flow_to_send, 5); @@ -41,9 +51,15 @@ int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) workflow->max_active_flows = GET_CMDARG_ULL(nDPId_options.max_flows_per_thread); workflow->ndpi_flows_idle = (void **)ndpi_calloc(workflow->max_idle_flows, sizeof(void *)); workflow->ndpi_flows_active = (void **)ndpi_calloc(workflow->max_active_flows, sizeof(void *)); - reader_threads[0].collector_sockfd = -1; + reader_threads[0].collector_sockfd = memfd_create("collector", MFD_CLOEXEC); reader_threads[0].workflow = workflow; + if (reader_threads[0].collector_sockfd < 0 || + set_collector_nonblock(&reader_threads[0]) != 0) + { + return 1; + } + if (workflow->ndpi_flows_idle == NULL || workflow->ndpi_flows_active == NULL) { return 1; @@ -66,8 +82,20 @@ int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) } struct pcap_pkthdr pcap_hdr = {.caplen = size, .len = size}; - gettimeofday(&pcap_hdr.ts, NULL); // not optimal; more difficult to reproduce via crash files + if (size >= 8) + pcap_hdr.ts.tv_sec = get_u_int64_t(data, 0); ndpi_process_packet((uint8_t *)&reader_threads[0], &pcap_hdr, data); + char cbuf[BUFSIZ]; + ssize_t bytes_read = 0; + while ((bytes_read = read(reader_threads[0].collector_sockfd, cbuf, sizeof(cbuf))) > 0) + { + } + + struct timeval tval; + get_current_time(&tval); + uint64_t tval_us = tval.tv_sec * 1000 * 1000 + tval.tv_usec; + reader_threads[0].workflow->last_global_time += tval_us; + return 0; }