CVE-2015-8012 (published 2020-01-28T19:15Z)

lldpd before 0.8.0 allows remote attackers to cause a denial of service (assertion failure and daemon crash) via a malformed packet.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-617
cwe_name: Reachable Assertion
description: The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.
extended_description: 
            While assertion is good for catching logic errors and reducing the chances of reaching more serious vulnerability conditions, it can still lead to a denial of service.
            For example, if a server handles multiple simultaneous connections, and an assert() occurs in one single connection that causes all other connections to be dropped, this is a reachable assertion that leads to a denial of service.
         
         

Fix information:
repo_url: https://github.com/vincentbernat/lldpd
commit_details: repo_url: https://github.com/vincentbernat/lldpd
author: Vincent Bernat
author_date: 2015-10-04 02:24:29+02:00
msg: protocols: don't use assert on paths that can be reached

Malformed packets should not make lldpd crash. Ensure we can handle them
by not using assert() in this part.
repository: repo_url: https://github.com/vincentbernat/lldpd
repo_name: lldpd/lldpd
description: implementation of IEEE 802.1ab (LLDP)
repo_language: C
owner: vincentbernat
file_changes: filename: lldpd.c
change_type: ModificationType.MODIFY
diff: @@ -252,7 +252,6 @@ lldpd_alloc_mgmt(int family, void *addrptr, size_t addrsize, u_int32_t iface)
 		return NULL;
 	}
 	mgmt->m_family = family;
-	assert(addrsize <= LLDPD_MGMT_MAXADDRSIZE);
 	memcpy(&mgmt->m_addr, addrptr, addrsize);
 	mgmt->m_addrsize = addrsize;
 	mgmt->m_iface = iface;

programming_language: C
filename: cdp.c
change_type: ModificationType.MODIFY
diff: @@ -25,7 +25,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <arpa/inet.h>
-#include <assert.h>
 
 static int
 cdp_send(struct lldpd *global,
@@ -438,8 +437,13 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
 						mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr, 
 									sizeof(struct in_addr), 0);
 						if (mgmt == NULL) {
-							assert(errno == ENOMEM);
-							log_warn("cdp", "unable to allocate memory for management address");
+							if (errno == ENOMEM)
+								log_warn("cdp",
+								    "unable to allocate memory for management address");
+							else
+								log_warn("cdp",
+								    "too large management address received on %s",
+								    hardware->h_ifname);
 							goto malformed;
 						}
 						TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);

programming_language: C
filename: edp.c
change_type: ModificationType.MODIFY
diff: @@ -25,7 +25,6 @@
 #include <errno.h>
 #include <arpa/inet.h>
 #include <fnmatch.h>
-#include <assert.h>
 
 static int seq = 0;
 

programming_language: C
filename: lldp.c
change_type: ModificationType.MODIFY
diff: @@ -20,7 +20,6 @@
 
 #include <unistd.h>
 #include <errno.h>
-#include <assert.h>
 #include <time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -161,7 +160,7 @@ static int _lldp_send(struct lldpd *global,
 	/* Management addresses */
 	TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) {
 		proto = lldpd_af_to_lldp_proto(mgmt->m_family);
-		assert(proto != LLDP_MGMT_ADDR_NONE);
+		if (proto == LLDP_MGMT_ADDR_NONE) continue;
 		if (!(
 			  POKE_START_LLDP_TLV(LLDP_TLV_MGMT_ADDR) &&
 			  /* Size of the address, including its type */
@@ -749,9 +748,12 @@ lldp_decode(struct lldpd *cfg, char *frame, int s,
 				iface = 0;
 			mgmt = lldpd_alloc_mgmt(af, addr_ptr, addr_length, iface);
 			if (mgmt == NULL) {
-				assert(errno == ENOMEM);
-				log_warn("lldp", "unable to allocate memory "
-				    "for management address");
+				if (errno == ENOMEM)
+					log_warn("lldp", "unable to allocate memory "
+					    "for management address");
+				else
+					log_warn("lldp", "too large management address "
+					    "received on %s", hardware->h_ifname);
 				goto malformed;
 			}
 			TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);

programming_language: C
filename: sonmp.c
change_type: ModificationType.MODIFY
diff: @@ -24,7 +24,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <arpa/inet.h>
-#include <assert.h>
 
 static struct sonmp_chassis sonmp_chassis_types[] = {
 	{1, "unknown (via SONMP)"},
@@ -358,8 +357,11 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
 	}
 	mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &address, sizeof(struct in_addr), 0);
 	if (mgmt == NULL) {
-		assert(errno == ENOMEM);
-		log_warn("sonmp", "unable to allocate memory for management address");
+		if (errno == ENOMEM)
+			log_warn("sonmp", "unable to allocate memory for management address");
+		else
+			log_warn("sonmp", "too large management address received on %s",
+			    hardware->h_ifname);
 		goto malformed;
 	}
 	TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);

programming_language: C