From 043a129b2907da02faa33f1df912de46643ca773 Mon Sep 17 00:00:00 2001
From: Michael Mann <mmann78@netscape.net>
Date: Tue, 31 Mar 2026 09:21:17 -0400
Subject: [PATCH] kismet: General improvements (and fix Heap-Buffer-Overflow)

1. use proto_tree_add_item instead of proto_tree_add_string (fixes Heap-Buffer-Overflow and just generally a better approach)
2. Use tvb_ascii_isprint to ensure characters are ASCII
3. response_is_continuation only checks a single character, not a string, so adjust accordingly

Fixes #21129

AI-Assisted: no
(backported from commit cd6e74e5d60dbc0a7cdf3c0f038cf22d06a24e7f)
---
 epan/dissectors/packet-kismet.c | 57 ++++++++++++---------------------
 1 file changed, 21 insertions(+), 36 deletions(-)

Index: wireshark-3.6.24/epan/dissectors/packet-kismet.c
===================================================================
--- wireshark-3.6.24.orig/epan/dissectors/packet-kismet.c
+++ wireshark-3.6.24/epan/dissectors/packet-kismet.c
@@ -38,7 +38,7 @@ static expert_field ei_time_invalid = EI
 
 #define TCP_PORT_KISMET	2501 /* Not IANA registered */
 
-static gboolean response_is_continuation(const guchar * data);
+static gboolean response_is_continuation(guchar data);
 void proto_reg_handoff_kismet(void);
 void proto_register_kismet(void);
 
@@ -55,7 +55,6 @@ dissect_kismet(tvbuff_t * tvb, packet_in
 	gint next_offset;
 	int linelen;
 	int tokenlen;
-	int i;
 	const guchar *next_token;
 
 	/*
@@ -72,20 +71,11 @@ dissect_kismet(tvbuff_t * tvb, packet_in
 	 * Check if it is an ASCII based protocol with reasonable length
 	 * packets, if not return, and try another dissector.
 	 */
-	if (linelen < 8) {
-		/*
-		 * Packet is too short
-		 */
+	if (linelen < 8)
+		return 0;
+
+	if (!tvb_ascii_isprint(tvb, offset, 8))
 		return 0;
-	} else {
-		for (i = 0; i < 8; ++i) {
-			/*
-			 * Packet contains non-ASCII data
-			 */
-			if (line[i] < 32 || line[i] > 128)
-				return 0;
-		}
-	}
 
 	/*
 	 * If it is Kismet traffic set COL_PROTOCOL.
@@ -100,7 +90,7 @@ dissect_kismet(tvbuff_t * tvb, packet_in
 		is_continuation = FALSE;
 	} else {
 		is_request = FALSE;
-		is_continuation = response_is_continuation (line);
+		is_continuation = response_is_continuation(line[0]);
 	}
 
 	/*
@@ -170,48 +160,42 @@ dissect_kismet(tvbuff_t * tvb, packet_in
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_version, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line, tokenlen));
+						proto_tree_add_item(reqresp_tree, hf_kismet_version, tvb, offset, tokenlen, ENC_ASCII);
 
 						offset += (gint) (next_token - line);
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_start_time, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line, tokenlen));
+						proto_tree_add_item(reqresp_tree, hf_kismet_start_time, tvb, offset, tokenlen, ENC_ASCII);
 
 						offset += (gint) (next_token - line);
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_server_name, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line + 1, tokenlen - 2));
-
+						proto_tree_add_item(reqresp_tree, hf_kismet_server_name, tvb, offset+1, tokenlen-2, ENC_ASCII);
+ 
 						offset += (gint) (next_token - line);
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_build_revision, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line, tokenlen));
+						proto_tree_add_item(reqresp_tree, hf_kismet_build_revision, tvb, offset, tokenlen, ENC_ASCII);
 
 						offset += (gint) (next_token - line);
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_unknown_field, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line, tokenlen));
+						proto_tree_add_item(reqresp_tree, hf_kismet_unknown_field, tvb, offset, tokenlen, ENC_ASCII);
 
 						offset += (gint) (next_token - line);
 						linelen -= (int) (next_token - line);
 						line = next_token;
 						tokenlen = get_token_len(line, line + linelen, &next_token);
-						proto_tree_add_string(reqresp_tree, hf_kismet_extended_version_string, tvb, offset,
-							tokenlen, format_text(pinfo->pool, line, tokenlen));
+						proto_tree_add_item(reqresp_tree, hf_kismet_extended_version_string, tvb, offset, tokenlen, ENC_ASCII);
 					}
 					/*
 					 * *TIME: {Time}
 					 */
-					if (!strncmp(reqresp, "*TIME", 5)) {
+					else if (!strncmp(reqresp, "*TIME", 5)) {
 						nstime_t t;
 						char *ptr = NULL;
 						proto_tree* time_item;
@@ -250,15 +234,16 @@ dissect_kismet(tvbuff_t * tvb, packet_in
 }
 
 static gboolean
-response_is_continuation(const guchar * data)
+response_is_continuation(guchar data)
 {
-	if (!strncmp(data, "*", 1))
-		return FALSE;
-
-	if (!strncmp(data, "!", 1))
-		return FALSE;
-
-	return TRUE;
+	switch (data)
+	{
+		case '*':
+		case '!':
+			return FALSE;
+		default:
+			return TRUE;
+	}
 }
 
 void
