diff mbox series

[ovs-dev,branch-2.7] flow: Support extra padding length.

Message ID 20210210143950.2950378-11-i.maximets@ovn.org
State Accepted
Headers show
Series [ovs-dev,branch-2.7] flow: Support extra padding length. | expand

Commit Message

Ilya Maximets Feb. 10, 2021, 2:39 p.m. UTC
From: Flavio Leitner <fbl@sysclose.org>

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>
---
 lib/dp-packet.h     | 10 +++++-----
 lib/flow.c          |  5 ++---
 tests/classifier.at | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 8 deletions(-)

Comments

0-day Robot Feb. 10, 2021, 7:03 p.m. UTC | #1
Bleep bloop.  Greetings Ilya Maximets, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


build:
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.    -I ./include -I ./include -I ./lib -I ./lib    -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wno-null-pointer-arithmetic -Werror   -g -O2 -MT lib/odp-execute.lo -MD -MP -MF $depbase.Tpo -c -o lib/odp-execute.lo lib/odp-execute.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wno-null-pointer-arithmetic -Werror -g -O2 -MT lib/odp-execute.lo -MD -MP -MF lib/.deps/odp-execute.Tpo -c lib/odp-execute.c -o lib/odp-execute.o
depbase=`echo lib/odp-util.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.    -I ./include -I ./include -I ./lib -I ./lib    -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wno-null-pointer-arithmetic -Werror   -g -O2 -MT lib/odp-util.lo -MD -MP -MF $depbase.Tpo -c -o lib/odp-util.lo lib/odp-util.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wno-null-pointer-arithmetic -Werror -g -O2 -MT lib/odp-util.lo -MD -MP -MF lib/.deps/odp-util.Tpo -c lib/odp-util.c -o lib/odp-util.o
lib/odp-util.c: In function 'parse_odp_key_mask_attr':
lib/odp-util.c:3938:30: error: 'mask_offset' may be used uninitialized in this function [-Werror=maybe-uninitialized]
             nl_msg_end_nested(mask, mask_offset);                             \
                              ^
lib/odp-util.c:3923:28: note: 'mask_offset' was declared here
         size_t key_offset, mask_offset;                    \
                            ^
lib/odp-util.c:4066:5: note: in expansion of macro 'SCAN_BEGIN_NESTED'
     SCAN_BEGIN_NESTED("tunnel(", OVS_KEY_ATTR_TUNNEL) {
     ^
lib/odp-util.c: At top level:
cc1: error: unrecognized command line option "-Wno-null-pointer-arithmetic" [-Werror]
cc1: all warnings being treated as errors
make[2]: *** [lib/odp-util.lo] Error 1
make[2]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_from_pw/workspace'
make: *** [all] Error 2


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
diff mbox series

Patch

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index b993d7e3f..e45bc455b 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -59,7 +59,7 @@  struct dp_packet {
     bool rss_hash_valid;        /* Is the 'rss_hash' valid? */
 #endif
     enum dp_packet_source source;  /* Source of memory allocated as 'base'. */
-    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,
@@ -88,8 +88,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_l2(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 *);
@@ -281,14 +281,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 37fec991a..ccedf29cf 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -661,7 +661,7 @@  miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
         if (OVS_UNLIKELY(tot_len > size || ip_len > tot_len)) {
             goto out;
         }
-        if (OVS_UNLIKELY(size - tot_len > UINT8_MAX)) {
+        if (OVS_UNLIKELY(size - tot_len > UINT16_MAX)) {
             goto out;
         }
         dp_packet_set_l2_pad_size(packet, size - tot_len);
@@ -696,8 +696,7 @@  miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
         if (OVS_UNLIKELY(plen > size)) {
             goto out;
         }
-        /* Jumbo Payload option not supported yet. */
-        if (OVS_UNLIKELY(size - plen > UINT8_MAX)) {
+        if (OVS_UNLIKELY(size - plen > UINT16_MAX)) {
             goto out;
         }
         dp_packet_set_l2_pad_size(packet, size - plen);
diff --git a/tests/classifier.at b/tests/classifier.at
index e56ba3a75..4d003bc96 100644
--- a/tests/classifier.at
+++ b/tests/classifier.at
@@ -306,3 +306,39 @@  ovs-ofctl: Incorrect instruction ordering
 ])
 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,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,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,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
+Datapath actions: 2
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP