diff options
author | 2017-10-09 08:35:38 +0000 | |
---|---|---|
committer | 2017-10-09 08:35:38 +0000 | |
commit | df4a15bc1fe47e27f4c1e62e865ee303c6e12c79 (patch) | |
tree | a59104b5975da8c5e1e2cfb35e2bffb33fc729ab /sys | |
parent | Correct logic check preventing the device to attach. (diff) | |
download | wireguard-openbsd-df4a15bc1fe47e27f4c1e62e865ee303c6e12c79.tar.xz wireguard-openbsd-df4a15bc1fe47e27f4c1e62e865ee303c6e12c79.zip |
Reduces the scope of the NET_LOCK() in sysctl(2) path.
Exposes per-CPU counters to real parrallelism.
ok visa@, bluhm@, jca@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_domain.c | 4 | ||||
-rw-r--r-- | sys/net/if.c | 16 | ||||
-rw-r--r-- | sys/net/if_etherip.c | 14 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 8 | ||||
-rw-r--r-- | sys/net/rtsock.c | 10 | ||||
-rw-r--r-- | sys/netinet/igmp.c | 14 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 9 | ||||
-rw-r--r-- | sys/netinet/ip_divert.c | 26 | ||||
-rw-r--r-- | sys/netinet/ip_ether.c | 18 | ||||
-rw-r--r-- | sys/netinet/ip_gre.c | 23 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 8 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 60 | ||||
-rw-r--r-- | sys/netinet/ip_ipip.c | 9 | ||||
-rw-r--r-- | sys/netinet/ipsec_input.c | 59 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 127 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 28 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 14 | ||||
-rw-r--r-- | sys/netinet6/ip6_divert.c | 26 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 33 |
19 files changed, 346 insertions, 160 deletions
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index b2a43a41cd5..4cfbe5de4ff 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_domain.c,v 1.52 2017/08/11 21:24:19 mpi Exp $ */ +/* $OpenBSD: uipc_domain.c,v 1.53 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */ /* @@ -207,10 +207,8 @@ net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, protocol = name[1]; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) if (pr->pr_protocol == protocol && pr->pr_sysctl) { - NET_LOCK(); error = (*pr->pr_sysctl)(name + 2, namelen - 2, oldp, oldlenp, newp, newlen); - NET_UNLOCK(); return (error); } return (ENOPROTOOPT); diff --git a/sys/net/if.c b/sys/net/if.c index 07eeb249264..60020606df5 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.512 2017/08/22 15:02:34 mpi Exp $ */ +/* $OpenBSD: if.c,v 1.513 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2666,10 +2666,14 @@ ifpromisc(struct ifnet *ifp, int pswitch) return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); } +/* XXX move to kern/uipc_mbuf.c */ int sysctl_mq(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct mbuf_queue *mq) { + unsigned int maxlen; + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -2678,8 +2682,14 @@ sysctl_mq(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IFQCTL_LEN: return (sysctl_rdint(oldp, oldlenp, newp, mq_len(mq))); case IFQCTL_MAXLEN: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &mq->mq_maxlen)); /* XXX directly accessing maxlen */ + maxlen = mq->mq_maxlen; + error = sysctl_int(oldp, oldlenp, newp, newlen, &maxlen); + if (!error && maxlen != mq->mq_maxlen) { + mtx_enter(&mq->mq_mtx); + mq->mq_maxlen = maxlen; + mtx_leave(&mq->mq_mtx); + } + return (error); case IFQCTL_DROPS: return (sysctl_rdint(oldp, oldlenp, newp, mq_drops(mq))); default: diff --git a/sys/net/if_etherip.c b/sys/net/if_etherip.c index b10909a41be..5d83bd1d4e8 100644 --- a/sys/net/if_etherip.c +++ b/sys/net/if_etherip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_etherip.c,v 1.19 2017/06/06 11:51:13 mpi Exp $ */ +/* $OpenBSD: if_etherip.c,v 1.20 2017/10/09 08:35:38 mpi Exp $ */ /* * Copyright (c) 2015 Kazuya GODA <goda@openbsd.org> * @@ -662,18 +662,26 @@ int ip_etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return ENOTDIR; switch (name[0]) { case ETHERIPCTL_ALLOW: - return sysctl_int(oldp, oldlenp, newp, newlen, ðerip_allow); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, ðerip_allow); + NET_UNLOCK(); + return (error); case ETHERIPCTL_STATS: if (newp != NULL) return EPERM; - return sysctl_struct(oldp, oldlenp, newp, newlen, + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, ðeripstat, sizeof(etheripstat)); + NET_UNLOCK(); + return (error); default: break; } diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 947accd6c44..76a38551e17 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.166 2017/09/08 05:36:53 deraadt Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.167 2017/10/09 08:35:38 mpi Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -2386,8 +2386,6 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, int error = EINVAL; u_int rdomain; - NET_ASSERT_LOCKED(); - if (new) return (EPERM); if (namelen < 1) @@ -2403,7 +2401,9 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case NET_KEY_SADB_DUMP: if ((error = suser(curproc, 0)) != 0) return (error); + NET_LOCK(); error = tdb_walk(rdomain, pfkeyv2_sysctl_walker, &w); + NET_UNLOCK(); if (oldp) *oldlenp = w.w_where - oldp; else @@ -2411,8 +2411,10 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, break; case NET_KEY_SPD_DUMP: + NET_LOCK(); error = pfkeyv2_ipo_walk(rdomain, pfkeyv2_sysctl_policydumper, &w); + NET_UNLOCK(); if (oldp) *oldlenp = w.w_where - oldp; else diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index b7ba9cd5d59..dc77a2411b3 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.250 2017/09/05 07:59:11 mpi Exp $ */ +/* $OpenBSD: rtsock.c,v 1.251 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -1733,8 +1733,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, struct rt_tableinfo tableinfo; u_int tableid = 0; - NET_ASSERT_LOCKED(); - if (new) return (EPERM); if (namelen < 3 || namelen > 4) @@ -1757,6 +1755,7 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, switch (w.w_op) { case NET_RT_DUMP: case NET_RT_FLAGS: + NET_LOCK(); for (i = 1; i <= AF_MAX; i++) { if (af != 0 && af != i) continue; @@ -1767,10 +1766,13 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, if (error) break; } + NET_UNLOCK(); break; case NET_RT_IFLIST: + NET_LOCK(); error = sysctl_iflist(af, &w); + NET_UNLOCK(); break; case NET_RT_STATS: @@ -1786,7 +1788,9 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, &tableinfo, sizeof(tableinfo)); return (error); case NET_RT_IFNAMES: + NET_LOCK(); error = sysctl_ifnames(&w); + NET_UNLOCK(); break; } free(w.w_tmem, M_RTABLE, 0); diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index b4b23884d47..a358e73c8c6 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: igmp.c,v 1.69 2017/06/19 17:58:49 bluhm Exp $ */ +/* $OpenBSD: igmp.c,v 1.70 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: igmp.c,v 1.15 1996/02/13 23:41:25 christos Exp $ */ /* @@ -680,6 +680,8 @@ int igmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -690,9 +692,13 @@ igmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, return (EPERM); return (igmp_sysctl_igmpstat(oldp, oldlenp, newp)); default: - if (name[0] < IGMPCTL_MAXID) - return (sysctl_int_arr(igmpctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < IGMPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(igmpctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } /* NOTREACHED */ diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index a18d778f2e9..abb4766fb26 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.315 2017/08/11 21:24:19 mpi Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.316 2017/10/09 08:35:38 mpi Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -739,6 +739,8 @@ int carp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -749,8 +751,11 @@ carp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, default: if (name[0] <= 0 || name[0] >= CARPCTL_MAXID) return (ENOPROTOOPT); - return sysctl_int(oldp, oldlenp, newp, newlen, + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, &carp_opts[name[0]]); + NET_UNLOCK(); + return (error); } } diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 466a41a8651..6f1bc3e55ee 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_divert.c,v 1.54 2017/10/06 22:08:30 bluhm Exp $ */ +/* $OpenBSD: ip_divert.c,v 1.55 2017/10/09 08:35:38 mpi Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -360,23 +360,35 @@ int divert_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case DIVERTCTL_SENDSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert_sendspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert_sendspace); + NET_UNLOCK(); + return (error); case DIVERTCTL_RECVSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert_recvspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert_recvspace); + NET_UNLOCK(); + return (error); case DIVERTCTL_STATS: return (divert_sysctl_divstat(oldp, oldlenp, newp)); default: - if (name[0] < DIVERTCTL_MAXID) - return sysctl_int_arr(divertctl_vars, name, namelen, + if (name[0] < DIVERTCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(divertctl_vars, name, namelen, oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } diff --git a/sys/netinet/ip_ether.c b/sys/netinet/ip_ether.c index c90b61441c0..37721a19349 100644 --- a/sys/netinet/ip_ether.c +++ b/sys/netinet/ip_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ether.c,v 1.86 2017/06/19 17:58:49 bluhm Exp $ */ +/* $OpenBSD: ip_ether.c,v 1.87 2017/10/09 08:35:38 mpi Exp $ */ /* * The author of this code is Angelos D. Keromytis (kermit@adk.gr) * @@ -468,19 +468,27 @@ int etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case ETHERIPCTL_ALLOW: - return (sysctl_int(oldp, oldlenp, newp, newlen, - ðerip_allow)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + ðerip_allow); + NET_UNLOCK(); + return (error); case ETHERIPCTL_STATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - ðeripstat, sizeof(etheripstat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + ðeripstat, sizeof(etheripstat)); + NET_UNLOCK(); + return (error); default: return (ENOPROTOOPT); } diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index d87ee2addb2..3f3672285ef 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_gre.c,v 1.66 2017/08/15 17:47:15 bluhm Exp $ */ +/* $OpenBSD: ip_gre.c,v 1.67 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -373,15 +373,23 @@ int gre_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case GRECTL_ALLOW: - return (sysctl_int(oldp, oldlenp, newp, newlen, &gre_allow)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_allow); + NET_UNLOCK(); + return (error); case GRECTL_WCCP: - return (sysctl_int(oldp, oldlenp, newp, newlen, &gre_wccp)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_wccp); + NET_UNLOCK(); + return (error); default: return (ENOPROTOOPT); } @@ -392,14 +400,19 @@ int ipmobile_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case MOBILEIPCTL_ALLOW: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &ip_mobile_allow)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &ip_mobile_allow); + NET_UNLOCK(); + return (error); default: return (ENOPROTOOPT); } diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index cdfa20cccd7..954f4219769 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.171 2017/08/10 02:26:26 bluhm Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.172 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -881,8 +881,6 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, { int error; - NET_ASSERT_LOCKED(); - /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -890,6 +888,7 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, switch (name[0]) { case ICMPCTL_REDIRTIMEOUT: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &icmp_redirtimeout); if (icmp_redirect_timeout_q != NULL) { @@ -903,6 +902,7 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, icmp_redirect_timeout_q = rt_timer_queue_create(icmp_redirtimeout); } + NET_UNLOCK(); break; case ICMPCTL_STATS: @@ -911,8 +911,10 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, default: if (name[0] < ICMPCTL_MAXID) { + NET_LOCK(); error = sysctl_int_arr(icmpctl_vars, name, namelen, oldp, oldlenp, newp, newlen); + NET_UNLOCK(); break; } error = ENOPROTOOPT; diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 5149f7924d6..bf07a950b15 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.322 2017/09/07 10:54:49 bluhm Exp $ */ +/* $OpenBSD: ip_input.c,v 1.323 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -1617,26 +1617,24 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, extern struct mrtstat mrtstat; #endif - NET_ASSERT_LOCKED(); - /* Almost all sysctl names at this level are terminal. */ if (namelen != 1 && name[0] != IPCTL_IFQUEUE) return (ENOTDIR); switch (name[0]) { -#ifdef notyet - case IPCTL_DEFMTU: - return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtu)); -#endif case IPCTL_SOURCEROUTE: /* * Don't allow this to change in a secure environment. */ if (newp && securelevel > 0) return (EPERM); - return (sysctl_int(oldp, oldlenp, newp, newlen, - &ip_dosourceroute)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &ip_dosourceroute); + NET_UNLOCK(); + return (error); case IPCTL_MTUDISC: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc); if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) { @@ -1646,25 +1644,37 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, rt_timer_queue_destroy(ip_mtudisc_timeout_q); ip_mtudisc_timeout_q = NULL; } + NET_UNLOCK(); return error; case IPCTL_MTUDISCTIMEOUT: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc_timeout); if (ip_mtudisc_timeout_q != NULL) rt_timer_queue_change(ip_mtudisc_timeout_q, ip_mtudisc_timeout); + NET_UNLOCK(); return (error); case IPCTL_IPSEC_ENC_ALGORITHM: - return (sysctl_tstring(oldp, oldlenp, newp, newlen, - ipsec_def_enc, sizeof(ipsec_def_enc))); + NET_LOCK(); + error = sysctl_tstring(oldp, oldlenp, newp, newlen, + ipsec_def_enc, sizeof(ipsec_def_enc)); + NET_UNLOCK(); + return (error); case IPCTL_IPSEC_AUTH_ALGORITHM: - return (sysctl_tstring(oldp, oldlenp, newp, newlen, + NET_LOCK(); + error = sysctl_tstring(oldp, oldlenp, newp, newlen, ipsec_def_auth, - sizeof(ipsec_def_auth))); + sizeof(ipsec_def_auth)); + NET_UNLOCK(); + return (error); case IPCTL_IPSEC_IPCOMP_ALGORITHM: - return (sysctl_tstring(oldp, oldlenp, newp, newlen, + NET_LOCK(); + error = sysctl_tstring(oldp, oldlenp, newp, newlen, ipsec_def_comp, - sizeof(ipsec_def_comp))); + sizeof(ipsec_def_comp)); + NET_UNLOCK(); + return (error); case IPCTL_IFQUEUE: return (sysctl_niq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &ipintrq)); @@ -1679,11 +1689,17 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case IPCTL_MRTMFC: if (newp) return (EPERM); - return mrt_sysctl_mfc(oldp, oldlenp); + NET_LOCK(); + error = mrt_sysctl_mfc(oldp, oldlenp); + NET_UNLOCK(); + return (error); case IPCTL_MRTVIF: if (newp) return (EPERM); - return mrt_sysctl_vif(oldp, oldlenp); + NET_LOCK(); + error = mrt_sysctl_vif(oldp, oldlenp); + NET_UNLOCK(); + return (error); #else case IPCTL_MRTPROTO: case IPCTL_MRTSTATS: @@ -1692,9 +1708,13 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (EOPNOTSUPP); #endif default: - if (name[0] < IPCTL_MAXID) - return (sysctl_int_arr(ipctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < IPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(ipctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (EOPNOTSUPP); } /* NOTREACHED */ diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c index 1eb94e06d70..7b552557586 100644 --- a/sys/netinet/ip_ipip.c +++ b/sys/netinet/ip_ipip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipip.c,v 1.86 2017/07/05 11:34:10 bluhm Exp $ */ +/* $OpenBSD: ip_ipip.c,v 1.87 2017/10/09 08:35:38 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -592,13 +592,18 @@ int ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case IPIPCTL_ALLOW: - return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow); + NET_UNLOCK(); + return (error); case IPIPCTL_STATS: return (ipip_sysctl_ipipstat(oldp, oldlenp, newp)); default: diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index a3fad485026..07c040c9b77 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.156 2017/07/05 11:34:10 bluhm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.157 2017/10/09 08:35:38 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -615,6 +615,8 @@ int esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -623,12 +625,19 @@ esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case ESPCTL_STATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &espstat, sizeof(espstat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + &espstat, sizeof(espstat)); + NET_UNLOCK(); + return (error); default: - if (name[0] < ESPCTL_MAXID) - return (sysctl_int_arr(espctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < ESPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(espctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } } @@ -637,6 +646,8 @@ int ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -645,12 +656,19 @@ ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case AHCTL_STATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &ahstat, sizeof(ahstat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + &ahstat, sizeof(ahstat)); + NET_UNLOCK(); + return (error); default: - if (name[0] < AHCTL_MAXID) - return (sysctl_int_arr(ahctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < AHCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(ahctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } } @@ -659,6 +677,8 @@ int ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -667,12 +687,19 @@ ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case IPCOMPCTL_STATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &ipcompstat, sizeof(ipcompstat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + &ipcompstat, sizeof(ipcompstat)); + NET_UNLOCK(); + return (error); default: - if (name[0] < IPCOMPCTL_MAXID) - return (sysctl_int_arr(ipcompctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < IPCOMPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(ipcompctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } } diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 1ff211b69ae..1e70b9e07c9 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.155 2017/09/05 07:59:11 mpi Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.156 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -955,8 +955,6 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, { int error, nval; - NET_ASSERT_LOCKED(); - /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); @@ -964,73 +962,91 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, switch (name[0]) { #ifdef TCP_SACK case TCPCTL_SACK: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_do_sack)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_do_sack); + NET_UNLOCK(); + return (error); #endif case TCPCTL_SLOWHZ: return (sysctl_rdint(oldp, oldlenp, newp, PR_SLOWHZ)); case TCPCTL_BADDYNAMIC: - return (sysctl_struct(oldp, oldlenp, newp, newlen, - baddynamicports.tcp, sizeof(baddynamicports.tcp))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + baddynamicports.tcp, sizeof(baddynamicports.tcp)); + NET_UNLOCK(); + return (error); case TCPCTL_ROOTONLY: if (newp && securelevel > 0) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - rootonlyports.tcp, sizeof(rootonlyports.tcp))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + rootonlyports.tcp, sizeof(rootonlyports.tcp)); + NET_UNLOCK(); + return (error); case TCPCTL_IDENT: - return (tcp_ident(oldp, oldlenp, newp, newlen, 0)); + NET_LOCK(); + error = tcp_ident(oldp, oldlenp, newp, newlen, 0); + NET_UNLOCK(); + return (error); case TCPCTL_DROP: - return (tcp_ident(oldp, oldlenp, newp, newlen, 1)); + NET_LOCK(); + error = tcp_ident(oldp, oldlenp, newp, newlen, 1); + NET_UNLOCK(); + return (error); case TCPCTL_ALWAYS_KEEPALIVE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_always_keepalive)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_always_keepalive); + NET_UNLOCK(); + return (error); #ifdef TCP_ECN case TCPCTL_ECN: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &tcp_do_ecn)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_do_ecn); + NET_UNLOCK(); + return (error); #endif case TCPCTL_REASS_LIMIT: + NET_LOCK(); nval = tcp_reass_limit; error = sysctl_int(oldp, oldlenp, newp, newlen, &nval); - if (error) - return (error); - if (nval != tcp_reass_limit) { + if (!error && nval != tcp_reass_limit) { error = pool_sethardlimit(&tcpqe_pool, nval, NULL, 0); - if (error) - return (error); - tcp_reass_limit = nval; + if (!error) + tcp_reass_limit = nval; } - return (0); + NET_UNLOCK(); + return (error); #ifdef TCP_SACK case TCPCTL_SACKHOLE_LIMIT: + NET_LOCK(); nval = tcp_sackhole_limit; error = sysctl_int(oldp, oldlenp, newp, newlen, &nval); - if (error) - return (error); - if (nval != tcp_sackhole_limit) { + if (!error && nval != tcp_sackhole_limit) { error = pool_sethardlimit(&sackhl_pool, nval, NULL, 0); - if (error) - return (error); - tcp_sackhole_limit = nval; + if (!error) + tcp_sackhole_limit = nval; } - return (0); + NET_UNLOCK(); + return (error); #endif case TCPCTL_STATS: return (tcp_sysctl_tcpstat(oldp, oldlenp, newp)); case TCPCTL_SYN_USE_LIMIT: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &tcp_syn_use_limit); - if (error) - return (error); - if (newp != NULL) { + if (!error && newp != NULL) { /* * Global tcp_syn_use_limit is used when reseeding a * new cache. Also update the value in active cache. @@ -1040,33 +1056,40 @@ tcp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, if (tcp_syn_cache[1].scs_use > tcp_syn_use_limit) tcp_syn_cache[1].scs_use = tcp_syn_use_limit; } - return (0); + NET_UNLOCK(); + return (error); case TCPCTL_SYN_HASH_SIZE: + NET_LOCK(); nval = tcp_syn_hash_size; error = sysctl_int(oldp, oldlenp, newp, newlen, &nval); - if (error) - return (error); - if (nval != tcp_syn_hash_size) { - if (nval < 1 || nval > 100000) - return (EINVAL); - /* - * If global hash size has been changed, switch sets as - * soon as possible. Then the actual hash array will - * be reallocated. - */ - if (tcp_syn_cache[0].scs_size != nval) - tcp_syn_cache[0].scs_use = 0; - if (tcp_syn_cache[1].scs_size != nval) - tcp_syn_cache[1].scs_use = 0; - tcp_syn_hash_size = nval; + if (!error && nval != tcp_syn_hash_size) { + if (nval < 1 || nval > 100000) { + error = EINVAL; + } else { + /* + * If global hash size has been changed, + * switch sets as soon as possible. Then + * the actual hash array will be reallocated. + */ + if (tcp_syn_cache[0].scs_size != nval) + tcp_syn_cache[0].scs_use = 0; + if (tcp_syn_cache[1].scs_size != nval) + tcp_syn_cache[1].scs_use = 0; + tcp_syn_hash_size = nval; + } } - return (0); + NET_UNLOCK(); + return (error); default: - if (name[0] < TCPCTL_MAXID) - return (sysctl_int_arr(tcpctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < TCPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(tcpctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } /* NOTREACHED */ diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 6d3916980b1..95b093bee58 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.240 2017/09/05 07:59:11 mpi Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.241 2017/10/09 08:35:38 mpi Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -1277,20 +1277,28 @@ int udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case UDPCTL_BADDYNAMIC: - return (sysctl_struct(oldp, oldlenp, newp, newlen, - baddynamicports.udp, sizeof(baddynamicports.udp))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + baddynamicports.udp, sizeof(baddynamicports.udp)); + NET_UNLOCK(); + return (error); case UDPCTL_ROOTONLY: if (newp && securelevel > 0) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - rootonlyports.udp, sizeof(rootonlyports.udp))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + rootonlyports.udp, sizeof(rootonlyports.udp)); + NET_UNLOCK(); + return (error); case UDPCTL_STATS: if (newp != NULL) @@ -1299,9 +1307,13 @@ udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (udp_sysctl_udpstat(oldp, oldlenp, newp)); default: - if (name[0] < UDPCTL_MAXID) - return (sysctl_int_arr(udpctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < UDPCTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(udpctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } /* NOTREACHED */ diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 9602b127d07..3becc223313 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.216 2017/09/01 15:05:31 mpi Exp $ */ +/* $OpenBSD: icmp6.c,v 1.217 2017/10/09 08:35:38 mpi Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1887,6 +1887,8 @@ int icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return ENOTDIR; @@ -1896,9 +1898,13 @@ icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case ICMPV6CTL_STATS: return icmp6_sysctl_icmp6stat(oldp, oldlenp, newp); default: - if (name[0] < ICMPV6CTL_MAXID) - return (sysctl_int_arr(icmpv6ctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < ICMPV6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(icmpv6ctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return ENOPROTOOPT; } /* NOTREACHED */ diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c index 011514a521e..1f20dc64d83 100644 --- a/sys/netinet6/ip6_divert.c +++ b/sys/netinet6/ip6_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.c,v 1.53 2017/10/06 22:08:30 bluhm Exp $ */ +/* $OpenBSD: ip6_divert.c,v 1.54 2017/10/09 08:35:38 mpi Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -363,23 +363,35 @@ int divert6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case DIVERT6CTL_SENDSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert6_sendspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert6_sendspace); + NET_UNLOCK(); + return (error); case DIVERT6CTL_RECVSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert6_recvspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert6_recvspace); + NET_UNLOCK(); + return (error); case DIVERT6CTL_STATS: return (divert6_sysctl_div6stat(oldp, oldlenp, newp)); default: - if (name[0] < DIVERT6CTL_MAXID) - return sysctl_int_arr(divert6ctl_vars, name, namelen, + if (name[0] < DIVERT6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(divert6ctl_vars, name, namelen, oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index ade41a8a03b..4e588d83394 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.202 2017/08/22 15:02:34 mpi Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.203 2017/10/09 08:35:38 mpi Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -1383,8 +1383,6 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, #endif int error; - NET_ASSERT_LOCKED(); - /* Almost all sysctl names at this level are terminal. */ if (namelen != 1 && name[0] != IPV6CTL_IFQUEUE) return (ENOTDIR); @@ -1398,18 +1396,27 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IPV6CTL_MRTSTATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &mrt6stat, sizeof(mrt6stat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + &mrt6stat, sizeof(mrt6stat)); + NET_UNLOCK(); + return (error); case IPV6CTL_MRTPROTO: return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto); case IPV6CTL_MRTMIF: if (newp) return (EPERM); - return mrt6_sysctl_mif(oldp, oldlenp); + NET_LOCK(); + error = mrt6_sysctl_mif(oldp, oldlenp); + NET_UNLOCK(); + return (error); case IPV6CTL_MRTMFC: if (newp) return (EPERM); - return mrt6_sysctl_mfc(oldp, oldlenp); + NET_LOCK(); + error = mrt6_sysctl_mfc(oldp, oldlenp); + NET_UNLOCK(); + return (error); #else case IPV6CTL_MRTSTATS: case IPV6CTL_MRTPROTO: @@ -1418,19 +1425,25 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, return (EOPNOTSUPP); #endif case IPV6CTL_MTUDISCTIMEOUT: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip6_mtudisc_timeout); if (icmp6_mtudisc_timeout_q != NULL) rt_timer_queue_change(icmp6_mtudisc_timeout_q, ip6_mtudisc_timeout); + NET_UNLOCK(); return (error); case IPV6CTL_IFQUEUE: return (sysctl_niq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &ip6intrq)); default: - if (name[0] < IPV6CTL_MAXID) - return (sysctl_int_arr(ipv6ctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < IPV6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(ipv6ctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (EOPNOTSUPP); } /* NOTREACHED */ |