BT-DHT dissector stack overflow via nested structs
## Summary The `dissect_bencoded_list()` function in the `BT-DHT` dissector crashes due to a stack overflow. Crash occurs when using 'Decode As' on a system with limited stack (`ulimit -s 1024`). Impact: - **SIGSEGV crash** on systems with ≤~ 1MB stack - **Does NOT crash** on default 8MB Linux stack (stack usage is only ~1.6MB) - **Requires decode-as**: BT-DHT heuristic is registered as `HEURISTIC_DISABLE` ## AI assistance Identified using Claude Opus 4.6. I've verified the bug, but not the root cause or mitigation. ## Sample capture file [generate_bt_dht.py](/uploads/dd15b1797558e2e1f32a07a334cb9363/generate_bt_dht.py) [bt_dht_stack_overflow.pcap](/uploads/c42f7e4d9468b7f773ddd9fe499d6cbc/bt_dht_stack_overflow.pcap) ## Steps to reproduce ``` $ ../.venv/bin/python3 generate_bt_dht.py [+] Generated bt_dht_stack_overflow.pcap (64013 byte payload, 32000 levels) Bug: packet-bt-dht.c:217 dissect_bencoded_list() - no recursion depth guard Test: ./build/run/tshark -d udp.port==6881,bt-dht -r pocs/bt_dht_stack_overflow.pcap Expected: SIGSEGV (exit code 139) or abort due to stack overflow $ bash -c 'ulimit -s 1024 && ../build/run/tshark -d udp.port==6881,bt-dht -r bt_dht_stack_overflow.pcap' ** (tshark:430983) 21:06:59.450076 [(none) MESSAGE] -- JSON Dictionary: No config.txt or jsonmain.xml found (using generic mode) Segmentation fault (core dumped) $ bash -c 'ulimit -s 2048 && ../build/run/tshark -d udp.port==6881,bt-dht -r bt_dht_stack_overflow.pcap' ** (tshark:431033) 21:07:08.625887 [(none) MESSAGE] -- JSON Dictionary: No config.txt or jsonmain.xml found (using generic mode) 1 0.000000 10.0.0.1 → 10.0.0.2 BT-DHT 64055 ``` ## What is the current bug behavior? **AI suggested root cause:** `dissect_bencoded_list()` recurses for each nested bencoded list element. Each `l` byte in the payload triggers one recursion level consuming only 2 bytes (the `l` prefix + corresponding `e` suffix). No `increment_dissection_depth()` is used. With a 64KB UDP payload: 32,000 nested lists × ~50 bytes/frame ≈ 1.6MB stack usage. ## What is the expected correct behavior? **AI suggested fix:** Add `increment_dissection_depth(pinfo)` / `decrement_dissection_depth(pinfo)` guards to the two recursive entry points: **`dissect_bencoded_list()`** (line 217): ```c static int dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) { increment_dissection_depth(pinfo); // ... existing body ... decrement_dissection_depth(pinfo); return offset; } ``` ## Build information Built from master branch. ``` ** (tshark:396187) 19:08:22.771852 [(none) MESSAGE] -- JSON Dictionary: No config.txt or jsonmain.xml found (using generic mode) TShark (Wireshark) 4.7.0 (v4.7.0rc0-2101-g6fd3e409475e). Copyright 1998-2026 Gerald Combs <gerald@wireshark.org> and contributors. Licensed under the terms of the GNU General Public License (version 2 or later). This is free software; see the file named COPYING in the distribution. There is NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compile-time info: Bit width: 64-bit Compiler: GCC 13.3.0 GLib: 2.80.0 With: +brotli +libxml2 2.9.14 +PCRE2 10.42 2022-12-11 +Gcrypt 1.10.3 +LZ4 1.9.4 +Snappy 1.1.10 +GnuTLS 3.8.3 and PKCS#11 +MaxMind +zlib 1.3 +Kerberos (MIT) +nghttp2 1.59.0 +Zstandard 1.5.5 +libpcap +nghttp3 0.8.0 Without: -libnl -Lua -xxhash -libsmi -POSIX capabilities -zlib-ng Runtime info: OS: Linux 6.8.0-100-generic CPU: [redacted] Memory: 11914 MB of physical memory GLib: 2.80.0 Locale: LC_TYPE=en_US.UTF-8 Plugins: supported, 0 loaded With: +brotli 1.1.0 +nghttp2 1.59.0 +c-ares 1.27.0 +nghttp3 0.8.0 +Gcrypt 1.10.3 +PCRE2 10.42 2022-12-11 +GnuTLS 3.8.3 +zlib 1.3 +libpcap 1.10.4 (with TPACKET_V3) +Zstandard 1.5.5 +LZ4 1.9.4 ```
issue