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
This commit is contained in:
Ryan Stone 2016-08-18 22:59:10 +00:00
parent 41029db13f
commit 11f2a7cd67
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304437

View File

@ -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);
}
/*