The OVS LLDP implementation includes support for AutoAttach standard, which
the 'upstream' lldpd project does not include.  As part of adding this
support, the message parsing for these TLVs did not include proper length
checks for the LLDP_TLV_AA_ELEMENT_SUBTYPE and the
LLDP_TLV_AA_ISID_VLAN_ASGNS_SUBTYPE elements.  The result is that a message
without a proper boundary will cause an overread of memory, and lead to
undefined results, including crashes or other unidentified behavior.

The fix is to introduce proper bounds checking for these elements.  Introduce
a unit test to ensure that we have some proper rejection in this code
base in the future.

Fixes: be53a5c447c3 ("auto-attach: Initial support for Auto-Attach standard")
Signed-off-by: Qian Chen <cq674350...@163.com>
Co-authored-by: Aaron Conole <acon...@redhat.com>
Signed-off-by: Aaron Conole <acon...@redhat.com>
---
NOTES: This bug is publicly known and disclosed at
       https://github.com/openvswitch/ovs/pull/405 which makes this mostly
       a repost.
v2:    Convert from system traffic test to a basic unit test

 lib/lldp/lldp.c       |  2 ++
 tests/ofproto-dpif.at | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/lib/lldp/lldp.c b/lib/lldp/lldp.c
index dfeb2a8002..6fdcfef569 100644
--- a/lib/lldp/lldp.c
+++ b/lib/lldp/lldp.c
@@ -583,6 +583,7 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int 
s,
 
                 switch(tlv_subtype) {
                 case LLDP_TLV_AA_ELEMENT_SUBTYPE:
+                    CHECK_TLV_SIZE(50, "ELEMENT");
                     PEEK_BYTES(&msg_auth_digest, sizeof msg_auth_digest);
 
                     aa_element_dword = PEEK_UINT32;
@@ -629,6 +630,7 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int 
s,
                     break;
 
                 case LLDP_TLV_AA_ISID_VLAN_ASGNS_SUBTYPE:
+                    CHECK_TLV_SIZE(36, "ISID_VLAN_ASGNS");
                     PEEK_BYTES(&msg_auth_digest, sizeof msg_auth_digest);
 
                     /* Subtract off tlv type and length (2Bytes) + OUI (3B) +
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index eb4cd18960..fa6111c1ed 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -62,6 +62,25 @@ AT_CHECK([ovs-appctl coverage/read-counter rev_reconfigure], 
[0], [dnl
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto-dpif - malformed lldp autoattach tlv])
+OVS_VSWITCHD_START()
+add_of_ports br0 1
+
+dnl Enable lldp
+AT_CHECK([ovs-vsctl set interface p1 lldp:enable=true])
+
+dnl Send a malformed lldp packet
+packet="0180c200000ef6b426aa5f0088cc020704f6b426aa5f000403057632060200780c"dnl
+"5044454144424545464445414442454546444541444245454644454144424545464445414"dnl
+"4424545464445414442454546444541444245454644454144424545464445414442454546"dnl
+"4445414442454546fe0500040d0c010000"
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 "$packet"], [0], [stdout])
+
+OVS_WAIT_UNTIL([grep -q "ISID_VLAN_ASGNS TLV too short" ovs-vswitchd.log])
+
+OVS_VSWITCHD_STOP(["/|WARN|ISID_VLAN_ASGNS TLV too short received on/d"])
+AT_CLEANUP
+
 AT_SETUP([ofproto-dpif - active-backup bonding (with primary)])
 
 dnl Create br0 with members p1, p2 and p7, creating bond0 with p1 and
-- 
2.38.1

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

Reply via email to