Remove epoch assertion from if_setlladdr(). Originally this function was
protected by IF_ADDR_LOCK(), which was a mutex, so that two simultaneous if_setlladdr() can't execute. Later it was switched to IF_ADDR_RLOCK(), likely by a mistake. Later it was switched to NET_EPOCH_ENTER(). Then I incorrectly added NET_EPOCH_ASSERT() here. In reality ifp->if_addr never goes away and never changes its length. So, doing bcopy() in it is always "safe", meaning it won't dereference a wrong pointer or write into someone's else memory. Of course doing two bcopy() in parallel would result in a mess of two addresses, but net epoch doesn't protect against that, neither IF_ADDR_RLOCK() did. So for now, just remove the assertion and leave for later a proper fix. Reported by: markj
This commit is contained in:
parent
1c64917ffa
commit
be8284f983
30
sys/net/if.c
30
sys/net/if.c
@ -3822,26 +3822,18 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||
struct sockaddr_dl *sdl;
|
||||
struct ifaddr *ifa;
|
||||
struct ifreq ifr;
|
||||
int rc;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
|
||||
rc = 0;
|
||||
ifa = ifp->if_addr;
|
||||
if (ifa == NULL) {
|
||||
rc = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (ifa == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||
if (sdl == NULL) {
|
||||
rc = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (len != sdl->sdl_alen) { /* don't allow length to change */
|
||||
rc = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (sdl == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
if (len != sdl->sdl_alen) /* don't allow length to change */
|
||||
return (EINVAL);
|
||||
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_XETHER:
|
||||
@ -3851,8 +3843,7 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||
bcopy(lladdr, LLADDR(sdl), len);
|
||||
break;
|
||||
default:
|
||||
rc = ENODEV;
|
||||
goto out;
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3873,9 +3864,8 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||
}
|
||||
}
|
||||
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
|
||||
|
||||
return (0);
|
||||
out:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user