If an MLD packet is not large enough to contain the
message-specific data, it may lead to a NULL pointer access.
This patch fixes the issue by adding appropriate length checks.

Fixes: 06994f879c9d ("mcast-snooping: Add Multicast Listener Discovery support")
Signed-off-by: Eelco Chaudron <echau...@redhat.com>
---
V2:
  - Based on review feedback removed the BUILD_ASSERT.
  - Added BUILD_ASSERT_DEV() for the OVS specific
    ovs_16aligned_in6_addr union.
  - Updated comment to be more clear.
---
 lib/mcast-snooping.c | 8 ++++++++
 lib/packets.h        | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index b279c1229..7e1a55120 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -543,6 +543,14 @@ mcast_snooping_add_mld(struct mcast_snooping *ms,
     offset += MLD_HEADER_LEN;
     addr = dp_packet_at(p, offset, sizeof(struct in6_addr));
 
+    if (!addr) {
+        /* We error out if the provided packet is not large enough to handle
+         * the mld->type values below.  Note that whenever a new type gets
+         * added, its data should be equal to or larger than the size of
+         * struct in6_addr. */
+        return 0;
+    }
+
     switch (mld->type) {
     case MLD_REPORT:
         ret = mcast_snooping_add_group(ms, addr, vlan, port,
diff --git a/lib/packets.h b/lib/packets.h
index d687fa999..6eba07700 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -979,6 +979,8 @@ union ovs_16aligned_in6_addr {
     ovs_be16 be16[8];
     ovs_16aligned_be32 be32[4];
 };
+BUILD_ASSERT_DECL(sizeof(union ovs_16aligned_in6_addr)
+                  == sizeof(struct in6_addr));
 
 /* Like struct ip6_hdr, but whereas that struct requires 32-bit alignment, this
  * one only requires 16-bit alignment. */
-- 
2.50.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to