Forgot to attach the patch, sorry.

* Jochen Sprickerhof <[email protected]> [2026-02-14 16:44]:
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected], Balint Reczey 
<[email protected]>
Control: affects -1 + src:wireshark
User: [email protected]
Usertags: pu

[ Reason ]
Several security issues have been found in Wireshark. They have all been
tagged no-DSA by the security team and Balint agreed that I can take
care of the update.

[ Impact ]
All crashes or denial of service when analyzing network data.

[ Tests ]
autopkgtest and manual tests with the sample data from upstream.

[ Risks ]
Low risk. This is a userland tool and patches mostly add bound checks.

[ Checklist ]
 [X] *all* changes are documented in the d/changelog
 [X] I reviewed all changes and I approve them
 [X] attach debdiff against the package in (old)stable
 [X] the issue is verified as fixed in unstable (and stable)

diff --git a/debian/changelog b/debian/changelog
index 25987ad4c3..71cc9c42e8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,26 @@
+wireshark (4.0.17-0+deb12u2) bookworm; urgency=medium
+
+  * Non-maintainer upload.
+  * Fix CVE-2024-11596: ECMP dissector crash allows denial of service via
+    packet injection or crafted capture file.
+  * Fix CVE-2025-5601: Column handling crashes allows denial of service via
+    packet injection or crafted capture file.
+  * Fix CVE-2024-9781: AppleTalk and RELOAD Framing dissector crash allows
+    denial of service via packet injection or crafted capture file.
+  * Fix CVE-2025-11626: MONGO dissector infinite loop allows denial of
+    service.
+  * Fix CVE-2025-13499: Kafka dissector crash allows denial of service.
+  * Fix CVE-2025-13945: HTTP3 dissector crash allows denial of service.
+  * Fix CVE-2025-13946: MEGACO dissector infinite loop in allows denial of
+    service.
+  * Fix CVE-2025-9817: SSH dissector crash allows denial of service.
+  * Fix CVE-2026-0960: HTTP3 protocol dissector infinite loop allows denial of
+    service.
+  * Fix CVE-2025-1492: Bundle Protocol and CBOR dissector crashes allows
+    denial of service via packet injection or crafted capture file.
+
+ -- Jochen Sprickerhof <[email protected]>  Wed, 28 Jan 2026 13:22:40 +0100
+
 wireshark (4.0.17-0+deb12u1) bookworm; urgency=medium
 
   * Non-maintainer upload.
