svn commit: r343363 - in head/sys: netinet netinet6

Mark Johnston markj at FreeBSD.org
Wed Jan 23 22:18:24 UTC 2019


Author: markj
Date: Wed Jan 23 22:18:23 2019
New Revision: 343363
URL: https://svnweb.freebsd.org/changeset/base/343363

Log:
  Fix an LLE lookup race.
  
  After the afdata read lock was converted to epoch(9), readers could
  observe a linked LLE and block on the LLE while a thread was
  unlinking the LLE.  The writer would then release the lock and schedule
  the LLE for deferred free, allowing readers to continue and potentially
  schedule the LLE timer.  By the point the timer fires, the structure is
  freed, typically resulting in a crash in the callout subsystem.
  
  Fix the problem by modifying the lookup path to check for the LLE_LINKED
  flag upon acquiring the LLE lock.  If it's not set, the lookup fails.
  
  PR:		234296
  Reviewed by:	bz
  Tested by:	sbruno, Victor <chernov_victor at list.ru>,
  		Mike Andrews <mandrews at bit0.com>
  MFC after:	3 days
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D18906

Modified:
  head/sys/netinet/in.c
  head/sys/netinet6/in6.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Wed Jan 23 22:00:17 2019	(r343362)
+++ head/sys/netinet/in.c	Wed Jan 23 22:18:23 2019	(r343363)
@@ -1399,6 +1399,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: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Wed Jan 23 22:00:17 2019	(r343362)
+++ head/sys/netinet6/in6.c	Wed Jan 23 22:18:23 2019	(r343363)
@@ -2342,6 +2342,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);
 }
 


More information about the svn-src-all mailing list