summaryrefslogtreecommitdiffstats
path: root/meta-networking/recipes-support/wireshark/files/CVE-2026-0962.patch
blob: 615b11eb7f67ce2ca3fc09e72cbd1490d2300e76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From 4b1c045a4639b54a0aea717667a30c01c683001c Mon Sep 17 00:00:00 2001
From: Gerald Combs <gerald@wireshark.org>
Date: Mon, 12 Jan 2026 17:01:48 -0800
Subject: [PATCH] SOME/IP-SD: Fix a buffer overflow

Make sure we don't write past the end of our option port array. Make our
option count unsigned.

Fixes #20945

(cherry picked from commit 55ec8b3db4968c97115f014fb5974206cdf57454)

Conflicts:
	epan/dissectors/packet-someip-sd.c

CVE: CVE-2026-0962
Upstream-Status: Backport [https://gitlab.com/wireshark/wireshark/-/commit/825b83e1ed146f6c8fa8f1d7ad2794061b82c895]
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
---
 epan/dissectors/packet-someip-sd.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/epan/dissectors/packet-someip-sd.c b/epan/dissectors/packet-someip-sd.c
index 85144d5..79935bb 100644
--- a/epan/dissectors/packet-someip-sd.c
+++ b/epan/dissectors/packet-someip-sd.c
@@ -242,6 +242,7 @@ static expert_field ef_someipsd_option_unknown = EI_INIT;
 static expert_field ef_someipsd_option_wrong_length = EI_INIT;
 static expert_field ef_someipsd_L4_protocol_unsupported = EI_INIT;
 static expert_field ef_someipsd_config_string_malformed = EI_INIT;
+static expert_field ef_someipsd_too_many_options = EI_INIT;
 
 /*** prototypes ***/
 void proto_register_someip_sd(void);
@@ -274,7 +275,7 @@ someip_sd_register_ports(guint32 opt_index, guint32 opt_num, guint32 option_coun
 }
 
 static void
-dissect_someip_sd_pdu_option_configuration(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
+dissect_someip_sd_pdu_option_configuration(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, unsigned optionnum) {
     guint32         offset_orig = offset;
     const guint8   *config_string;
     proto_item     *ti;
@@ -317,7 +318,7 @@ dissect_someip_sd_pdu_option_configuration(tvbuff_t *tvb, packet_info *pinfo, pr
 }
 
 static void
-dissect_someip_sd_pdu_option_loadbalancing(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
+dissect_someip_sd_pdu_option_loadbalancing(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint32 length, unsigned optionnum) {
     tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, NULL, "%d: Load Balancing Option", optionnum);
 
     /* Add common fields */
@@ -337,7 +338,7 @@ dissect_someip_sd_pdu_option_loadbalancing(tvbuff_t *tvb, packet_info *pinfo _U_
 }
 
 static void
-dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum, guint32 option_ports[]) {
+dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, unsigned optionnum, guint32 option_ports[]) {
     guint8              type = 255;
     const gchar        *description = NULL;
     guint32             l4port = 0;
@@ -350,7 +351,7 @@ dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
     type = tvb_get_guint8(tvb, offset + 2);
     description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
-    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
+    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%u: %s Option", optionnum, description);
 
     if (length != SD_OPTION_IPV4_LENGTH) {
         expert_add_info(pinfo, ti_top, &ef_someipsd_option_wrong_length);
@@ -391,7 +392,7 @@ dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 }
 
 static void
-dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum, guint32 option_ports[]) {
+dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, unsigned optionnum, guint32 option_ports[]) {
     guint8              type = 255;
     const gchar        *description = NULL;
     guint32             l4port = 0;
@@ -404,7 +405,7 @@ dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree
     type = tvb_get_guint8(tvb, offset + 2);
     description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
 
-    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
+    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%u: %s Option", optionnum, description);
 
     if (length != SD_OPTION_IPV6_LENGTH) {
         expert_add_info(pinfo, ti_top, &ef_someipsd_option_wrong_length);
@@ -444,11 +445,11 @@ dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 }
 
 static void
-dissect_someip_sd_pdu_option_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
+dissect_someip_sd_pdu_option_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, unsigned optionnum) {
     guint32             len = 0;
     proto_item         *ti;
 
-    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti, "%d: %s Option", optionnum,
+    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti, "%u: %s Option", optionnum,
         val_to_str_const(tvb_get_guint8(tvb, offset + 2), sd_option_type, "Unknown"));
 
     expert_add_info(pinfo, ti, &ef_someipsd_option_unknown);
@@ -473,7 +474,7 @@ static int
 dissect_someip_sd_pdu_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint32 offset_orig, guint32 length, guint32 option_ports[], guint *option_count) {
     guint16             real_length = 0;
     guint8              option_type = 0;
-    int                 optionnum = 0;
+    unsigned            optionnum = 0;
     tvbuff_t           *subtvb = NULL;
 
     guint32             offset = offset_orig;
@@ -484,7 +485,10 @@ dissect_someip_sd_pdu_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
     }
 
     while (tvb_bytes_exist(tvb, offset, SD_OPTION_MINLENGTH)) {
-        ws_assert(optionnum >= 0 && optionnum < SD_MAX_NUM_OPTIONS);
+        if (optionnum >= SD_MAX_NUM_OPTIONS) {
+            expert_add_info(pinfo, ti, &ef_someipsd_too_many_options);
+            return offset;
+        }
         option_ports[optionnum] = 0;
 
         real_length = tvb_get_ntohs(tvb, offset) + 3;
@@ -1195,6 +1199,7 @@ proto_register_someip_sd(void) {
         { &ef_someipsd_option_wrong_length,{ "someipsd.option_wrong_length", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Option length is incorrect!", EXPFILL } },
         { &ef_someipsd_L4_protocol_unsupported,{ "someipsd.L4_protocol_unsupported", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Unsupported Layer 4 Protocol!", EXPFILL } },
         { &ef_someipsd_config_string_malformed,{ "someipsd.config_string_malformed", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Configuration String malformed!", EXPFILL } },
+        { &ef_someipsd_too_many_options,{ "someipsd.too_many_options", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Too many options!", EXPFILL } },
     };
 
     /* Register Protocol, Fields, ETTs, Expert Info, Taps, Dissector */