diff --git a/debian/patches/CVE-2024-11596.patch b/debian/patches/CVE-2024-11596.patch
new file mode 100644
index 0000000000..188344e6e5
--- /dev/null
+++ b/debian/patches/CVE-2024-11596.patch
@@ -0,0 +1,162 @@
+From: Gerald Combs <[email protected]>
+Date: Thu, 14 Nov 2024 10:56:37 -0800
+Subject: ECMP: Exorcise a string buffer arithmetic gremlin
+
+Use a wmem_strbuf instead of manually allocating a string and managing
+its offsets.
+
+Avoid appending a dangling space to our string.
+
+Fixes #20214
+
+(cherry picked from commit c8e58870733f88f275ca9a6fa115ed085f987d94)
+
+Conflicts:
+	epan/dissectors/packet-ecmp.c
+
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/18076/diffs?commit_id=06e0b0bb0925fe4b99cfb7243cce473031b09dee
+---
+ epan/dissectors/packet-ecmp.c | 77 +++++++++----------------------------------
+ 1 file changed, 16 insertions(+), 61 deletions(-)
+
+diff --git a/epan/dissectors/packet-ecmp.c b/epan/dissectors/packet-ecmp.c
+index 5b0ed6a..a1e351b 100644
+--- a/epan/dissectors/packet-ecmp.c
++++ b/epan/dissectors/packet-ecmp.c
+@@ -1122,72 +1122,54 @@ static int display_raw_cyclic_data(guint8 display, int offset, guint16 buffer_si
+ 		proto_tree_add_bytes_format_value(ecmp_current_tree, hf_ecmp_cyclic_data, tvb, offset-1, 0, NULL, "No data");
+ 	} else {
+ 		/* define some variables  */
+-		gchar*		pdata = NULL; /* pointer to array that stores the formatted data string */
+-		guint16		idx = 0; /* counts through formatted string array */
+-		guint8		value8 = 0; /* placeholder for extracted 8-bit data */
+-		guint16		value16 = 0; /* placeholder for extracted 16-bit data */
+-		guint32		value32 = 0; /* placeholder for extracted 32-bit data */
++		wmem_strbuf_t*	pdata = wmem_strbuf_new(wmem_packet_scope(), ""); /* formatted data string */
+ 		guint16		num_elements_total = 0; /* contains total number of elements (byte/word/long) to be processed  */
+ 		const guint16	num_byte_elements_per_line = 16; /* number of byte (8-bit) elements per line e.g.  "1B " (3 chars per element)  */
+ 		const guint16	num_word_elements_per_line = 16; /* number of word (16-bit) elements per line e.g.  "A81B " (5 chars per element) */
+ 		const guint16	num_long_elements_per_line = 8; /* number of long (32-bit) elements per line e.g.  "01F4A81B " (9 chars per element) */
+ 		guint16		num_elements_per_line = 8; /* counts the current number of elements per line */
+ 		guint16		num_elements = 0; /* counts the number of elements in the format string */
+-		guint16		format_string_size = 0; /* size of dynamic array to hold the formatted string */
+ 		guint16		a = 0; /* value used for looping */
+ 		int		start_offset, line_offset;
+ 
+-		/* calculate format string array size and other stuff                               */
+-		/*                                                                                  */
+-		/* Note: format string does require a nul-terminator (the + 1 in the equations)     */
+-		/*                                                                                  */
+-		/* display = 0:  (byte format  "1D 24 3F ... A3 "                                   */
+-		/*      format_string_size = (num_byte_elements_per_line * 3) + 1                   */
+-		/*                                                                                  */
+-		/* display = 1:  (word format  "1D24 3F84 120B ... 1FA3 "                           */
+-		/*      format_string_size = (num_word_elements_per_line * 5) + 1                   */
+-		/*                                                                                  */
+-		/* display = 2:  (byte format  "1D243F84 9BC08F20 ... 28BB1FA3 "                    */
+-		/*      format_string_size = (num_long_elements_per_line * 9) + 1                   */
++		/* calculate number of elements                                                     */
+ 		/*                                                                                  */
+ 		if (display == cyclic_display_byte_format) {
+-			format_string_size = (num_byte_elements_per_line * 3) + 1; /* format_string_size = 49  */
+ 			num_elements_per_line = num_byte_elements_per_line; /* num_elements_per_line = 16  */
+ 			num_elements_total = buffer_size;
+ 		} else if (display == cyclic_display_word_format) {
+-			format_string_size = (num_word_elements_per_line * 5) + 1; /* format_string_size = 81  */
+ 			num_elements_per_line = num_word_elements_per_line; /* num_elements_per_line = 16  */
+ 			num_elements_total = buffer_size >> 1;
+ 		} else if (display == cyclic_display_long_format) {
+-			format_string_size = (num_long_elements_per_line * 9) + 1; /* format_string_size = 73  */
+ 			num_elements_per_line = num_long_elements_per_line; /* num_elements_per_line = 8  */
+ 			num_elements_total = buffer_size >> 2;
+ 		} else {
+-			format_string_size = (num_byte_elements_per_line * 3) + 1; /* format_string_size = 49  */
+ 			num_elements_per_line = num_byte_elements_per_line; /* num_elements_per_line = 16  */
+ 			num_elements_total = buffer_size;
+ 		}
+ 
+-		/* allocate dynamic memory for one line  */
+-		pdata = (gchar *)wmem_alloc(wmem_packet_scope(), format_string_size);
+-
+ 		/* OK, let's get started */
+-		idx = 0;
+ 		num_elements = 0;
+ 
+ 		line_offset = start_offset = offset;
+ 		/* work through the display elements, 1 byte\word\long at a time  */
+-		for (a = 0; a < num_elements_total; a++ )
+-			{
++		for (a = 0; a < num_elements_total; a++ ) {
++			if (wmem_strbuf_get_len(pdata) > 0) {
++				wmem_strbuf_append_c(pdata, ' ');
++			}
++
+ 			/* use Wireshark accessor function to get the next byte, word, or long data  */
+ 			if (display == cyclic_display_byte_format) {
+-				value8 = tvb_get_guint8(tvb, offset);
++				guint8 value8 = tvb_get_guint8(tvb, offset);
++				wmem_strbuf_append_printf(pdata, "%02x", value8);
+ 				offset++;
+ 			} else if (display == cyclic_display_word_format) {
+-				value16 = tvb_get_ntohs(tvb, offset);
++				guint16 value16 = tvb_get_ntohs(tvb, offset);
++				wmem_strbuf_append_printf(pdata, "%04x", value16);
+ 				offset += 2;
+ 			} else if (display == cyclic_display_long_format) {
+-				value32 = tvb_get_ntohl(tvb, offset);
++				guint32 value32 = tvb_get_ntohl(tvb, offset);
++				wmem_strbuf_append_printf(pdata, "%08x", value32);
+ 				offset += 4;
+ 			}
+ 
+@@ -1196,47 +1178,20 @@ static int display_raw_cyclic_data(guint8 display, int offset, guint16 buffer_si
+ 
+ 			/* check if we hit the max number of byte elements per line  */
+ 			if (num_elements >= num_elements_per_line) {
+-				/* we hit end of the current line  */
+-				/* add final value to string */
+-				if (display == cyclic_display_byte_format) {
+-					snprintf(&pdata[idx], 32, "%02x",value8);
+-				} else if (display == cyclic_display_word_format) {
+-						snprintf(&pdata[idx], 32, "%04x",value16);
+-				} else if (display == cyclic_display_long_format) {
+-					snprintf(&pdata[idx], 32, "%08x",value32);
+-				}
+-
+ 				/* display the completed line in the sub-tree  */
+-				proto_tree_add_bytes_format(ecmp_current_tree, hf_ecmp_cyclic_data, tvb, offset, offset-line_offset, NULL, "%s", pdata);
++				proto_tree_add_bytes_format(ecmp_current_tree, hf_ecmp_cyclic_data, tvb, offset, offset-line_offset, NULL, "%s", wmem_strbuf_get_str(pdata));
+ 
+ 				/* start the line over */
+-				idx = 0;
++				wmem_strbuf_truncate(pdata, 0);
+ 				num_elements = 0;
+ 				line_offset = offset;
+-
+-			} else {
+-				/* we're still adding to the current line  */
+-				/* add current value to string */
+-				if (display == cyclic_display_byte_format) {
+-					snprintf(&pdata[idx], 32, "%02x ",value8);
+-					idx += 3;
+-				} else if (display == cyclic_display_word_format) {
+-					snprintf(&pdata[idx], 32, "%04x ",value16);
+-					idx += 5;
+-				} else if (display == cyclic_display_long_format) {
+-					snprintf(&pdata[idx], 32, "%08x ",value32);
+-					idx += 9;
+-				}
+ 			}
+ 		}
+ 
+ 		/* if we exited the loop, see if there's a partial line to display  */
+ 		if (num_elements > 0) {
+-			/* add null-terminator to partial line  */
+-			pdata[idx] = 0x00;
+-
+ 			/* display the partial line in the sub-tree  */
+-			proto_tree_add_bytes_format(ecmp_current_tree, hf_ecmp_cyclic_data, tvb, start_offset, offset-start_offset, NULL, "%s", pdata);
++			proto_tree_add_bytes_format(ecmp_current_tree, hf_ecmp_cyclic_data, tvb, start_offset, offset-start_offset, NULL, "%s", wmem_strbuf_get_str(pdata));
+ 		}
+ 	}
+ 	return offset;
diff --git a/debian/patches/CVE-2024-9781.patch b/debian/patches/CVE-2024-9781.patch
new file mode 100644
index 0000000000..cf2725aef9
--- /dev/null
+++ b/debian/patches/CVE-2024-9781.patch
@@ -0,0 +1,122 @@
+From: Gerald Combs <[email protected]>
+Date: Tue, 8 Oct 2024 11:56:28 -0700
+Subject: AppleTalk: Make sure we have valid addresses
+
+Make sure ATP, ZIP, and ASP have valid addresses. Use sizeof instead of
+a hard-coded value in a few places.
+
+Fixes #20114
+
+(cherry picked from commit 3de741321f85c205c0a8266c40f33cb0013bd1d2)
+
+origin: https://gitlab.com/wireshark/wireshark/-/commit/418fd5fe4b5934e8a4f53053c1de7bb94dba3811
+---
+ epan/dissectors/packet-atalk.c | 44 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 32 insertions(+), 12 deletions(-)
+
+diff --git a/epan/dissectors/packet-atalk.c b/epan/dissectors/packet-atalk.c
+index ed0fe43..d346934 100644
+--- a/epan/dissectors/packet-atalk.c
++++ b/epan/dissectors/packet-atalk.c
+@@ -225,9 +225,18 @@ static int hf_asp_attn_code     = -1;
+ static int hf_asp_seq           = -1;
+ static int hf_asp_size          = -1;
+ 
++/*
++ * Structure used to represent a DDP address; gives the layout of the
++ * data pointed to by an Appletalk "address" structure.
++ */
++struct atalk_ddp_addr {
++    guint16 net;
++    guint8  node;
++};
++
+ typedef struct {
+   guint32 conversation;
+-  guint8  src[4];
++  guint8 src[sizeof(struct atalk_ddp_addr)];
+   guint16 tid;
+ } asp_request_key;
+ 
+@@ -495,6 +504,10 @@ static const value_string asp_error_vals[] = {
+   {0,                   NULL } };
+ value_string_ext asp_error_vals_ext = VALUE_STRING_EXT_INIT(asp_error_vals);
+ 
++static bool is_ddp_address(address *addr) {
++  return addr->type == atalk_address_type && addr->len == sizeof(struct atalk_ddp_addr);
++}
++
+ /*
+  * hf_index must be a FT_UINT_STRING type
+  * Are these always in a Mac extended character set?  Should we have a
+@@ -737,6 +750,12 @@ dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+   conversation_t  *conversation;
+   asp_request_val *request_val   = NULL;
+ 
++  // ATP is carried over DDP
++  if (!(is_ddp_address(&pinfo->src) && is_ddp_address(&pinfo->dst))) {
++    return 0;
++  }
++
++
+   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
+ 
+   ctrlinfo = tvb_get_guint8(tvb, offset);
+@@ -763,7 +782,7 @@ dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+     asp_request_key request_key;
+ 
+     request_key.conversation = conversation->conv_index;
+-    memcpy(request_key.src, (!atp_asp_dsi_info.reply)?pinfo->src.data:pinfo->dst.data, 4);
++    memcpy(request_key.src, (!atp_asp_dsi_info.reply)?pinfo->src.data:pinfo->dst.data, sizeof(struct atalk_ddp_addr));
+     request_key.tid = atp_asp_dsi_info.tid;
+ 
+     request_val = (asp_request_val *) wmem_map_lookup(atp_request_hash, &request_key);
+@@ -1011,7 +1030,7 @@ get_transaction(tvbuff_t *tvb, packet_info *pinfo, struct atp_asp_dsi_info *atp_
+   conversation = find_or_create_conversation(pinfo);
+ 
+   request_key.conversation = conversation->conv_index;
+-  memcpy(request_key.src, (!atp_asp_dsi_info->reply)?pinfo->src.data:pinfo->dst.data, 4);
++  memcpy(request_key.src, (!atp_asp_dsi_info->reply)?pinfo->src.data:pinfo->dst.data, sizeof(struct atalk_ddp_addr));
+   request_key.tid = atp_asp_dsi_info->tid;
+ 
+   request_val = (asp_request_val *) wmem_map_lookup(asp_request_hash, &request_key);
+@@ -1044,6 +1063,11 @@ dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+   if (data == NULL)
+     return 0;
+ 
++  // ASP is carried over ATP/DDP
++  if (!(is_ddp_address(&pinfo->src) && is_ddp_address(&pinfo->dst))) {
++    return 0;
++  }
++
+   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
+   col_clear(pinfo->cinfo, COL_INFO);
+ 
+@@ -1176,15 +1200,6 @@ dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+ /* -----------------------------
+    ZIP protocol cf. inside appletalk chap. 8
+ */
+-/*
+- * Structure used to represent a DDP address; gives the layout of the
+- * data pointed to by an Appletalk "address" structure.
+- */
+-struct atalk_ddp_addr {
+-    guint16 net;
+-    guint8  node;
+-};
+-
+ 
+ static int atalk_str_len(const address* addr _U_)
+ {
+@@ -1234,6 +1249,11 @@ dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+   if (data == NULL)
+     return 0;
+ 
++  // ATP ZIP is carried over DDP
++  if (!(is_ddp_address(&pinfo->src) && is_ddp_address(&pinfo->dst))) {
++    return 0;
++  }
++
+   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
+   col_clear(pinfo->cinfo, COL_INFO);
+ 
diff --git a/debian/patches/CVE-2025-11626.patch b/debian/patches/CVE-2025-11626.patch
new file mode 100644
index 0000000000..c193098e56
--- /dev/null
+++ b/debian/patches/CVE-2025-11626.patch
@@ -0,0 +1,91 @@
+From: John Thacker <[email protected]>
+Date: Mon, 22 Sep 2025 21:41:00 -0400
+Subject: Mongo: Avoid infinite loop in dissect_op_msg_section
+
+If the size of a a OP_MSG data section is indicated as -1, that
+leads to advancing the offset by section_len + 1, or zero, which
+causes an infinite loop.
+
+The total message and section lengths in Mongo are signed int32s;
+it is impossible for them to be negative, and impossible for the
+section length to be INT_MAX (since the message length includes
+the length of the four byte headers and flag bits.)
+
+Throw an error to avoid the offset moving backwards, an infinite loop,
+or signed integer overflow.
+
+Also update some URLs to their new locations.
+
+Fix #20724.
+
+(backported from commit 1ec4709cab382f7077ba66d2e382c2e75ce335c1)
+
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/21448
+---
+ epan/dissectors/packet-mongo.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/epan/dissectors/packet-mongo.c b/epan/dissectors/packet-mongo.c
+index 4a387fe..464ce77 100644
+--- a/epan/dissectors/packet-mongo.c
++++ b/epan/dissectors/packet-mongo.c
+@@ -12,9 +12,9 @@
+ 
+ /*
+  * See Mongo Wire Protocol Specification
+- * http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
++ * https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/
+  * See also BSON Specification
+- * http://bsonspec.org/#/specification
++ * http://bsonspec.org/spec.html
+  */
+ 
+ #include "config.h"
+@@ -23,6 +23,7 @@
+ #include <epan/exceptions.h>
+ #include <epan/expert.h>
+ #include <epan/proto_data.h>
++#include <epan/exceptions.h>
+ #include "packet-tcp.h"
+ #include "packet-tls.h"
+ #ifdef HAVE_SNAPPY
+@@ -278,6 +279,7 @@ static gint ett_mongo_doc_sequence= -1;
+ 
+ static expert_field ei_mongo_document_recursion_exceeded = EI_INIT;
+ static expert_field ei_mongo_document_length_bad = EI_INIT;
++static expert_field ei_mongo_section_size_bad = EI_INIT;
+ static expert_field ei_mongo_unknown = EI_INIT;
+ static expert_field ei_mongo_unsupported_compression = EI_INIT;
+ static expert_field ei_mongo_too_large_compressed = EI_INIT;
+@@ -790,13 +792,21 @@ dissect_op_msg_section(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tr
+   gint section_len = -1;   /* Section length */
+ 
+   e_type = tvb_get_guint8(tvb, offset);
+-  section_len = tvb_get_letohl(tvb, offset+1);
+ 
+-  ti = proto_tree_add_item(tree, hf_mongo_msg_sections_section, tvb, offset, 1 + section_len, ENC_NA);
++  ti = proto_tree_add_item(tree, hf_mongo_msg_sections_section, tvb, offset, 1, ENC_NA);
+   section_tree = proto_item_add_subtree(ti, ett_mongo_section);
+   proto_tree_add_item(section_tree, hf_mongo_msg_sections_section_kind, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+   offset += 1;
+ 
++  section_len = tvb_get_letohil(tvb, offset);
++  /* The section length must be strictly smaller than the total message size,
++   * both signed int32s. This prevents signed integer overflow. */
++  if (section_len < 0 || section_len == INT32_MAX) {
++    proto_tree_add_expert_format(section_tree, pinfo, &ei_mongo_section_size_bad, tvb, offset, 4, "Bogus Mongo message section size: %i", section_len);
++    THROW(ReportedBoundsError);
++  }
++  proto_item_set_len(ti, 1 + section_len);
++
+   switch (e_type) {
+     case KIND_BODY:
+       section_len = dissect_bson_document(tvb, pinfo, offset, section_tree, hf_mongo_msg_sections_section_body);
+@@ -1464,6 +1474,7 @@ proto_register_mongo(void)
+   static ei_register_info ei[] = {
+      { &ei_mongo_document_recursion_exceeded, { "mongo.document.recursion_exceeded", PI_MALFORMED, PI_ERROR, "BSON document recursion exceeds", EXPFILL }},
+      { &ei_mongo_document_length_bad, { "mongo.document.length.bad",  PI_MALFORMED, PI_ERROR, "BSON document length bad", EXPFILL }},
++     { &ei_mongo_section_size_bad, { "mongo.msg.sections.section.size.bad",  PI_MALFORMED, PI_ERROR, "Bogus Mongo message section size", EXPFILL }},
+      { &ei_mongo_unknown, { "mongo.unknown.expert", PI_UNDECODED, PI_WARN, "Unknown Data (not interpreted)", EXPFILL }},
+      { &ei_mongo_unsupported_compression, { "mongo.unsupported_compression.expert", PI_UNDECODED, PI_WARN, "This packet was compressed with an unsupported compressor", EXPFILL }},
+      { &ei_mongo_too_large_compressed, { "mongo.too_large_compressed.expert", PI_UNDECODED, PI_WARN, "The size of the uncompressed packet exceeded the maximum allowed value", EXPFILL }},
diff --git a/debian/patches/CVE-2025-13499.patch b/debian/patches/CVE-2025-13499.patch
new file mode 100644
index 0000000000..5f4cabddbd
--- /dev/null
+++ b/debian/patches/CVE-2025-13499.patch
@@ -0,0 +1,39 @@
+From: Darius Davis <[email protected]>
+Date: Sat, 25 Oct 2025 15:01:34 +1000
+Subject: Kafka: Fix decompress_snappy with no xerial chunks.
+
+Instead of returning true without setting outputs, report a failure to
+decompress and return false to the caller.
+
+Fix #20823
+
+(cherry picked from commit 49137f8ce93c9f7ac55b69c8e089ba6a422f633e)
+
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/22048
+---
+ epan/dissectors/packet-kafka.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/epan/dissectors/packet-kafka.c b/epan/dissectors/packet-kafka.c
+index d432d8d..5c05659 100644
+--- a/epan/dissectors/packet-kafka.c
++++ b/epan/dissectors/packet-kafka.c
+@@ -1791,6 +1791,7 @@ decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length,
+             count++;
+             DISSECTOR_ASSERT_HINT(count < MAX_LOOP_ITERATIONS, "MAX_LOOP_ITERATIONS exceeded");
+         }
++        ret = composite_tvb != NULL;
+ 
+     } else {
+ 
+@@ -1813,9 +1814,9 @@ decompress_snappy(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 length,
+ 
+         *decompressed_tvb = tvb_new_child_real_data(tvb, decompressed_buffer, (guint)out_size, (gint)out_size);
+         *decompressed_offset = 0;
++        ret = TRUE;
+ 
+     }
+-    ret = TRUE;
+ end:
+     if (composite_tvb) {
+         tvb_composite_finalize(composite_tvb);
diff --git a/debian/patches/CVE-2025-13945.patch b/debian/patches/CVE-2025-13945.patch
new file mode 100644
index 0000000000..ae8d74e87d
--- /dev/null
+++ b/debian/patches/CVE-2025-13945.patch
@@ -0,0 +1,333 @@
+From: John Thacker <[email protected]>
+Date: Fri, 14 Nov 2025 20:20:44 -0500
+Subject: epan: Use a GSequence for tvb_composite and make it non-recursive
+
+To speed up tvb_composites consisting of many child tvbuffs,
+use a GSequence. This is a data structure that internally has
+a balanced binary tree. It differs from GTree in that one can
+do initial insertions without sorting. In our case, the ordering
+at the time of tvb_composite_finalize is *the* ordering, and is
+the same ordering that comparing according to the calculated
+end offsets will have, so this is faster on insert than a GTree.
+
+Like a GTree, it is much faster O(log N) vs O(N) on lookup to find
+the location of the TVB with end offset greater than or equal to
+the desired offset than using a GQueue.
+
+Also, make composite_memcpy iterative instead of recursive, which
+removes the current hard limit of 500 without causing stack overflow
+with very large numbers of child TVBs.
+
+The file in #20860 works fine now but there could still be limits
+imposed (at least on the total number of bytes?) for a compression
+bomb more similar to the file found in #12077.
+
+(backported from commit 9139917bd8e2c80a5db7079993d5528db74e3519)
+
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/22318
+---
+ epan/tvbuff_composite.c | 177 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 114 insertions(+), 63 deletions(-)
+
+diff --git a/epan/tvbuff_composite.c b/epan/tvbuff_composite.c
+index 8c3d4cf..9d567d3 100644
+--- a/epan/tvbuff_composite.c
++++ b/epan/tvbuff_composite.c
+@@ -16,14 +16,49 @@
+ #include "proto.h"	/* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
+ 
+ typedef struct {
+-	GSList		*tvbs;
+-
++	tvbuff_t *tvb;
+ 	/* Used for quick testing to see if this
+ 	 * is the tvbuff that a COMPOSITE is
+ 	 * interested in. */
+-	guint		*start_offsets;
+-	guint		*end_offsets;
++	unsigned start_offset;
++	unsigned end_offset;
++} tvb_comp_member_t;
++
++static int
++tvb_comp_off_compare(const void *a, const void *b, void *user_data)
++{
++	tvb_comp_member_t* off_a = (tvb_comp_member_t*)a;
++	tvb_comp_member_t* off_b = (tvb_comp_member_t*)b;
++	tvb_comp_member_t* key = (tvb_comp_member_t*)user_data;
++
++	if (off_a->end_offset < off_b->end_offset)
++		return -1;
++	else if (off_a->end_offset > off_b->end_offset)
++		return 1;
++
++	/* This is a hack to ensure that in cases of ties, key is always
++	 * sorted first. This ensures that g_sequence_search returns an
++	 * iterator pointing to the tvb in the sequence with a matching
++	 * offset instead of the node after it. (It would be simpler but
++	 * somewhat slower to have the natural comparison function and
++	 * call g_sequence_lookup followed by g_sequence_search in case
++	 * of failure.)
++	 *
++	 * If we allowed zero length TVBs to be part of the composite,
++	 * we might have to search through all the TVBs with the same
++	 * end_offset to find the right one. (Or maybe we could just
++	 * no-op and not add the zero length TVBs?)
++	 */
++	if (off_a == key) {
++		return -1;
++	} else if (off_b == key) {
++		return 1;
++	}
++	return 0;
++}
+ 
++typedef struct {
++	GSequence	*tvbs;
+ } tvb_comp_t;
+ 
+ struct tvb_composite {
+@@ -38,11 +73,9 @@ composite_free(tvbuff_t *tvb)
+ 	struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
+ 	tvb_comp_t *composite = &composite_tvb->composite;
+ 
+-	g_slist_free(composite->tvbs);
++	g_sequence_free(composite->tvbs);
+ 
+-	g_free(composite->start_offsets);
+-	g_free(composite->end_offsets);
+-	g_free((gpointer)tvb->real_data);
++	g_free((void *)tvb->real_data);
+ }
+ 
+ static guint
+@@ -55,8 +88,8 @@ static const guint8*
+ composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
+ {
+ 	struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
+-	guint	    i, num_members;
+ 	tvb_comp_t *composite;
++	tvb_comp_member_t *member = NULL;
+ 	tvbuff_t   *member_tvb = NULL;
+ 	guint	    member_offset;
+ 	GSList	   *slist;
+@@ -66,23 +99,19 @@ composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length)
+ 	/* Maybe the range specified by offset/length
+ 	 * is contiguous inside one of the member tvbuffs */
+ 	composite = &composite_tvb->composite;
+-	num_members = g_slist_length(composite->tvbs);
+ 
+-	for (i = 0; i < num_members; i++) {
+-		if (abs_offset <= composite->end_offsets[i]) {
+-			slist = g_slist_nth(composite->tvbs, i);
+-			member_tvb = (tvbuff_t *)slist->data;
+-			break;
+-		}
+-	}
++	tvb_comp_member_t key = { .end_offset = abs_offset };
++	GSequenceIter *iter = g_sequence_search(composite->tvbs, &key, tvb_comp_off_compare, &key);
+ 
+ 	/* special case */
+-	if (!member_tvb) {
++	if (g_sequence_iter_is_end(iter)) {
+ 		DISSECTOR_ASSERT(abs_offset == tvb->length && abs_length == 0);
+ 		return "";
+ 	}
+ 
+-	member_offset = abs_offset - composite->start_offsets[i];
++	member = (tvb_comp_member_t *)g_sequence_get(iter);
++	member_tvb = member->tvb;
++	member_offset = abs_offset - member->start_offset;
+ 
+ 	if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) {
+ 		/*
+@@ -108,8 +137,8 @@ composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, guint abs_lengt
+ 	struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
+ 	guint8 *target = (guint8 *) _target;
+ 
+-	guint	    i, num_members;
+ 	tvb_comp_t *composite;
++	tvb_comp_member_t *member = NULL;
+ 	tvbuff_t   *member_tvb = NULL;
+ 	guint	    member_offset, member_length;
+ 	GSList	   *slist;
+@@ -119,23 +148,18 @@ composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, guint abs_lengt
+ 	/* Maybe the range specified by offset/length
+ 	 * is contiguous inside one of the member tvbuffs */
+ 	composite   = &composite_tvb->composite;
+-	num_members = g_slist_length(composite->tvbs);
+-
+-	for (i = 0; i < num_members; i++) {
+-		if (abs_offset <= composite->end_offsets[i]) {
+-			slist = g_slist_nth(composite->tvbs, i);
+-			member_tvb = (tvbuff_t *)slist->data;
+-			break;
+-		}
+-	}
++	tvb_comp_member_t key = { .end_offset = abs_offset };
++	GSequenceIter *iter = g_sequence_search(composite->tvbs, &key, tvb_comp_off_compare, &key);
+ 
+ 	/* special case */
+-	if (!member_tvb) {
++	if (g_sequence_iter_is_end(iter)) {
+ 		DISSECTOR_ASSERT(abs_offset == tvb->length && abs_length == 0);
+ 		return target;
+ 	}
+ 
+-	member_offset = abs_offset - composite->start_offsets[i];
++	member = (tvb_comp_member_t *)g_sequence_get(iter);
++	member_tvb = member->tvb;
++	member_offset = abs_offset - member->start_offset;
+ 
+ 	if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) {
+ 		DISSECTOR_ASSERT(!tvb->real_data);
+@@ -147,18 +171,32 @@ composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, guint abs_lengt
+ 		 * then iterate across the other member tvb's, copying their portions
+ 		 * until we have copied all data.
+ 		 */
+-		member_length = tvb_captured_length_remaining(member_tvb, member_offset);
+ 
+-		/* composite_memcpy() can't handle a member_length of zero. */
+-		DISSECTOR_ASSERT(member_length > 0);
++		unsigned target_offset = 0;
++		while (abs_length) {
+ 
+-		tvb_memcpy(member_tvb, target, member_offset, member_length);
+-		abs_offset	+= member_length;
+-		abs_length	-= member_length;
++			member_length = tvb_captured_length_remaining(member_tvb, member_offset);
+ 
+-		/* Recurse */
+-		if (abs_length > 0) {
+-			composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
++			/* composite_memcpy() can't handle a member_length of zero. */
++			DISSECTOR_ASSERT(member_length > 0);
++
++			member_length = MIN(member_length, abs_length);
++
++			tvb_memcpy(member_tvb, target + target_offset, member_offset, member_length);
++			target_offset   += member_length;
++			abs_offset	+= member_length;
++			abs_length	-= member_length;
++
++			if (!abs_length)
++				break;
++			iter = g_sequence_iter_next(iter);
++			/* tvb_memcpy calls check_offset_length and so there
++			 * should be enough captured length to copy. */
++			DISSECTOR_ASSERT(!g_sequence_iter_is_end(iter));
++
++			member = (tvb_comp_member_t *)g_sequence_get(iter);
++			member_tvb = member->tvb;
++			member_offset = 0;
+ 		}
+ 
+ 		return target;
+@@ -198,9 +236,7 @@ tvb_new_composite(void)
+ 	struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
+ 	tvb_comp_t *composite = &composite_tvb->composite;
+ 
+-	composite->tvbs		 = NULL;
+-	composite->start_offsets = NULL;
+-	composite->end_offsets	 = NULL;
++	composite->tvbs		 = g_sequence_new(g_free);
+ 
+ 	return tvb;
+ }
+@@ -219,12 +255,15 @@ tvb_composite_append(tvbuff_t *tvb, tvbuff_t *member)
+ 	 */
+ 	if (member && member->length) {
+ 		composite       = &composite_tvb->composite;
+-		composite->tvbs = g_slist_append(composite->tvbs, member);
+-
+ 		/* Attach the composite TVB to the first TVB only. */
+-		if (!composite->tvbs->next) {
+-			tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb);
++		if (g_sequence_is_empty(composite->tvbs)) {
++			tvb_add_to_chain(member, tvb);
+ 		}
++		tvb_comp_member_t *new_member = g_new(tvb_comp_member_t, 1);
++		new_member->tvb = member;
++		new_member->start_offset = 0;
++		new_member->end_offset = 0;
++		g_sequence_append(composite->tvbs, new_member);
+ 	}
+ }
+ 
+@@ -242,12 +281,15 @@ tvb_composite_prepend(tvbuff_t *tvb, tvbuff_t *member)
+ 	 */
+ 	if (member && member->length) {
+ 		composite       = &composite_tvb->composite;
+-		composite->tvbs = g_slist_prepend(composite->tvbs, member);
+-
+ 		/* Attach the composite TVB to the first TVB only. */
+-		if (!composite->tvbs->next) {
+-			tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb);
++		if (g_sequence_is_empty(composite->tvbs)) {
++			tvb_add_to_chain(member, tvb);
+ 		}
++		tvb_comp_member_t *new_member = g_new(tvb_comp_member_t, 1);
++		new_member->tvb = member;
++		new_member->start_offset = 0;
++		new_member->end_offset = 0;
++		g_sequence_prepend(composite->tvbs, new_member);
+ 	}
+ }
+ 
+@@ -255,8 +297,9 @@ void
+ tvb_composite_finalize(tvbuff_t *tvb)
+ {
+ 	struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb;
+-	GSList	   *slist;
+-	guint	    num_members;
++
++	unsigned	num_members;
++	tvb_comp_member_t *member;
+ 	tvbuff_t   *member_tvb;
+ 	tvb_comp_t *composite;
+ 	int	    i = 0;
+@@ -268,26 +311,34 @@ tvb_composite_finalize(tvbuff_t *tvb)
+ 	DISSECTOR_ASSERT(tvb->contained_length == 0);
+ 
+ 	composite   = &composite_tvb->composite;
+-	num_members = g_slist_length(composite->tvbs);
++
++	num_members = g_sequence_get_length(composite->tvbs);
+ 
+ 	/* Dissectors should not create composite TVBs if they're not going to
+ 	 * put at least one TVB in them.
+ 	 * (Without this check--or something similar--we'll seg-fault below.)
++	 * (XXX - Now with a GSequence we shouldn't segfault, we'll get the
++	 * end iterator and it should work, so we could remove this and some
++	 * checks in dissectors to simplify their code.)
+ 	 */
+ 	DISSECTOR_ASSERT(num_members);
+ 
+-	composite->start_offsets = g_new(guint, num_members);
+-	composite->end_offsets = g_new(guint, num_members);
+-
+-	for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
+-		DISSECTOR_ASSERT((guint) i < num_members);
+-		member_tvb = (tvbuff_t *)slist->data;
+-		composite->start_offsets[i] = tvb->length;
++	/* Record the offsets - we have to do that now because it's possible
++	 * to prepend TVBs. Note that the GSequence is already sorted according
++	 * to these offsets, we're just noting them, so we don't need to sort.
++	 */
++	GSequenceIter *iter = g_sequence_get_begin_iter(composite->tvbs);
++	for (i=0; i < num_members; i++, iter=g_sequence_iter_next(iter)) {
++		member = (tvb_comp_member_t *)g_sequence_get(iter);
++		member_tvb = member->tvb;
++		member->start_offset = tvb->length;
+ 		tvb->length += member_tvb->length;
++		/* XXX - What does it mean to make a composite TVB out of
++		 * TVBs with length shorter than their reported length?
++		 */
+ 		tvb->reported_length += member_tvb->reported_length;
+ 		tvb->contained_length += member_tvb->contained_length;
+-		composite->end_offsets[i] = tvb->length - 1;
+-		i++;
++		member->end_offset = tvb->length - 1;
+ 	}
+ 
+ 	tvb->initialized = TRUE;
diff --git a/debian/patches/CVE-2025-13946.patch b/debian/patches/CVE-2025-13946.patch
new file mode 100644
index 0000000000..1470550146
--- /dev/null
+++ b/debian/patches/CVE-2025-13946.patch
@@ -0,0 +1,42 @@
+From: AndersBroman <[email protected]>
+Date: Mon, 1 Dec 2025 08:41:55 +0100
+Subject: MEGACO: Handle tvb_get_uint8 returning -1
+
+When dissecting a media descriptor, handle tvb_get_uint8 returning
+-1 when searching for a left or right bracket and not finding it
+by setting the bracket offset to the end offset so that the loop
+will exit. Leaving it at -1 can cause going backwards and at worst
+infinite loops.
+
+Fix #20884
+
+(cherry picked from commit aba1fbe6266beb6bf9b887b6eab008e4f4841c9b)
+
+Co-authored-by: John Thacker <[email protected]>
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/22553
+---
+ epan/dissectors/packet-megaco.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/epan/dissectors/packet-megaco.c b/epan/dissectors/packet-megaco.c
+index dda9336..c248d70 100644
+--- a/epan/dissectors/packet-megaco.c
++++ b/epan/dissectors/packet-megaco.c
+@@ -1772,8 +1772,15 @@ dissect_megaco_mediadescriptor(tvbuff_t *tvb, proto_tree *megaco_tree_command_li
+         mediaParm = find_megaco_mediaParm_names(tvb, tvb_current_offset, tokenlen);
+ 
+         tvb_LBRKT = tvb_find_guint8(tvb, tvb_next_offset , tvb_last_RBRKT, '{');
+-        tvb_next_offset = tvb_find_guint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, '}');
+-        tvb_RBRKT = tvb_next_offset;
++        if (tvb_LBRKT == -1) {
++            // Not found, use the end offset.
++            tvb_LBRKT = tvb_last_RBRKT;
++        }
++        tvb_RBRKT = tvb_find_guint8(tvb, tvb_current_offset+1 , tvb_last_RBRKT, '}');
++        if (tvb_RBRKT == -1) {
++            // Not found, use the end offset.
++            tvb_RBRKT = tvb_last_RBRKT;
++        }
+ 
+         switch ( mediaParm ){
+         case MEGACO_LOCAL_TOKEN:
diff --git a/debian/patches/CVE-2025-1492.patch b/debian/patches/CVE-2025-1492.patch
new file mode 100644
index 0000000000..8372b18efa
--- /dev/null
+++ b/debian/patches/CVE-2025-1492.patch
@@ -0,0 +1,84 @@
+From: Gerald Combs <[email protected]>
+Date: Wed, 5 Feb 2025 19:55:12 -0800
+Subject: wscbor: Add a recursion check
+
+Blind-ish attempt at fixing #20373
+
+(cherry picked from commit 83c73a83ad9ec7baa4bbf06d6da9cdd91009d5ed)
+
+ Conflicts:
+	epan/wscbor.c
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/19002
+---
+ epan/wscbor.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/epan/wscbor.c b/epan/wscbor.c
+index 47355cc..40a37b7 100644
+--- a/epan/wscbor.c
++++ b/epan/wscbor.c
+@@ -16,6 +16,7 @@
+ #include <epan/packet.h>
+ #include <epan/exceptions.h>
+ #include <epan/expert.h>
++#include <epan/prefs.h>
+ #include <stdio.h>
+ #include <inttypes.h>
+ #include "wscbor.h"
+@@ -358,7 +359,11 @@ gboolean wscbor_is_indefinite_break(const wscbor_chunk_t *chunk) {
+     );
+ }
+ 
+-gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset) {
++gboolean wscbor_skip_next_item_internal(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset, unsigned depth) {
++    if (depth > prefs.gui_max_tree_depth) {
++
++        return false;
++    }
+     wscbor_chunk_t *chunk = wscbor_chunk_read(alloc, tvb, offset);
+     switch (chunk->type_major) {
+         case CBOR_TYPE_UINT:
+@@ -373,12 +378,12 @@ gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *off
+         case CBOR_TYPE_ARRAY: {
+             if (chunk->type_minor == 31) {
+                 // wait for indefinite break
+-                while (!wscbor_skip_next_item(alloc, tvb, offset)) {}
++                while (!wscbor_skip_next_item_internal(alloc, tvb, offset, depth + 1)) {}
+             }
+             else {
+                 const guint64 count = chunk->head_value;
+                 for (guint64 ix = 0; ix < count; ++ix) {
+-                    wscbor_skip_next_item(alloc, tvb, offset);
++                    wscbor_skip_next_item_internal(alloc, tvb, offset, depth + 1);
+                 }
+             }
+             break;
+@@ -386,13 +391,13 @@ gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *off
+         case CBOR_TYPE_MAP: {
+             if (chunk->type_minor == 31) {
+                 // wait for indefinite break
+-                while (!wscbor_skip_next_item(alloc, tvb, offset)) {}
++                while (!wscbor_skip_next_item_internal(alloc, tvb, offset, depth + 1)) {}
+             }
+             else {
+                 const guint64 count = chunk->head_value;
+                 for (guint64 ix = 0; ix < count; ++ix) {
+-                    wscbor_skip_next_item(alloc, tvb, offset);
+-                    wscbor_skip_next_item(alloc, tvb, offset);
++                    wscbor_skip_next_item_internal(alloc, tvb, offset, depth + 1);
++                    wscbor_skip_next_item_internal(alloc, tvb, offset, depth + 1);
+                 }
+             }
+             break;
+@@ -403,6 +408,11 @@ gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *off
+     return is_break;
+ }
+ 
++gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset) {
++    wscbor_skip_next_item_internal(alloc, tvb, offset, 0);
++}
++
++
+ gboolean wscbor_skip_if_errors(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset, const wscbor_chunk_t *chunk) {
+     if (wscbor_has_errors(chunk) == 0) {
+         return FALSE;
diff --git a/debian/patches/CVE-2025-5601.patch b/debian/patches/CVE-2025-5601.patch
new file mode 100644
index 0000000000..4930b883fd
--- /dev/null
+++ b/debian/patches/CVE-2025-5601.patch
@@ -0,0 +1,58 @@
+From: John Thacker <[email protected]>
+Date: Sat, 26 Apr 2025 10:01:19 +0000
+Subject: column: Do not allow fence to go beyond column size when prepending
+
+When moving the fence location forward when prepending, ensure
+that it does not go past the end of the buffer.
+
+Also get rid of unnecessary branching and strlen calls.
+
+Fix #20509
+
+(cherry picked from commit 53213086304caa3dfbdd7dc39c2668a3aea1a5c0)
+
+Co-authored-by: John Thacker <[email protected]>
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/18076/diffs?commit_id=8c186dbb381cf51064fa8dbff7953468d5ae394c
+---
+ epan/column-utils.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/epan/column-utils.c b/epan/column-utils.c
+index e80558d..6886608 100644
+--- a/epan/column-utils.c
++++ b/epan/column-utils.c
+@@ -578,8 +578,13 @@ col_prepend_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
+       /*
+        * Move the fence, unless it's at the beginning of the string.
+        */
+-      if (col_item->col_fence > 0)
++      if (col_item->col_fence > 0) {
++        /* pos >= strlen if truncation occurred; this saves on a strlen
++         * call and prevents adding a single byte character later if a
++         * a multibyte character was truncated (good). */
+         col_item->col_fence += (int) strlen(col_item->col_buf);
++        col_item->col_fence = MIN((int)(max_len - 1), col_item->col_fence);
++      }
+ 
+       (void) g_strlcat(col_item->col_buf, orig, max_len);
+       col_item->col_data = col_item->col_buf;
+@@ -622,11 +627,14 @@ col_prepend_fence_fstr(column_info *cinfo, const gint el, const gchar *format, .
+        * Move the fence if it exists, else create a new fence at the
+        * end of the prepended data.
+        */
+-      if (col_item->col_fence > 0) {
+-        col_item->col_fence += (int) strlen(col_item->col_buf);
+-      } else {
+-        col_item->col_fence = (int) strlen(col_item->col_buf);
+-      }
++      /* pos >= strlen if truncation occurred; this saves on a strlen
++       * call and prevents adding a single byte character later if a
++       * a multibyte character was truncated (good). */
++      col_item->col_fence += (int) strlen(col_item->col_buf);
++      col_item->col_fence = MIN((int)(max_len - 1), col_item->col_fence);
++      /*
++       * Append the original data.
++       */
+       (void) g_strlcat(col_item->col_buf, orig, max_len);
+       col_item->col_data = col_item->col_buf;
+     }
diff --git a/debian/patches/CVE-2025-9817.patch b/debian/patches/CVE-2025-9817.patch
new file mode 100644
index 0000000000..0bb8c6f686
--- /dev/null
+++ b/debian/patches/CVE-2025-9817.patch
@@ -0,0 +1,30 @@
+From: John Thacker <[email protected]>
+Date: Sat, 26 Jul 2025 11:48:36 +0000
+Subject: ssh: Add a null check
+
+Fix #20642
+
+(cherry picked from commit 39daba5e247ea495f88b0be82f0b7ebbdbf50fba)
+
+Co-authored-by: John Thacker <[email protected]>
+
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/20668
+---
+ epan/dissectors/packet-ssh.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/epan/dissectors/packet-ssh.c b/epan/dissectors/packet-ssh.c
+index fea3f29..9cda842 100644
+--- a/epan/dissectors/packet-ssh.c
++++ b/epan/dissectors/packet-ssh.c
+@@ -2315,6 +2315,10 @@ ssh_kex_shared_secret(gint kex_type, ssh_bignum *pub, ssh_bignum *priv, ssh_bign
+     }
+ 
+     if(kex_type==SSH_KEX_DH_GEX){
++        if (modulo == NULL) {
++            ws_debug("Missing group modulo");
++            return NULL;
++        }
+         gcry_mpi_t b = NULL;
+         gcry_mpi_scan(&b, GCRYMPI_FMT_USG, pub->data, pub->length, NULL);
+         gcry_mpi_t d = NULL, e = NULL, m = NULL;
diff --git a/debian/patches/CVE-2026-0960.patch b/debian/patches/CVE-2026-0960.patch
new file mode 100644
index 0000000000..1ed9c97ab6
--- /dev/null
+++ b/debian/patches/CVE-2026-0960.patch
@@ -0,0 +1,36 @@
+From: John Thacker <[email protected]>
+Date: Mon, 12 Jan 2026 15:28:22 +0000
+Subject: QUIC: Update reassembly ID for a new MSP
+
+When a QUIC frame has more than one MSP, the reassembly id for the
+second MSP has to be used when adding or looking it up, instead of
+the original reassembly id of the first MSP.
+
+Fixes reassembly of the file in #20944 in most cases, outside of issues
+with out of order UDP packets / QUIC packets.
+
+(cherry picked from commit 562c3c070c6f58d01904d42338489b1a64ad7655)
+
+Co-authored-by: John Thacker <[email protected]>
+origin: https://gitlab.com/wireshark/wireshark/-/merge_requests/23175
+---
+ epan/dissectors/packet-quic.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c
+index a470f83..d592c02 100644
+--- a/epan/dissectors/packet-quic.c
++++ b/epan/dissectors/packet-quic.c
+@@ -1669,9 +1669,10 @@ again:
+                     deseg_seq, nxtseq+pinfo->desegment_len, stream->multisegment_pdus);
+             }
+ 
+-            /* add this segment as the first one for this new pdu */
++            /* add this segment as the first one for this new pdu
++             * Use the the new MSP's reassembly ID (its first frame). */
+             fragment_add(&quic_reassembly_table, tvb, deseg_offset,
+-                         pinfo, reassembly_id, NULL,
++                         pinfo, msp->first_frame, stream_info,
+                          0, nxtseq - deseg_seq,
+                          nxtseq < msp->nxtpdu);
+         }
diff --git a/debian/patches/series b/debian/patches/series
index 3834e173fe..0059d68b6b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,13 @@
 09_idl2wrs.patch
 0004-Use-packaged-JS-and-CSS-resources-instead-of-pulling.patch
 0001-DOCSIS-Extended-EH-Elements-are-not-recursive.patch
+CVE-2024-11596.patch
+CVE-2025-5601.patch
+CVE-2024-9781.patch
+CVE-2025-9817.patch
+CVE-2025-11626.patch
+CVE-2025-13499.patch
+CVE-2025-13945.patch
+CVE-2025-13946.patch
+CVE-2026-0960.patch
+CVE-2025-1492.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to