Rearrange the implementation of bounded sysctl. The primitive
authorbluhm <bluhm@openbsd.org>
Fri, 30 Apr 2021 13:52:48 +0000 (13:52 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 30 Apr 2021 13:52:48 +0000 (13:52 +0000)
functions are sysctl_int() and sysctl_rdint().  This brings us back
the 4.4BSD implementation.  Then sysctl_int_bounded() builds the
magic for range checks on top.  sysctl_bounded_arr() is a wrapper
around it to support multiple variables.
Introduce macros that describe the meaning of the magic boundary
values.  Use these macros in obvious places.
input and OK gnezdo@ mvs@

sys/kern/kern_sysctl.c
sys/kern/kern_tc.c
sys/kern/sysv_sem.c
sys/netinet/ip_input.c
sys/netinet/tcp_usrreq.c
sys/netinet6/ip6_input.c
sys/sys/sysctl.h

index 2cdda78..2a41db4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sysctl.c,v 1.390 2021/04/23 07:21:02 bluhm Exp $ */
+/*     $OpenBSD: kern_sysctl.c,v 1.391 2021/04/30 13:52:48 bluhm Exp $ */
 /*     $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $     */
 
 /*-
@@ -818,13 +818,14 @@ debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  * Reads, or writes that lower the value
  */
 int
-sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
+sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
+    int *valp)
 {
        unsigned int oval = *valp, val = *valp;
        int error;
 
        if (newp == NULL)
-               return (sysctl_rdint(oldp, oldlenp, newp, *valp));
+               return (sysctl_rdint(oldp, oldlenp, newp, val));
 
        if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
                return (error);
@@ -840,36 +841,41 @@ sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *va
  */
 int
 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
-{
-       return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, valp, 0, 0));
-}
-
-int
-sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
-    int *valp, int minimum, int maximum)
 {
        int error = 0;
-       int val;
 
        if (oldp && *oldlenp < sizeof(int))
                return (ENOMEM);
        if (newp && newlen != sizeof(int))
                return (EINVAL);
        *oldlenp = sizeof(int);
-       val = *valp;
        if (oldp)
-               error = copyout(&val, oldp, sizeof(int));
+               error = copyout(valp, oldp, sizeof(int));
        if (error == 0 && newp)
-               error = copyin(newp, &val, sizeof(int));
-       if (error)
-               return (error);
-       if (minimum == maximum || (minimum <= val && val <= maximum))
-               *valp = val;
-       else
-               error = EINVAL;
+               error = copyin(newp, valp, sizeof(int));
        return (error);
 }
 
+int
+sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
+    int *valp, int minimum, int maximum)
+{
+       int val = *valp;
+       int error;
+
+       /* read only */
+       if (newp == NULL || minimum > maximum)
+               return (sysctl_rdint(oldp, oldlenp, newp, val));
+
+       if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
+               return (error);
+       /* bounded and outside limits */
+       if (minimum < maximum && (val < minimum || maximum < val))
+               return (EINVAL);
+       *valp = val;
+       return (0);
+}
+
 /*
  * As above, but read-only.
  */
@@ -901,14 +907,8 @@ sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen,
                return (ENOTDIR);
        for (i = 0; i < valplen; ++i) {
                if (valpp[i].mib == name[0]) {
-                       if (valpp[i].minimum <= valpp[i].maximum) {
-                               return (sysctl_int_bounded(oldp, oldlenp, newp,
-                                   newlen, valpp[i].var, valpp[i].minimum,
-                                   valpp[i].maximum));
-                       } else {
-                               return (sysctl_rdint(oldp, oldlenp, newp,
-                                   *valpp[i].var));
-                       }
+                       return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                           valpp[i].var, valpp[i].minimum, valpp[i].maximum));
                }
        }
        return (EOPNOTSUPP);
