summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-04-18 22:01:25 +0000
committerVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-04-18 22:01:25 +0000
commit2a0885608f7f356466c08865d6a8f19736dd893a (patch)
tree2c759113291768b831b9201b462b14b995e25743 /sys/net/rtsock.c
parent9275ff7135dd9e0e3fd3b3eb510bed34dda0453e (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.c19
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);
}
/*