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