index c0eac3d..376d26b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_tc.c,v 1.71 2021/02/23 04:44:31 cheloha Exp $ */
+/*     $OpenBSD: kern_tc.c,v 1.72 2021/04/30 13:52:48 bluhm Exp $ */
 
 /*
  * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
@@ -829,7 +829,7 @@ inittimecounter(void)
 }
 
 const struct sysctl_bounded_args tc_vars[] = {
-       { KERN_TIMECOUNTER_TICK, &tc_tick, 1, 0 },
+       { KERN_TIMECOUNTER_TICK, &tc_tick, SYSCTL_INT_READONLY },
        { KERN_TIMECOUNTER_TIMESTEPWARNINGS, &timestepwarnings, 0, 1 },
 };
 
index a258b5c..4ad2cf2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysv_sem.c,v 1.60 2020/11/17 03:23:54 gnezdo Exp $    */
+/*     $OpenBSD: sysv_sem.c,v 1.61 2021/04/30 13:52:48 bluhm Exp $     */
 /*     $NetBSD: sysv_sem.c,v 1.26 1996/02/09 19:00:25 christos Exp $   */
 
 /*
@@ -860,10 +860,10 @@ sema_reallocate(int val)
 }
 
 const struct sysctl_bounded_args sysvsem_vars[] = {
-       { KERN_SEMINFO_SEMUME, &seminfo.semume, 1, 0 },
-       { KERN_SEMINFO_SEMUSZ, &seminfo.semusz, 1, 0 },
-       { KERN_SEMINFO_SEMVMX, &seminfo.semvmx, 1, 0 },
-       { KERN_SEMINFO_SEMAEM, &seminfo.semaem, 1, 0 },
+       { KERN_SEMINFO_SEMUME, &seminfo.semume, SYSCTL_INT_READONLY },
+       { KERN_SEMINFO_SEMUSZ, &seminfo.semusz, SYSCTL_INT_READONLY },
+       { KERN_SEMINFO_SEMVMX, &seminfo.semvmx, SYSCTL_INT_READONLY },
+       { KERN_SEMINFO_SEMAEM, &seminfo.semaem, SYSCTL_INT_READONLY },
        { KERN_SEMINFO_SEMOPM, &seminfo.semopm, 1, INT_MAX },
 };
 
index 7578303..c2f63e7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_input.c,v 1.358 2021/04/23 21:55:36 bluhm Exp $    */
+/*     $OpenBSD: ip_input.c,v 1.359 2021/04/30 13:52:48 bluhm Exp $    */
 /*     $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
 
 /*
@@ -113,7 +113,7 @@ extern int ip_mrtproto;
 
 const struct sysctl_bounded_args ipctl_vars[] = {
 #ifdef MROUTING
-       { IPCTL_MRTPROTO, &ip_mrtproto, 1, 0 },
+       { IPCTL_MRTPROTO, &ip_mrtproto, SYSCTL_INT_READONLY },
 #endif
        { IPCTL_FORWARDING, &ipforwarding, 0, 2 },
        { IPCTL_SENDREDIRECTS, &ipsendredirects, 0, 1 },
index 71408fb..98d2270 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_usrreq.c,v 1.180 2021/03/10 10:21:49 jsg Exp $    */
+/*     $OpenBSD: tcp_usrreq.c,v 1.181 2021/04/30 13:52:48 bluhm Exp $  */
 /*     $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
 
 /*
@@ -112,7 +112,7 @@ u_int       tcp_autorcvbuf_inc = 16 * 1024;
 
 static int pr_slowhz = PR_SLOWHZ;
 const struct sysctl_bounded_args tcpctl_vars[] = {
-       { TCPCTL_SLOWHZ, &pr_slowhz, 1, 0 },
+       { TCPCTL_SLOWHZ, &pr_slowhz, SYSCTL_INT_READONLY },
        { TCPCTL_RFC1323, &tcp_do_rfc1323, 0, 1 },
        { TCPCTL_KEEPINITTIME, &tcptv_keep_init, 1, 3 * TCPTV_KEEP_INIT },
        { TCPCTL_KEEPIDLE, &tcp_keepidle, 1, 5 * TCPTV_KEEP_IDLE },
index cb50b32..7d76fa7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip6_input.c,v 1.232 2021/03/10 10:21:49 jsg Exp $     */
+/*     $OpenBSD: ip6_input.c,v 1.233 2021/04/30 13:52:48 bluhm Exp $   */
 /*     $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
 
 /*
@@ -1339,9 +1339,9 @@ extern int ip6_mrtproto;
 #endif
 
 const struct sysctl_bounded_args ipv6ctl_vars[] = {
-       { IPV6CTL_DAD_PENDING, &ip6_dad_pending, 1, 0 },
+       { IPV6CTL_DAD_PENDING, &ip6_dad_pending, SYSCTL_INT_READONLY },
 #ifdef MROUTING
-       { IPV6CTL_MRTPROTO, &ip6_mrtproto, 1, 0 },
+       { IPV6CTL_MRTPROTO, &ip6_mrtproto, SYSCTL_INT_READONLY },
 #endif
        { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 1 },
        { IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
index 68c18cf..d574e2c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysctl.h,v 1.214 2021/03/10 10:21:47 jsg Exp $        */
+/*     $OpenBSD: sysctl.h,v 1.215 2021/04/30 13:52:48 bluhm Exp $      */
 /*     $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $  */
 
 /*
@@ -1000,6 +1000,9 @@ struct sysctl_bounded_args {
        int maximum; /* read-only variable if minimum > maximum */
 };
 
+#define SYSCTL_INT_UNBOUNDED   0,0
+#define SYSCTL_INT_READONLY    1,0
+
 /*
  * Internal sysctl function calling convention:
  *