From 73d42680fce8598324364dbb31b9bc3b8320adf7 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sun, 19 Sep 2021 21:18:47 +0200 Subject: [PATCH] sonmp: fix heap overflow when reading SONMP packets By sending short SONMP packets, an attacker can make the decoder crash by reading too much data on the heap. SONMP packets are fixed in size, just ensure we get the enough bytes to contain a SONMP packet. CVE-2021-43612 --- NEWS | 2 ++ src/daemon/protocols/sonmp.c | 2 +- src/daemon/protocols/sonmp.h | 2 +- tests/check_sonmp.c | 10 +++++----- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 68925bf7..dbb1b804 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ lldpd (1.0.13) + Add support for 2.5G, 5G, 25G and 50G based Ethernet (#475) + Fix link-down detection on OpenBSD (#476) + Fix LLDP packets encapsuled in VLAN 0 in some conditions + + Fix heap overflow when reading SONMP. CVE-2021-43612. + Thanks to Jeremy Galindo for discovering this one. lldpd (1.0.12) * Fix: diff --git a/src/daemon/protocols/sonmp.c b/src/daemon/protocols/sonmp.c index 41dcf6aa..f8f12469 100644 --- a/src/daemon/protocols/sonmp.c +++ b/src/daemon/protocols/sonmp.c @@ -311,7 +311,7 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s, length = s; pos = (u_int8_t*)frame; - if (length < SONMP_SIZE) { + if (length < SONMP_SIZE + 2*ETHER_ADDR_LEN + sizeof(u_int16_t)) { log_warnx("sonmp", "too short SONMP frame received on %s", hardware->h_ifname); goto malformed; } diff --git a/src/daemon/protocols/sonmp.h b/src/daemon/protocols/sonmp.h index 0e60106d..ff7a720f 100644 --- a/src/daemon/protocols/sonmp.h +++ b/src/daemon/protocols/sonmp.h @@ -24,7 +24,7 @@ #define LLC_ORG_NORTEL { 0x00, 0x00, 0x81 } #define LLC_PID_SONMP_HELLO 0x01a2 #define LLC_PID_SONMP_FLATNET 0x01a1 -#define SONMP_SIZE (2*ETHER_ADDR_LEN + sizeof(u_int16_t) + 8) +#define SONMP_SIZE 19 struct sonmp_chassis { int type; diff --git a/tests/check_sonmp.c b/tests/check_sonmp.c index 8c7a208f..b25f0e2f 100644 --- a/tests/check_sonmp.c +++ b/tests/check_sonmp.c @@ -33,7 +33,7 @@ START_TEST (test_send_sonmp) IEEE 802.3 Ethernet Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:00) Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) - Length: 22 + Length: 19 Logical-Link Control DSAP: SNAP (0xaa) IG Bit: Individual @@ -55,7 +55,7 @@ Nortel Networks / SynOptics Network Management Protocol IEEE 802.3 Ethernet Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:01) Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) - Length: 22 + Length: 19 Logical-Link Control DSAP: SNAP (0xaa) IG Bit: Individual @@ -76,13 +76,13 @@ Nortel Networks / SynOptics Network Management Protocol */ char pkt1[] = { 0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x5e, 0x10, - 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x16, 0xaa, 0xaa, + 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, 0xac, 0x11, 0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03, 0x01 }; char pkt2[] = { 0x01, 0x00, 0x81, 0x00, 0x01, 0x01, 0x5e, 0x10, - 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x16, 0xaa, 0xaa, + 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa1, 0xac, 0x11, 0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03, 0x01 }; @@ -99,7 +99,7 @@ Nortel Networks / SynOptics Network Management Protocol chassis.c_id_len = ETHER_ADDR_LEN; TAILQ_INIT(&chassis.c_mgmt); addr = inet_addr("172.17.142.37"); - mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, + mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr, sizeof(in_addr_t), 0); if (mgmt == NULL) ck_abort(); -- 2.39.5