From: Vitaliy Makkoveev Subject: sysctl(2): unlock ah_sysctl() and ipcomp_sysctl() To: Alexander Bluhm , tech@openbsd.org Date: Fri, 6 Dec 2024 00:11:38 +0300 Both are atomically accessed `ah_enable' and `ipcomp_enable' booleans and per-CPU counters based statistics. esp_sysctl() is much more system wide, so I want unlock it separately. Index: sys/netinet/in_proto.c =================================================================== RCS file: /cvs/src/sys/netinet/in_proto.c,v diff -u -p -r1.116 in_proto.c --- sys/netinet/in_proto.c 4 Dec 2024 22:48:41 -0000 1.116 +++ sys/netinet/in_proto.c 5 Dec 2024 21:00:16 -0000 @@ -285,7 +285,7 @@ const struct protosw inetsw[] = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_AH, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL, .pr_input = ah46_input, .pr_ctlinput = ah4_ctlinput, .pr_ctloutput = rip_ctloutput, @@ -307,7 +307,7 @@ const struct protosw inetsw[] = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_IPCOMP, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL, .pr_input = ipcomp46_input, .pr_ctloutput = rip_ctloutput, .pr_usrreqs = &rip_usrreqs, Index: sys/netinet/ipsec_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ipsec_input.c,v diff -u -p -r1.206 ipsec_input.c --- sys/netinet/ipsec_input.c 16 Sep 2023 09:33:27 -0000 1.206 +++ sys/netinet/ipsec_input.c 5 Dec 2024 21:00:17 -0000 @@ -86,6 +86,11 @@ #include "bpfilter.h" +/* + * Locks used to protect data: + * a atomic + */ + void ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int); #ifdef ENCDEBUG @@ -114,8 +119,8 @@ int ipsec_exp_first_use = IPSEC_DEFAULT_ int ipsec_expire_acquire = IPSEC_DEFAULT_EXPIRE_ACQUIRE; int esp_enable = 1; -int ah_enable = 1; -int ipcomp_enable = 0; +int ah_enable = 1; /* [a] */ +int ipcomp_enable = 0; /* [a] */ const struct sysctl_bounded_args espctl_vars[] = { {ESPCTL_ENABLE, &esp_enable, 0, 1}, @@ -673,8 +678,6 @@ 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); @@ -683,11 +686,8 @@ ah_sysctl(int *name, u_int namelen, void case AHCTL_STATS: return ah_sysctl_ahstat(oldp, oldlenp, newp); default: - NET_LOCK(); - error = sysctl_bounded_arr(ahctl_vars, nitems(ahctl_vars), name, + return sysctl_bounded_arr(ahctl_vars, nitems(ahctl_vars), name, namelen, oldp, oldlenp, newp, newlen); - NET_UNLOCK(); - return (error); } } @@ -706,8 +706,6 @@ 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); @@ -716,12 +714,9 @@ ipcomp_sysctl(int *name, u_int namelen, case IPCOMPCTL_STATS: return ipcomp_sysctl_ipcompstat(oldp, oldlenp, newp); default: - NET_LOCK(); - error = sysctl_bounded_arr(ipcompctl_vars, + return sysctl_bounded_arr(ipcompctl_vars, nitems(ipcompctl_vars), name, namelen, oldp, oldlenp, newp, newlen); - NET_UNLOCK(); - return (error); } } @@ -775,7 +770,7 @@ ah46_input(struct mbuf **mp, int *offp, #if NPF > 0 ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) || #endif - !ah_enable) + !atomic_load_int(&ah_enable)) return ipsec_input_disabled(mp, offp, proto, af); protoff = ipsec_protoff(*mp, *offp, af); @@ -832,7 +827,7 @@ ipcomp46_input(struct mbuf **mp, int *of #if NPF > 0 ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) || #endif - !ipcomp_enable) + !atomic_load_int(&ipcomp_enable)) return ipsec_input_disabled(mp, offp, proto, af); protoff = ipsec_protoff(*mp, *offp, af); Index: sys/netinet/ipsec_output.c =================================================================== RCS file: /cvs/src/sys/netinet/ipsec_output.c,v diff -u -p -r1.98 ipsec_output.c --- sys/netinet/ipsec_output.c 11 Feb 2024 01:27:45 -0000 1.98 +++ sys/netinet/ipsec_output.c 5 Dec 2024 21:00:17 -0000 @@ -92,8 +92,9 @@ ipsp_process_packet(struct mbuf *m, stru /* Check that the transform is allowed by the administrator. */ if ((tdb->tdb_sproto == IPPROTO_ESP && !esp_enable) || - (tdb->tdb_sproto == IPPROTO_AH && !ah_enable) || - (tdb->tdb_sproto == IPPROTO_IPCOMP && !ipcomp_enable)) { + (tdb->tdb_sproto == IPPROTO_AH && !atomic_load_int(&ah_enable)) || + (tdb->tdb_sproto == IPPROTO_IPCOMP && + !atomic_load_int(&ipcomp_enable))) { DPRINTF("IPsec outbound packet dropped due to policy " "(check your sysctls)"); error = EHOSTUNREACH; Index: sys/netinet6/in6_proto.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_proto.c,v diff -u -p -r1.120 in6_proto.c --- sys/netinet6/in6_proto.c 4 Dec 2024 22:48:41 -0000 1.120 +++ sys/netinet6/in6_proto.c 5 Dec 2024 21:00:17 -0000 @@ -205,7 +205,7 @@ const struct protosw inet6sw[] = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_AH, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL, .pr_input = ah46_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs, @@ -225,7 +225,7 @@ const struct protosw inet6sw[] = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_IPCOMP, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPSOCKET|PR_MPSYSCTL, .pr_input = ipcomp46_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs,