svn commit: r304437 - head/sys/netinet

Ryan Stone rstone at FreeBSD.org
Thu Aug 18 22:59:12 UTC 2016


Author: rstone
Date: Thu Aug 18 22:59:10 2016
New Revision: 304437
URL: https://svnweb.freebsd.org/changeset/base/304437

Log:
  Fix unlocked access to ifnet address list
  
  in_broadcast() was iterating over the ifnet address list without
  first taking an IF_ADDR_RLOCK.  This could cause a panic if a
  concurrent operation modified the list.
  
  Reviewed by: bz
  MFC after: 2 months
  Sponsored by: EMC / Isilon Storage Division
  Differential Revision: https://reviews.freebsd.org/D7227

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Thu Aug 18 22:59:05 2016	(r304436)
+++ head/sys/netinet/in.c	Thu Aug 18 22:59:10 2016	(r304437)
@@ -954,21 +954,27 @@ int
 in_broadcast(struct in_addr in, struct ifnet *ifp)
 {
 	register struct ifaddr *ifa;
+	int found;
 
 	if (in.s_addr == INADDR_BROADCAST ||
 	    in.s_addr == INADDR_ANY)
 		return (1);
 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
 		return (0);
+	found = 0;
 	/*
 	 * Look through the list of addresses for a match
 	 * with a broadcast address.
 	 */
+	IF_ADDR_RLOCK(ifp);
 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
 		if (ifa->ifa_addr->sa_family == AF_INET &&
-		    in_ifaddr_broadcast(in, (struct in_ifaddr *)ifa))
-			    return (1);
-	return (0);
+		    in_ifaddr_broadcast(in, (struct in_ifaddr *)ifa)) {
+			found = 1;
+			break;
+		}
+	IF_ADDR_RUNLOCK(ifp);
+	return (found);
 }
 
 /*


More information about the svn-src-head mailing list