Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Feb 2019 17:59:50 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r343787 - in releng/12.0/sys: netinet netinet6
Message-ID:  <201902051759.x15HxoUF041367@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Tue Feb  5 17:59:50 2019
New Revision: 343787
URL: https://svnweb.freebsd.org/changeset/base/343787

Log:
  MFS12 r343454: Fix an LLE lookup race
  
  PR:		234296
  Submitted by:	markj
  Approved by:	so

Modified:
  releng/12.0/sys/netinet/in.c
  releng/12.0/sys/netinet6/in6.c
Directory Properties:
  releng/12.0/   (props changed)

Modified: releng/12.0/sys/netinet/in.c
==============================================================================
--- releng/12.0/sys/netinet/in.c	Tue Feb  5 17:57:30 2019	(r343786)
+++ releng/12.0/sys/netinet/in.c	Tue Feb  5 17:59:50 2019	(r343787)
@@ -1372,15 +1372,13 @@ in_lltable_lookup(struct lltable *llt, u_int flags, co
 	IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
 	KASSERT(l3addr->sa_family == AF_INET,
 	    ("sin_family %d", l3addr->sa_family));
-	lle = in_lltable_find_dst(llt, sin->sin_addr);
+	KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
+	    (LLE_UNLOCKED | LLE_EXCLUSIVE),
+	    ("wrong lle request flags: %#x", flags));
 
+	lle = in_lltable_find_dst(llt, sin->sin_addr);
 	if (lle == NULL)
 		return (NULL);
-
-	KASSERT((flags & (LLE_UNLOCKED|LLE_EXCLUSIVE)) !=
-	    (LLE_UNLOCKED|LLE_EXCLUSIVE),("wrong lle request flags: 0x%X",
-	    flags));
-
 	if (flags & LLE_UNLOCKED)
 		return (lle);
 
@@ -1389,6 +1387,17 @@ in_lltable_lookup(struct lltable *llt, u_int flags, co
 	else
 		LLE_RLOCK(lle);
 
+	/*
+	 * If the afdata lock is not held, the LLE may have been unlinked while
+	 * we were blocked on the LLE lock.  Check for this case.
+	 */
+	if (__predict_false((lle->la_flags & LLE_LINKED) == 0)) {
+		if (flags & LLE_EXCLUSIVE)
+			LLE_WUNLOCK(lle);
+		else
+			LLE_RUNLOCK(lle);
+		return (NULL);
+	}
 	return (lle);
 }
 

Modified: releng/12.0/sys/netinet6/in6.c
==============================================================================
--- releng/12.0/sys/netinet6/in6.c	Tue Feb  5 17:57:30 2019	(r343786)
+++ releng/12.0/sys/netinet6/in6.c	Tue Feb  5 17:59:50 2019	(r343787)
@@ -2311,16 +2311,13 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
 	IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
 	KASSERT(l3addr->sa_family == AF_INET6,
 	    ("sin_family %d", l3addr->sa_family));
+	KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
+	    (LLE_UNLOCKED | LLE_EXCLUSIVE),
+	    ("wrong lle request flags: %#x", flags));
 
 	lle = in6_lltable_find_dst(llt, &sin6->sin6_addr);
-
 	if (lle == NULL)
 		return (NULL);
-
-	KASSERT((flags & (LLE_UNLOCKED|LLE_EXCLUSIVE)) !=
-	    (LLE_UNLOCKED|LLE_EXCLUSIVE),("wrong lle request flags: 0x%X",
-	    flags));
-
 	if (flags & LLE_UNLOCKED)
 		return (lle);
 
@@ -2328,6 +2325,18 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
 		LLE_WLOCK(lle);
 	else
 		LLE_RLOCK(lle);
+
+	/*
+	 * If the afdata lock is not held, the LLE may have been unlinked while
+	 * we were blocked on the LLE lock.  Check for this case.
+	 */
+	if (__predict_false((lle->la_flags & LLE_LINKED) == 0)) {
+		if (flags & LLE_EXCLUSIVE)
+			LLE_WUNLOCK(lle);
+		else
+			LLE_RUNLOCK(lle);
+		return (NULL);
+	}
 	return (lle);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902051759.x15HxoUF041367>