From b32486e30fdd0563098df93eb0798e8b778c074f Mon Sep 17 00:00:00 2001 From: bluhm Date: Fri, 30 Apr 2021 13:52:48 +0000 Subject: [PATCH] Rearrange the implementation of bounded sysctl. The primitive 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 | 56 ++++++++++++++++++++-------------------- sys/kern/kern_tc.c | 4 +-- sys/kern/sysv_sem.c | 10 +++---- sys/netinet/ip_input.c | 4 +-- sys/netinet/tcp_usrreq.c | 4 +-- sys/netinet6/ip6_input.c | 6 ++--- sys/sys/sysctl.h | 5 +++- 7 files changed, 46 insertions(+), 43 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 2cdda78ae4a..2a41db49833 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -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); diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index c0eac3d4cdc..376d26b5af1 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -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 @@ -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, ×tepwarnings, 0, 1 }, }; diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index a258b5c4ac6..4ad2cf2a712 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -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 }, }; diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7578303d544..c2f63e79c69 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -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 }, diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 71408fb7a80..98d2270d8f4 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -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 }, diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index cb50b32bdcc..7d76fa7dbf9 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -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 }, diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 68c18cfdf8a..d574e2cb028 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -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: * -- 2.20.1