From 7ccae7b0e7f5e619c0b8eac6f0bf5807a323ffb4 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 6 Aug 2025 22:26:47 -0400 Subject: kernel: sysctl: Allow 'old*' fields to be NULL When setting sysctl variables from userspace, the 'old' fields will unused and thus typically be set to NULL. This commit modifies the behaviour of do_sysctl() to enable this. Signed-off-by: Ian Moffett --- sys/kern/kern_sysctl.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'sys/kern/kern_sysctl.c') diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index ad90f1a..8b298a7 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -91,19 +91,17 @@ static int do_sysctl(struct sysctl_args *args) { struct sysctl_args new_args; - size_t name_len, oldlenp; + size_t name_len = 1, oldlenp = 0; int *name = NULL; void *oldp = NULL, *newp = NULL; int retval = 0; - if (args->oldlenp == NULL) { - return -EINVAL; - } - - name_len = args->nlen; - retval = copyin(args->oldlenp, &oldlenp, sizeof(oldlenp)); - if (retval != 0) { - goto done; + if (args->oldlenp != NULL) { + name_len = args->nlen; + retval = copyin(args->oldlenp, &oldlenp, sizeof(oldlenp)); + if (retval != 0) { + goto done; + } } /* Copy in newp if it is set */ @@ -124,10 +122,12 @@ do_sysctl(struct sysctl_args *args) return retval; } - oldp = dynalloc(oldlenp); - retval = copyin(args->oldp, oldp, oldlenp); - if (retval != 0) { - return retval; + if (oldlenp != 0) { + oldp = dynalloc(oldlenp); + retval = copyin(args->oldp, oldp, oldlenp); + if (retval != 0) { + return retval; + } } /* Prepare the arguments for the sysctl call */ @@ -143,7 +143,9 @@ do_sysctl(struct sysctl_args *args) goto done; } - copyout(oldp, args->oldp, oldlenp); + if (oldlenp != 0) { + copyout(oldp, args->oldp, oldlenp); + } done: if (name != NULL) dynfree(name); -- cgit v1.2.3