Blame SOURCES/0004-8021Qaz-check-for-rx-block-validity.patch

dc4502
From bcb3ef5ab848eb648f05a840030df1f230976a70 Mon Sep 17 00:00:00 2001
dc4502
From: Aaron Conole <aconole@redhat.com>
dc4502
Date: Wed, 25 Aug 2021 10:37:22 -0400
dc4502
Subject: [PATCH 4/8] 8021Qaz: check for rx block validity
dc4502
dc4502
There is a slim but possible race in the 8021Qaz processing when handling
dc4502
TLVs during ifdown windows.  To address this, check for the rx block
dc4502
before dereferencing it.
dc4502
dc4502
closes https://github.com/intel/openlldp/issues/78
dc4502
Signed-off-by: Aaron Conole <aconole@redhat.com>
dc4502
---
dc4502
 lldp_8021qaz.c | 41 ++++++++++++++++++++++++++++-------------
dc4502
 1 file changed, 28 insertions(+), 13 deletions(-)
dc4502
dc4502
diff --git a/lldp_8021qaz.c b/lldp_8021qaz.c
dc4502
index 045bd45..8bb2bc9 100644
dc4502
--- a/lldp_8021qaz.c
dc4502
+++ b/lldp_8021qaz.c
dc4502
@@ -1563,48 +1563,63 @@ static bool unpack_ieee8021qaz_tlvs(struct port *port,
dc4502
 	/* Process */
dc4502
 	switch (tlv->info[OUI_SIZE]) {
dc4502
 	case IEEE8021QAZ_ETSCFG_TLV:
dc4502
-		if (tlvs->rx->etscfg == NULL) {
dc4502
+		if (tlvs->rx && tlvs->rx->etscfg == NULL) {
dc4502
 			tlvs->ieee8021qazdu |= RCVD_IEEE8021QAZ_TLV_ETSCFG;
dc4502
 			tlvs->rx->etscfg = tlv;
dc4502
-		} else {
dc4502
+		} else if (tlvs->rx) {
dc4502
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate ETSCFG TLV\n",
dc4502
 				__func__, port->ifname);
dc4502
 			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSCFG;
dc4502
 			return false;
dc4502
+		} else {
dc4502
+			LLDPAD_INFO("%s: %s: 802.1Qaz port IFDOWN\n",
dc4502
+				__func__, port->ifname);
dc4502
+			return false;
dc4502
 		}
dc4502
 		break;
dc4502
 	case IEEE8021QAZ_ETSREC_TLV:
dc4502
-		if (tlvs->rx->etsrec == NULL) {
dc4502
+		if (tlvs->rx && tlvs->rx->etsrec == NULL) {
dc4502
 			tlvs->ieee8021qazdu |= RCVD_IEEE8021QAZ_TLV_ETSREC;
dc4502
 			tlvs->rx->etsrec = tlv;
dc4502
-		} else {
dc4502
+		} else if (tlvs->rx) {
dc4502
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate ETSREC TLV\n",
dc4502
 				__func__, port->ifname);
dc4502
 			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSREC;
dc4502
 			return false;
dc4502
+		} else {
dc4502
+			LLDPAD_INFO("%s: %s: 802.1Qaz port IFDOWN\n",
dc4502
+				__func__, port->ifname);
dc4502
+			return false;
dc4502
 		}
dc4502
 		break;
dc4502
-
dc4502
 	case IEEE8021QAZ_PFC_TLV:
dc4502
-		if (tlvs->rx->pfc == NULL) {
dc4502
+		if (tlvs->rx && tlvs->rx->pfc == NULL) {
dc4502
 			tlvs->ieee8021qazdu |= RCVD_IEEE8021QAZ_TLV_PFC;
dc4502
 			tlvs->rx->pfc = tlv;
dc4502
-		} else {
dc4502
+		} else if (tlvs->rx) {
dc4502
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate PFC TLV\n",
dc4502
 				__func__, port->ifname);
dc4502
 			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_PFC;
dc4502
 			return false;
dc4502
+		} else {
dc4502
+			LLDPAD_INFO("%s: %s: 802.1Qaz port IFDOWN\n",
dc4502
+				__func__, port->ifname);
dc4502
+			return false;
dc4502
 		}
dc4502
 		break;
dc4502
 	case IEEE8021QAZ_APP_TLV:
dc4502
-		if (tlvs->rx->app == NULL) {
dc4502
+		if (tlvs->rx && tlvs->rx->app == NULL) {
dc4502
 			tlvs->ieee8021qazdu |= RCVD_IEEE8021QAZ_TLV_APP;
dc4502
 			tlvs->rx->app = tlv;
dc4502
-		} else {
dc4502
+		} else if (tlvs->rx) {
dc4502
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate APP TLV\n",
dc4502
 				    __func__, port->ifname);
dc4502
 			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_APP;
dc4502
 			return false;
dc4502
+		} else {
dc4502
+			LLDPAD_INFO("%s: %s: 802.1Qaz port IFDOWN\n",
dc4502
+				__func__, port->ifname);
dc4502
+			return false;
dc4502
 		}
dc4502
 		break;
dc4502
 	default:
dc4502
@@ -1891,26 +1906,26 @@ static void ieee8021qaz_mibUpdateObjects(struct port *port)
dc4502
 
dc4502
 	tlvs = ieee8021qaz_data(port->ifname);
dc4502
 
dc4502
-	if (tlvs->rx->etscfg) {
dc4502
+	if (tlvs->rx && tlvs->rx->etscfg) {
dc4502
 		process_ieee8021qaz_etscfg_tlv(port);
dc4502
 	} else if (tlvs->ets->cfgr) {
dc4502
 		free(tlvs->ets->cfgr);
dc4502
 		tlvs->ets->cfgr = NULL;
dc4502
 	}
dc4502
 
dc4502
-	if (tlvs->rx->etsrec) {
dc4502
+	if (tlvs->rx && tlvs->rx->etsrec) {
dc4502
 		process_ieee8021qaz_etsrec_tlv(port);
dc4502
 	} else if (tlvs->ets->recr) {
dc4502
 		free(tlvs->ets->recr);
dc4502
 		tlvs->ets->recr = NULL;
dc4502
 	}
dc4502
 
dc4502
-	if (tlvs->rx->pfc)
dc4502
+	if (tlvs->rx && tlvs->rx->pfc)
dc4502
 		process_ieee8021qaz_pfc_tlv(port);
dc4502
 	else if (tlvs->pfc)
dc4502
 		tlvs->pfc->remote_param = false;
dc4502
 
dc4502
-	if (tlvs->rx->app)
dc4502
+	if (tlvs->rx && tlvs->rx->app)
dc4502
 		process_ieee8021qaz_app_tlv(port);
dc4502
 	else
dc4502
 		ieee8021qaz_app_reset(&tlvs->app_head);
dc4502
-- 
dc4502
2.31.1
dc4502