Date: Thu, 12 Apr 2012 01:07:17 +0000 (UTC) From: Andrew Thompson <thompsa@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r234163 - head/sys/net Message-ID: <201204120107.q3C17H42003743@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: thompsa Date: Thu Apr 12 01:07:17 2012 New Revision: 234163 URL: http://svn.freebsd.org/changeset/base/234163 Log: Set the proto to LAGG_PROTO_NONE before calling the detach routine so packets are discarded, this is an issue because lacp drops the lock which may allow network threads to access freed memory. Expand the lock coverage so the detach/attach happen atomically. Submitted by: Andrew Boyer (earlier version) Modified: head/sys/net/if_lagg.c Modified: head/sys/net/if_lagg.c ============================================================================== --- head/sys/net/if_lagg.c Thu Apr 12 00:59:30 2012 (r234162) +++ head/sys/net/if_lagg.c Thu Apr 12 01:07:17 2012 (r234163) @@ -950,11 +950,11 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd error = EPROTONOSUPPORT; break; } + LAGG_WLOCK(sc); if (sc->sc_proto != LAGG_PROTO_NONE) { - LAGG_WLOCK(sc); - error = sc->sc_detach(sc); - /* Reset protocol and pointers */ + /* Reset protocol first in case detach unlocks */ sc->sc_proto = LAGG_PROTO_NONE; + error = sc->sc_detach(sc); sc->sc_detach = NULL; sc->sc_start = NULL; sc->sc_input = NULL; @@ -966,10 +966,14 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd sc->sc_lladdr = NULL; sc->sc_req = NULL; sc->sc_portreq = NULL; - LAGG_WUNLOCK(sc); + } else if (sc->sc_input != NULL) { + /* Still detaching */ + error = EBUSY; } - if (error != 0) + if (error != 0) { + LAGG_WUNLOCK(sc); break; + } for (int i = 0; i < (sizeof(lagg_protos) / sizeof(lagg_protos[0])); i++) { if (lagg_protos[i].ti_proto == ra->ra_proto) { @@ -977,7 +981,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd printf("%s: using proto %u\n", sc->sc_ifname, lagg_protos[i].ti_proto); - LAGG_WLOCK(sc); sc->sc_proto = lagg_protos[i].ti_proto; if (sc->sc_proto != LAGG_PROTO_NONE) error = lagg_protos[i].ti_attach(sc); @@ -985,6 +988,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd return (error); } } + LAGG_WUNLOCK(sc); error = EPROTONOSUPPORT; break; case SIOCGLAGGFLAGS:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204120107.q3C17H42003743>