diff options
author | asomers <asomers@FreeBSD.org> | 2014-10-06 23:17:01 +0000 |
---|---|---|
committer | asomers <asomers@FreeBSD.org> | 2014-10-06 23:17:01 +0000 |
commit | f906790c8793e71f5e1868214912b1a0035a5185 (patch) | |
tree | 03c8242a52da86375890f1a0238ec11607760c91 | |
parent | b754ead53081cb8550dd5712305e0d9c54b773cb (diff) | |
download | FreeBSD-src-f906790c8793e71f5e1868214912b1a0035a5185.zip FreeBSD-src-f906790c8793e71f5e1868214912b1a0035a5185.tar.gz |
MFC r265232
Fix a panic caused by doing "ifconfig -am" while a lagg is being destroyed.
The thread that is destroying the lagg has already set sc->sc_psc=NULL when
the "ifconfig -am" thread gets to lacp_req(). It tries to dereference
sc->sc_psc and panics. The solution is for lacp_req() to check the value of
sc->sc_psc. If NULL, harmlessly return an lacp_opreq structure full of
zeros. Full details in GNATS.
PR: 189003
-rw-r--r-- | sys/net/ieee8023ad_lacp.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index aef3740..bf231dc 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -591,10 +591,20 @@ lacp_req(struct lagg_softc *sc, caddr_t data) { struct lacp_opreq *req = (struct lacp_opreq *)data; struct lacp_softc *lsc = LACP_SOFTC(sc); - struct lacp_aggregator *la = lsc->lsc_active_aggregator; + struct lacp_aggregator *la; - LACP_LOCK(lsc); bzero(req, sizeof(struct lacp_opreq)); + + /* + * If the LACP softc is NULL, return with the opreq structure full of + * zeros. It is normal for the softc to be NULL while the lagg is + * being destroyed. + */ + if (NULL == lsc) + return; + + la = lsc->lsc_active_aggregator; + LACP_LOCK(lsc); if (la != NULL) { req->actor_prio = ntohs(la->la_actor.lip_systemid.lsi_prio); memcpy(&req->actor_mac, &la->la_actor.lip_systemid.lsi_mac, |