Fix ifa refcount leak in ifa_ifwithnet()
In 4f6c66cc9c75c8, ifa_ifwithnet() was changed to no longer ifa_ref() the returned ifaddr, and instead the caller was required to stay in the net_epoch for as long as they wanted the ifaddr to remain valid. However, this missed the case where an AF_LINK lookup would call ifaddr_byindex(), which still does ifa_ref() the ifaddr. This would cause a refcount leak. Fix this by inlining the relevant parts of ifaddr_byindex() here, with the ifa_ref() call removed. This also avoids an unnecessary entry and exit from the net_epoch for this case. I've audited all in-tree consumers of ifa_ifwithnet() that could possibly perform an AF_LINK lookup and confirmed that none of them will expect the ifaddr to have a reference that they need to release. MFC after: 2 months Sponsored by: Dell Inc Differential Revision: https://reviews.freebsd.org/D28705 Reviewed by: melifaro
This commit is contained in:
parent
32a95656b5
commit
5adea417d4
12
sys/net/if.c
12
sys/net/if.c
@ -1953,6 +1953,7 @@ ifa_ifwithnet(const struct sockaddr *addr, int ignore_ptp, int fibnum)
|
||||
struct ifaddr *ifa_maybe = NULL;
|
||||
u_int af = addr->sa_family;
|
||||
const char *addr_data = addr->sa_data, *cplim;
|
||||
const struct sockaddr_dl *sdl;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
/*
|
||||
@ -1960,9 +1961,14 @@ ifa_ifwithnet(const struct sockaddr *addr, int ignore_ptp, int fibnum)
|
||||
* so do that if we can.
|
||||
*/
|
||||
if (af == AF_LINK) {
|
||||
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= V_if_index)
|
||||
return (ifaddr_byindex(sdl->sdl_index));
|
||||
sdl = (const struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= V_if_index) {
|
||||
ifp = ifnet_byindex(sdl->sdl_index);
|
||||
if (ifp == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (ifp->if_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user