Module Name: src Committed By: christos Date: Sun Jan 2 20:50:56 UTC 2011
Modified Files: src/sys/kern: kern_verifiedexec.c Log Message: Simplify and avoid kernel segv when the list is NULL. To generate a diff of this commit: cvs rdiff -u -r1.122 -r1.123 src/sys/kern/kern_verifiedexec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_verifiedexec.c diff -u src/sys/kern/kern_verifiedexec.c:1.122 src/sys/kern/kern_verifiedexec.c:1.123 --- src/sys/kern/kern_verifiedexec.c:1.122 Wed Nov 17 15:07:50 2010 +++ src/sys/kern/kern_verifiedexec.c Sun Jan 2 15:50:55 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_verifiedexec.c,v 1.122 2010/11/17 20:07:50 dholland Exp $ */ +/* $NetBSD: kern_verifiedexec.c,v 1.123 2011/01/02 20:50:55 christos Exp $ */ /*- * Copyright (c) 2005, 2006 Elad Efrat <e...@netbsd.org> @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.122 2010/11/17 20:07:50 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.123 2011/01/02 20:50:55 christos Exp $"); #include "opt_veriexec.h" @@ -145,39 +145,52 @@ * Sysctl helper routine for Veriexec. */ static int -sysctl_kern_veriexec(SYSCTLFN_ARGS) +sysctl_kern_veriexec_algorithms(SYSCTLFN_ARGS) { - int newval, error; - int *var = NULL, raise_only = 0; - struct sysctlnode node; + size_t len; + int error; + const char *p; - node = *rnode; + if (newp != NULL) + return EPERM; - if (strcmp(rnode->sysctl_name, "strict") == 0) { - raise_only = 1; - var = &veriexec_strict; - } else if (strcmp(rnode->sysctl_name, "algorithms") == 0) { - node.sysctl_data = veriexec_fp_names; - node.sysctl_size = strlen(veriexec_fp_names) + 1; - return (sysctl_lookup(SYSCTLFN_CALL(&node))); - } else { - return (EINVAL); - } + if (namelen != 0) + return EINVAL; + + p = veriexec_fp_names == NULL ? "" : veriexec_fp_names; + + len = strlen(p) + 1; + + if (*oldlenp < len) + return ENOMEM; + + if ((error = copyout(p, oldp, len)) != 0) + return error; + + *oldlenp = len; + return 0; +} - newval = *var; +static int +sysctl_kern_veriexec_strict(SYSCTLFN_ARGS) +{ + struct sysctlnode node; + int error, newval; + node = *rnode; node.sysctl_data = &newval; + + newval = veriexec_strict; error = sysctl_lookup(SYSCTLFN_CALL(&node)); - if (error || newp == NULL) { - return (error); - } + if (error || newp == NULL) + return error; - if (raise_only && (newval < *var)) - return (EPERM); + if (newval < veriexec_strict) + return EPERM; - *var = newval; + veriexec_strict = newval; - return (error); + return 0; } SYSCTL_SETUP(sysctl_kern_veriexec_setup, "sysctl kern.veriexec setup") @@ -207,14 +220,14 @@ CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "strict", SYSCTL_DESCR("Veriexec strict level"), - sysctl_kern_veriexec, 0, NULL, 0, + sysctl_kern_veriexec_strict, 0, NULL, 0, CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, &rnode, NULL, CTLFLAG_PERMANENT, CTLTYPE_STRING, "algorithms", SYSCTL_DESCR("Veriexec supported hashing " "algorithms"), - sysctl_kern_veriexec, 0, NULL, 0, + sysctl_kern_veriexec_algorithms, 0, NULL, 0, CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, &rnode, &veriexec_count_node, CTLFLAG_PERMANENT,