Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 May 2012 08:00:34 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r236058 - stable/8/sys/net
Message-ID:  <201205260800.q4Q80YNO061052@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Sat May 26 08:00:34 2012
New Revision: 236058
URL: http://svn.freebsd.org/changeset/base/236058

Log:
  MFC r234163
  
   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:
  stable/8/sys/net/if_lagg.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/net/if_lagg.c
==============================================================================
--- stable/8/sys/net/if_lagg.c	Sat May 26 07:59:56 2012	(r236057)
+++ stable/8/sys/net/if_lagg.c	Sat May 26 08:00:34 2012	(r236058)
@@ -942,11 +942,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;
@@ -958,10 +958,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) {
@@ -969,7 +973,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);
@@ -977,6 +980,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?201205260800.q4Q80YNO061052>