aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2023-11-30 09:09:40 +0100
committerGitHub <noreply@github.com>2023-11-30 09:09:40 +0100
commit6f046df0dcb07dae74be127af555ad96e8576acf (patch)
treec0bedadb5e449652d54d4e01b8d192e78f98f7f0 /src
parentd85f8592b8374e2b8f149ceae3c301c6499606d1 (diff)
STUN: fix detection of DTLS (#2187)
Fix a memory leak ``` ==97697==ERROR: LeakSanitizer: detected memory leaks Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x55a6967cfa7e in malloc (/home/ivan/svnrepos/nDPI/fuzz/fuzz_ndpi_reader+0x701a7e) (BuildId: c7124999fa1ccc54346fa7bd536d8eab88c3ea01) #1 0x55a696972ab5 in ndpi_malloc /home/ivan/svnrepos/nDPI/src/lib/ndpi_memory.c:60:25 #2 0x55a696972da0 in ndpi_strdup /home/ivan/svnrepos/nDPI/src/lib/ndpi_memory.c:113:13 #3 0x55a696b7658d in processClientServerHello /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:2394:46 #4 0x55a696b86e81 in processTLSBlock /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:897:5 #5 0x55a696b80649 in ndpi_search_tls_udp /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:1262:11 #6 0x55a696b67a57 in ndpi_search_tls_wrapper /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:2751:5 #7 0x55a696b67758 in switch_to_tls /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:1408:3 #8 0x55a696c47810 in stun_search_again /home/ivan/svnrepos/nDPI/src/lib/protocols/stun.c:422:4 #9 0x55a6968a22af in ndpi_process_extra_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:7247:9 #10 0x55a6968acd6f in ndpi_internal_detection_process_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:7746:5 #11 0x55a6968aba3f in ndpi_detection_process_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:8013:22 #12 0x55a69683d30e in packet_processing /home/ivan/svnrepos/nDPI/fuzz/../example/reader_util.c:1723:31 #13 0x55a69683d30e in ndpi_workflow_process_packet /home/ivan/svnrepos/nDPI/fuzz/../example/reader_util.c:2440:10 #14 0x55a69680f08f in LLVMFuzzerTestOneInput /home/ivan/svnrepos/nDPI/fuzz/fuzz_ndpi_reader.c:135:7 [...] SUMMARY: AddressSanitizer: 16 byte(s) leaked in 1 allocation(s). ``` Found by oss-fuzzer See: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64564
Diffstat (limited to 'src')
-rw-r--r--src/lib/protocols/stun.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index 76a75b459..62e904b69 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -353,6 +353,8 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t app_proto = NDPI_PROTOCOL_UNKNOWN;
u_int32_t unused;
int first_dtls_pkt = 0;
+ u_int16_t old_proto_stack[2] = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN};
+ ndpi_protocol_category_t old_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;
NDPI_LOG_DBG2(ndpi_struct, "Packet counter %d protos %d/%d\n", flow->packet_counter,
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
@@ -396,6 +398,10 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
* the easiest (!?) solution is to remove everything, and let the TLS dissector
to set both master (i.e. DTLS) and subprotocol (if any) */
+ /* In same rare cases, with malformed/fuzzed traffic, `is_dtls()` might return false
+ positives. In that case, the TLS dissector doesn't set the master protocol, so we
+ need to rollback to the current state */
+
if(packet->tcp) {
/* TODO: TLS code assumes that DTLS is only over UDP */
NDPI_LOG_DBG(ndpi_struct, "Ignoring DTLS over TCP\n");
@@ -407,6 +413,11 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
/* First DTLS packet of the flow */
first_dtls_pkt = 1;
+ /* We might need to rollback this change... */
+ old_proto_stack[0] = flow->detected_protocol_stack[0];
+ old_proto_stack[1] = flow->detected_protocol_stack[1];
+ old_category = flow->category;
+
/* TODO: right way? It is a bit scary... do we need to reset something else too? */
reset_detected_protocol(ndpi_struct, flow);
change_category(ndpi_struct, flow, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
@@ -423,6 +434,23 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+
+ /* If this is not a real DTLS packet, we need to restore the old state */
+ if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN &&
+ first_dtls_pkt) {
+ NDPI_LOG_DBG(ndpi_struct, "Switch to TLS failed. Rollback to old classification\n");
+
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ old_proto_stack[1], old_proto_stack[0],
+ NDPI_CONFIDENCE_DPI);
+ change_category(ndpi_struct, flow, old_category);
+
+ flow->stun.maybe_dtls = 0;
+ flow->max_extra_packets_to_check -= 10;
+
+ NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ }
}
}
}