From b01b474b84a94ea4dd1af676a380bbaf710e5b03 Mon Sep 17 00:00:00 2001
From: John Thacker <johnthacker@gmail.com>
Date: Mon, 9 Mar 2026 20:33:41 -0400
Subject: [PATCH] BT DHT: Add recursion checks

Lists can be as small as two bytes, so in a crafted maximum size UDP
datagram the stack can overflow for stack sizes under 1.5 MiB or so.

Dictionaries are a little bigger, but go ahead and check anyway
(dictionaries and lists can be nested within each other.)

Thanks to bcoles for the POC.

Fix #21067

AI-Assisted: no

(backported from commit 7b2de9d1d129bf78ef45f3610ef0c4dfda9e26eb)
---
 epan/dissectors/packet-bt-dht.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

Index: wireshark-3.6.24/epan/dissectors/packet-bt-dht.c
===================================================================
--- wireshark-3.6.24.orig/epan/dissectors/packet-bt-dht.c
+++ wireshark-3.6.24/epan/dissectors/packet-bt-dht.c
@@ -195,11 +195,15 @@ dissect_bencoded_list(tvbuff_t *tvb, pac
       break;
     /* a sub-list */
     case 'l':
-      offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Sub-list" );
+      increment_dissection_depth(pinfo);
+      offset = dissect_bencoded_list(tvb, pinfo, sub_tree, offset, "Sub-list");
+      decrement_dissection_depth(pinfo);
       break;
     /* a dictionary */
     case 'd':
-      offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Sub-dict" );
+      increment_dissection_depth(pinfo);
+      offset = dissect_bencoded_dict(tvb, pinfo, sub_tree, offset, "Sub-dict");
+      decrement_dissection_depth(pinfo);
       break;
     /* a string */
     default:
@@ -422,7 +426,9 @@ dissect_bencoded_dict_entry(tvbuff_t *tv
   switch( tvb_get_guint8(tvb,offset) )
   {
   case 'd':
-    offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Value" );
+    increment_dissection_depth(pinfo);
+    offset = dissect_bencoded_dict(tvb, pinfo, sub_tree, offset, "Value");
+    decrement_dissection_depth(pinfo);
     val    = dict_str;
     break;
   case 'l':
@@ -433,7 +439,9 @@ dissect_bencoded_dict_entry(tvbuff_t *tv
     /* other unfamiliar lists */
     else
     {
-      offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Value" );
+      increment_dissection_depth(pinfo);
+      offset = dissect_bencoded_list(tvb, pinfo, sub_tree, offset, "Value");
+      decrement_dissection_depth(pinfo);
       val = list_str;
     }
     break;
@@ -735,7 +743,6 @@ proto_reg_handoff_bt_dht(void)
   heur_dissector_add("udp", dissect_bt_dht_heur, "BitTorrent DHT over UDP", "bittorrent_dht_udp", proto_bt_dht, HEURISTIC_DISABLE);
 
   bt_dht_handle = create_dissector_handle(dissect_bt_dht, proto_bt_dht);
-  // If this is ever streamed (transported over TCP) we need to add recursion checks.
   dissector_add_for_decode_as_with_preference("udp.port", bt_dht_handle);
 }
 
