Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Simplify and avoid kernel segv when the list is NULL.



details:   https://anonhg.NetBSD.org/src/rev/41dbc91fe5a8
branches:  trunk
changeset: 760329:41dbc91fe5a8
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Jan 02 20:50:55 2011 +0000

description:
Simplify and avoid kernel segv when the list is NULL.

diffstat:

 sys/kern/kern_verifiedexec.c |  71 ++++++++++++++++++++++++++-----------------
 1 files changed, 42 insertions(+), 29 deletions(-)

diffs (113 lines):

diff -r adf1e3738ae6 -r 41dbc91fe5a8 sys/kern/kern_verifiedexec.c
--- a/sys/kern/kern_verifiedexec.c      Sun Jan 02 19:24:47 2011 +0000
+++ b/sys/kern/kern_verifiedexec.c      Sun Jan 02 20:50:55 2011 +0000
@@ -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 <elad%NetBSD.org@localhost>
@@ -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;
+       size_t len;
+       int error;
+       const char *p;
+
+       if (newp != NULL)
+               return EPERM;
+
+       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;
+}
+
+static int
+sysctl_kern_veriexec_strict(SYSCTLFN_ARGS)
+{
        struct sysctlnode node;
+       int error, newval;
 
        node = *rnode;
+       node.sysctl_data = &newval;
 
-       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);
-       }
+       newval = veriexec_strict;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
 
-       newval = *var;
+       if (newval < veriexec_strict)
+               return EPERM;
 
-       node.sysctl_data = &newval;
-       error = sysctl_lookup(SYSCTLFN_CALL(&node));
-       if (error || newp == NULL) {
-               return (error);
-       }
+       veriexec_strict = newval;
 
-       if (raise_only && (newval < *var))
-               return (EPERM);
-
-       *var = 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,



Home | Main Index | Thread Index | Old Index