In if_setlladdr(), use IF_ADDR_LOCK() and ifaddr references to improve

the safety of link layer address manipulation.

MFC after:	6 weeks
This commit is contained in:
Robert Watson 2009-06-24 10:36:48 +00:00
parent 09d547787f
commit 3baaf2974d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194821

View File

@ -3145,14 +3145,23 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
struct ifaddr *ifa;
struct ifreq ifr;
IF_ADDR_LOCK(ifp);
ifa = ifp->if_addr;
if (ifa == NULL)
if (ifa == NULL) {
IF_ADDR_UNLOCK(ifp);
return (EINVAL);
}
ifa_ref(ifa);
IF_ADDR_UNLOCK(ifp);
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
if (sdl == NULL)
if (sdl == NULL) {
ifa_free(ifa);
return (EINVAL);
if (len != sdl->sdl_alen) /* don't allow length to change */
}
if (len != sdl->sdl_alen) { /* don't allow length to change */
ifa_free(ifa);
return (EINVAL);
}
switch (ifp->if_type) {
case IFT_ETHER:
case IFT_FDDI:
@ -3164,10 +3173,13 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
case IFT_IEEE8023ADLAG:
case IFT_IEEE80211:
bcopy(lladdr, LLADDR(sdl), len);
ifa_free(ifa);
break;
default:
ifa_free(ifa);
return (ENODEV);
}
/*
* If the interface is already up, we need
* to re-init it in order to reprogram its