summaryrefslogtreecommitdiffstats
path: root/recipes-networking/openvswitch/openvswitch-git/CVE-2020-35498.patch
blob: 5093f077d4886563b08f237ddc0d41c391e3c865 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
rom 0625dc79aec73b966f206e55655a2816696246d0 Mon Sep 17 00:00:00 2001
From: Flavio Leitner <fbl@sysclose.org>
Date: Mon, 26 Oct 2020 16:03:19 -0300
Subject: [PATCH] flow: Support extra padding length.

Although not required, padding can be optionally added until
the packet length is MTU bytes. A packet with extra padding
currently fails sanity checks.

Vulnerability: CVE-2020-35498
Fixes: fa8d9001a624 ("miniflow_extract: Properly handle small IP packets.")
Reported-by: Joakim Hindersson <joakim.hindersson@elastx.se>
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Flavio Leitner <fbl@sysclose.org>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>

Upstream-Status: Backport [https://github.com/openvswitch/ovs/commit/0625dc79aec73b966f206e55655a2816696246d0]
CVE: CVE-2020-35498
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 lib/conntrack.c     |  2 +-
 lib/dp-packet.h     | 10 +++++-----
 lib/flow.c          |  6 +++---
 tests/classifier.at | 36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index ff5a89457..0f486d74c 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -813,7 +813,7 @@ static void
 reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn)
 {
     char *tail = dp_packet_tail(pkt);
-    uint8_t pad = dp_packet_l2_pad_size(pkt);
+    uint16_t pad = dp_packet_l2_pad_size(pkt);
     struct conn_key inner_key;
     const char *inner_l4 = NULL;
     uint16_t orig_l3_ofs = pkt->l3_ofs;
diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index 9f8991faa..45655af46 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -81,7 +81,7 @@ struct dp_packet {
 
     /* All the following elements of this struct are copied in a single call
      * of memcpy in dp_packet_clone_with_headroom. */
-    uint8_t l2_pad_size;           /* Detected l2 padding size.
+    uint16_t l2_pad_size;          /* Detected l2 padding size.
                                     * Padding is non-pullable. */
     uint16_t l2_5_ofs;             /* MPLS label stack offset, or UINT16_MAX */
     uint16_t l3_ofs;               /* Network-level header offset,
@@ -118,8 +118,8 @@ void *dp_packet_resize_l2(struct dp_packet *, int increment);
 void *dp_packet_resize_l2_5(struct dp_packet *, int increment);
 static inline void *dp_packet_eth(const struct dp_packet *);
 static inline void dp_packet_reset_offsets(struct dp_packet *);
-static inline uint8_t dp_packet_l2_pad_size(const struct dp_packet *);
-static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint8_t);
+static inline uint16_t dp_packet_l2_pad_size(const struct dp_packet *);
+static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint16_t);
 static inline void *dp_packet_l2_5(const struct dp_packet *);
 static inline void dp_packet_set_l2_5(struct dp_packet *, void *);
 static inline void *dp_packet_l3(const struct dp_packet *);
@@ -327,14 +327,14 @@ dp_packet_reset_offsets(struct dp_packet *b)
     b->l4_ofs = UINT16_MAX;
 }
 
-static inline uint8_t
+static inline uint16_t
 dp_packet_l2_pad_size(const struct dp_packet *b)
 {
     return b->l2_pad_size;
 }
 
 static inline void
-dp_packet_set_l2_pad_size(struct dp_packet *b, uint8_t pad_size)
+dp_packet_set_l2_pad_size(struct dp_packet *b, uint16_t pad_size)
 {
     ovs_assert(pad_size <= dp_packet_size(b));
     b->l2_pad_size = pad_size;
diff --git a/lib/flow.c b/lib/flow.c
index 45bb96b54..353d5cd3e 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -655,7 +655,7 @@ ipv4_sanity_check(const struct ip_header *nh, size_t size,
 
     tot_len = ntohs(nh->ip_tot_len);
     if (OVS_UNLIKELY(tot_len > size || ip_len > tot_len ||
-                size - tot_len > UINT8_MAX)) {
+                size - tot_len > UINT16_MAX)) {
         return false;
     }
 
@@ -693,8 +693,8 @@ ipv6_sanity_check(const struct ovs_16aligned_ip6_hdr *nh, size_t size)
     if (OVS_UNLIKELY(plen + IPV6_HEADER_LEN > size)) {
         return false;
     }
-    /* Jumbo Payload option not supported yet. */
-    if (OVS_UNLIKELY(size - (plen + IPV6_HEADER_LEN) > UINT8_MAX)) {
+
+    if (OVS_UNLIKELY(size - (plen + IPV6_HEADER_LEN) > UINT16_MAX)) {
         return false;
     }
 
diff --git a/tests/classifier.at b/tests/classifier.at
index 88818618b..cdcd72c15 100644
--- a/tests/classifier.at
+++ b/tests/classifier.at
@@ -304,3 +304,39 @@ ovs-ofctl: "conjunction" actions may be used along with "note" but not any other
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+# Flow classifier a packet with excess of padding.
+AT_SETUP([flow classifier - packet with extra padding])
+OVS_VSWITCHD_START
+add_of_ports br0 1 2
+AT_DATA([flows.txt], [dnl
+priority=5,ip,ip_dst=1.1.1.1,actions=1
+priority=5,ip,ip_dst=1.1.1.2,actions=2
+priority=0,actions=drop
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+packet=00020202020000010101010008004500001c00010000401176cc01010101010101020d6a00350008ee3a
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 $packet] , [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+  [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
+Datapath actions: 2
+])
+# normal packet plus 255 bytes of padding (8bit padding).
+# 255 * 2 = 510
+padding=$(printf '%*s' 510 | tr ' ' '0')
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 ${packet}${padding}] , [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+  [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
+Datapath actions: 2
+])
+# normal packet plus padding up to 65535 bytes of length (16bit limit).
+# 65535 - 43 = 65492
+# 65492 * 2 = 130984
+padding=$(printf '%*s' 130984 | tr ' ' '0')
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 ${packet}${padding}], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+  [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
+Datapath actions: 2
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
-- 
2.25.1