summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2019-05-22 18:45:08 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2019-05-22 18:45:08 +0000
commit0218d2364b8dbd7d1fac92150c117dd08e20c7b6 (patch)
treea78715aadc208c881372580e4f5e4d7a93d28efa
parent2e0cdd7e7341d4f12421c98ffb59a5d02d4dd48d (diff)
Read and assign the integer value only once. With this sysctl_int() will
do word loads and stores and so partial updates should no longer be observed. With this accessing global variables set by sysctl_int() should be mostly MP save. OK dlg@ mpi@
-rw-r--r--sys/kern/kern_sysctl.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 465bb6038ef..82f26655caf 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.355 2019/05/09 14:59:30 claudio Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.356 2019/05/22 18:45:07 claudio Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -868,16 +868,20 @@ int
sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
{
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(valp, oldp, sizeof(int));
+ error = copyout(&val, oldp, sizeof(int));
if (error == 0 && newp)
- error = copyin(newp, valp, sizeof(int));
+ error = copyin(newp, &val, sizeof(int));
+ if (error == 0)
+ *valp = val;
return (error);
}