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,

Reply via email to