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:
Gleb Smirnoff 2019-10-08 17:55:45 +00:00
parent e4c40a8a71
commit 1e80e4f26c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=353314

View File

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