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:
parent
09d547787f
commit
3baaf2974d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194821
18
sys/net/if.c
18
sys/net/if.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user