diff options
author | Vitaliy Makkoveev <mvs@cvs.openbsd.org> | 2023-04-18 22:01:25 +0000 |
---|---|---|
committer | Vitaliy Makkoveev <mvs@cvs.openbsd.org> | 2023-04-18 22:01:25 +0000 |
commit | 2a0885608f7f356466c08865d6a8f19736dd893a (patch) | |
tree | 2c759113291768b831b9201b462b14b995e25743 /sys/net/rtsock.c | |
parent | 9275ff7135dd9e0e3fd3b3eb510bed34dda0453e (diff) |
Remove kernel lock from ifa_ifwithaddr() and ifa_ifwithdstaddr().
Netlock protects `if_list', `ifa_list' and returned `ifa' dereference,
so put netlock assertion within.
Please note, rtable_setsource() doesn't destroy data pointed by
`ar_source'. This is the `ifa_addr' data belongs to `ifa' and exclusive
netlock is required to destroy it. So the kernel lock is not required
within rt_setsource(). Take netlock by rt_setsource() caller to make
`ifa' dereference safe.
Suggestions and ok by bluhm@
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r-- | sys/net/rtsock.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index b6d3c06894e..d3cc836db49 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.362 2023/04/18 09:56:54 mvs Exp $ */ +/* $OpenBSD: rtsock.c,v 1.363 2023/04/18 22:01:24 mvs Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -853,8 +853,10 @@ route_output(struct mbuf *m, struct socket *so) error = EINVAL; goto fail; } - if ((error = - rt_setsource(tableid, info.rti_info[RTAX_IFA])) != 0) + NET_LOCK(); + error = rt_setsource(tableid, info.rti_info[RTAX_IFA]); + NET_UNLOCK(); + if (error) goto fail; } else { error = rtm_output(rtm, &rt, &info, prio, tableid); @@ -2350,7 +2352,6 @@ int rt_setsource(unsigned int rtableid, struct sockaddr *src) { struct ifaddr *ifa; - int error; /* * If source address is 0.0.0.0 or :: * use automatic source selection @@ -2374,20 +2375,14 @@ rt_setsource(unsigned int rtableid, struct sockaddr *src) return (EAFNOSUPPORT); } - KERNEL_LOCK(); /* * Check if source address is assigned to an interface in the * same rdomain */ - if ((ifa = ifa_ifwithaddr(src, rtableid)) == NULL) { - KERNEL_UNLOCK(); + if ((ifa = ifa_ifwithaddr(src, rtableid)) == NULL) return (EINVAL); - } - - error = rtable_setsource(rtableid, src->sa_family, ifa->ifa_addr); - KERNEL_UNLOCK(); - return (error); + return rtable_setsource(rtableid, src->sa_family, ifa->ifa_addr); } /* |