Module Name: src Committed By: pooka Date: Fri Jan 17 02:12:49 UTC 2014
Modified Files: src/sys/kern: init_sysctl.c kern_sysctl.c subr_cprng.c src/sys/sys: sysctl.h Log Message: Put cprng sysctls into subr_cprng.c. Also, make sysctl_prng static in subr_cprng and get rid of SYSCTL_PRIVATE namespace leak macro. Fixes ping(8) when run against a standalone rump kernel due to appearance of the kern.urandom sysctl node (in case someone was wondering ...) To generate a diff of this commit: cvs rdiff -u -r1.198 -r1.199 src/sys/kern/init_sysctl.c cvs rdiff -u -r1.243 -r1.244 src/sys/kern/kern_sysctl.c cvs rdiff -u -r1.22 -r1.23 src/sys/kern/subr_cprng.c cvs rdiff -u -r1.209 -r1.210 src/sys/sys/sysctl.h 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/init_sysctl.c diff -u src/sys/kern/init_sysctl.c:1.198 src/sys/kern/init_sysctl.c:1.199 --- src/sys/kern/init_sysctl.c:1.198 Sat Sep 14 13:18:02 2013 +++ src/sys/kern/init_sysctl.c Fri Jan 17 02:12:48 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: init_sysctl.c,v 1.198 2013/09/14 13:18:02 joerg Exp $ */ +/* $NetBSD: init_sysctl.c,v 1.199 2014/01/17 02:12:48 pooka Exp $ */ /*- * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -30,15 +30,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.198 2013/09/14 13:18:02 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.199 2014/01/17 02:12:48 pooka Exp $"); #include "opt_sysv.h" #include "opt_compat_netbsd.h" #include "opt_modular.h" #include "pty.h" -#define SYSCTL_PRIVATE - #include <sys/types.h> #include <sys/param.h> #include <sys/sysctl.h> @@ -115,8 +113,6 @@ static int sysctl_kern_cptime(SYSCTLFN_P #if NPTY > 0 static int sysctl_kern_maxptys(SYSCTLFN_PROTO); #endif /* NPTY > 0 */ -static int sysctl_kern_urnd(SYSCTLFN_PROTO); -static int sysctl_kern_arnd(SYSCTLFN_PROTO); static int sysctl_kern_lwp(SYSCTLFN_PROTO); static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO); static int sysctl_kern_root_partition(SYSCTLFN_PROTO); @@ -491,18 +487,6 @@ SYSCTL_SETUP(sysctl_kern_setup, "sysctl NULL, _POSIX_MONOTONIC_CLOCK, NULL, 0, CTL_KERN, KERN_MONOTONIC_CLOCK, CTL_EOL); sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT, - CTLTYPE_INT, "urandom", - SYSCTL_DESCR("Random integer value"), - sysctl_kern_urnd, 0, NULL, 0, - CTL_KERN, KERN_URND, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT, - CTLTYPE_INT, "arandom", - SYSCTL_DESCR("n bytes of random data"), - sysctl_kern_arnd, 0, NULL, 0, - CTL_KERN, KERN_ARND, CTL_EOL); - sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, CTLTYPE_INT, "labelsector", SYSCTL_DESCR("Sector number containing the disklabel"), @@ -1298,64 +1282,6 @@ sysctl_kern_maxptys(SYSCTLFN_ARGS) #endif /* NPTY > 0 */ /* - * sysctl helper routine for kern.urandom node. Picks a random number - * for you. - */ -static int -sysctl_kern_urnd(SYSCTLFN_ARGS) -{ - int v, rv; - - rv = cprng_strong(sysctl_prng, &v, sizeof(v), 0); - if (rv == sizeof(v)) { - struct sysctlnode node = *rnode; - node.sysctl_data = &v; - return (sysctl_lookup(SYSCTLFN_CALL(&node))); - } - else - return (EIO); /*XXX*/ -} - -/* - * sysctl helper routine for kern.arandom node. Picks a random number - * for you. - */ -static int -sysctl_kern_arnd(SYSCTLFN_ARGS) -{ - int error; - void *v; - struct sysctlnode node = *rnode; - - if (*oldlenp == 0) - return 0; - /* - * This code used to allow sucking 8192 bytes at a time out - * of the kernel arc4random generator. Evidently there is some - * very old OpenBSD application code that may try to do this. - * - * Note that this node is documented as type "INT" -- 4 or 8 - * bytes, not 8192. - * - * We continue to support this abuse of the "len" pointer here - * but only 256 bytes at a time, as, anecdotally, the actual - * application use here was to generate RC4 keys in userspace. - * - * Support for such large requests will probably be removed - * entirely in the future. - */ - if (*oldlenp > 256) - return E2BIG; - - v = kmem_alloc(*oldlenp, KM_SLEEP); - cprng_fast(v, *oldlenp); - node.sysctl_data = v; - node.sysctl_size = *oldlenp; - error = sysctl_lookup(SYSCTLFN_CALL(&node)); - kmem_free(v, *oldlenp); - return error; -} -/* * sysctl helper routine to do kern.lwp.* work. */ static int Index: src/sys/kern/kern_sysctl.c diff -u src/sys/kern/kern_sysctl.c:1.243 src/sys/kern/kern_sysctl.c:1.244 --- src/sys/kern/kern_sysctl.c:1.243 Sat Apr 27 20:13:16 2013 +++ src/sys/kern/kern_sysctl.c Fri Jan 17 02:12:48 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sysctl.c,v 1.243 2013/04/27 20:13:16 christos Exp $ */ +/* $NetBSD: kern_sysctl.c,v 1.244 2014/01/17 02:12:48 pooka Exp $ */ /*- * Copyright (c) 2003, 2007, 2008 The NetBSD Foundation, Inc. @@ -68,13 +68,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.243 2013/04/27 20:13:16 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.244 2014/01/17 02:12:48 pooka Exp $"); #include "opt_defcorename.h" #include "ksyms.h" -#define SYSCTL_PRIVATE - #include <sys/param.h> #define __COMPAT_SYSCTL #include <sys/sysctl.h> @@ -86,7 +84,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_sysctl. #include <sys/syscallargs.h> #include <sys/kauth.h> #include <sys/ktrace.h> -#include <sys/cprng.h> #define MAXDESCLEN 1024 MALLOC_DEFINE(M_SYSCTLNODE, "sysctlnode", "sysctl node structures"); @@ -167,8 +164,6 @@ long hostid; #endif char defcorename[MAXPATHLEN] = DEFCORENAME; -cprng_strong_t *sysctl_prng; - /* * ******************************************************************** * Section 0: Some simple glue @@ -260,8 +255,7 @@ sysctl_init(void) void sysctl_finalize(void) { - sysctl_prng = cprng_strong_create("sysctl", IPL_NONE, - CPRNG_INIT_ANY|CPRNG_REKEY_ANY); + sysctl_root.sysctl_flags |= CTLFLAG_PERMANENT; } Index: src/sys/kern/subr_cprng.c diff -u src/sys/kern/subr_cprng.c:1.22 src/sys/kern/subr_cprng.c:1.23 --- src/sys/kern/subr_cprng.c:1.22 Sat Jul 27 11:19:09 2013 +++ src/sys/kern/subr_cprng.c Fri Jan 17 02:12:48 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_cprng.c,v 1.22 2013/07/27 11:19:09 skrll Exp $ */ +/* $NetBSD: subr_cprng.c,v 1.23 2014/01/17 02:12:48 pooka Exp $ */ /*- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.22 2013/07/27 11:19:09 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.23 2014/01/17 02:12:48 pooka Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -42,9 +42,11 @@ __KERNEL_RCSID(0, "$NetBSD: subr_cprng.c #include <sys/kernel.h> #include <sys/kmem.h> #include <sys/lwp.h> +#include <sys/once.h> #include <sys/poll.h> /* XXX POLLIN/POLLOUT/&c. */ #include <sys/select.h> #include <sys/systm.h> +#include <sys/sysctl.h> #include <sys/rnd.h> #include <sys/rndsink.h> #if DEBUG @@ -57,6 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: subr_cprng.c #include <machine/cpu_counter.h> #endif +static int sysctl_kern_urnd(SYSCTLFN_PROTO); +static int sysctl_kern_arnd(SYSCTLFN_PROTO); + static void cprng_strong_generate(struct cprng_strong *, void *, size_t); static void cprng_strong_reseed(struct cprng_strong *); static void cprng_strong_reseed_from(struct cprng_strong *, const void *, @@ -70,7 +75,22 @@ static rndsink_callback_t cprng_strong_r void cprng_init(void) { + static struct sysctllog *random_sysctllog; + nist_ctr_initialize(); + + sysctl_createv(&random_sysctllog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "urandom", + SYSCTL_DESCR("Random integer value"), + sysctl_kern_urnd, 0, NULL, 0, + CTL_KERN, KERN_URND, CTL_EOL); + sysctl_createv(&random_sysctllog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "arandom", + SYSCTL_DESCR("n bytes of random data"), + sysctl_kern_arnd, 0, NULL, 0, + CTL_KERN, KERN_ARND, CTL_EOL); } static inline uint32_t @@ -477,3 +497,76 @@ cprng_strong_rndsink_callback(void *cont cprng_strong_reseed_from(cprng, seed, bytes, true); mutex_exit(&cprng->cs_lock); } + +static cprng_strong_t *sysctl_prng; + +static int +makeprng(void) +{ + + /* can't create in cprng_init(), too early */ + sysctl_prng = cprng_strong_create("sysctl", IPL_NONE, + CPRNG_INIT_ANY|CPRNG_REKEY_ANY); + return 0; +} + +/* + * sysctl helper routine for kern.urandom node. Picks a random number + * for you. + */ +static int +sysctl_kern_urnd(SYSCTLFN_ARGS) +{ + static ONCE_DECL(control); + int v, rv; + + RUN_ONCE(&control, makeprng); + rv = cprng_strong(sysctl_prng, &v, sizeof(v), 0); + if (rv == sizeof(v)) { + struct sysctlnode node = *rnode; + node.sysctl_data = &v; + return (sysctl_lookup(SYSCTLFN_CALL(&node))); + } + else + return (EIO); /*XXX*/ +} + +/* + * sysctl helper routine for kern.arandom node. Picks a random number + * for you. + */ +static int +sysctl_kern_arnd(SYSCTLFN_ARGS) +{ + int error; + void *v; + struct sysctlnode node = *rnode; + + if (*oldlenp == 0) + return 0; + /* + * This code used to allow sucking 8192 bytes at a time out + * of the kernel arc4random generator. Evidently there is some + * very old OpenBSD application code that may try to do this. + * + * Note that this node is documented as type "INT" -- 4 or 8 + * bytes, not 8192. + * + * We continue to support this abuse of the "len" pointer here + * but only 256 bytes at a time, as, anecdotally, the actual + * application use here was to generate RC4 keys in userspace. + * + * Support for such large requests will probably be removed + * entirely in the future. + */ + if (*oldlenp > 256) + return E2BIG; + + v = kmem_alloc(*oldlenp, KM_SLEEP); + cprng_fast(v, *oldlenp); + node.sysctl_data = v; + node.sysctl_size = *oldlenp; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + kmem_free(v, *oldlenp); + return error; +} Index: src/sys/sys/sysctl.h diff -u src/sys/sys/sysctl.h:1.209 src/sys/sys/sysctl.h:1.210 --- src/sys/sys/sysctl.h:1.209 Fri Sep 20 12:20:01 2013 +++ src/sys/sys/sysctl.h Fri Jan 17 02:12:48 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sysctl.h,v 1.209 2013/09/20 12:20:01 wiz Exp $ */ +/* $NetBSD: sysctl.h,v 1.210 2014/01/17 02:12:48 pooka Exp $ */ /* * Copyright (c) 1989, 1993 @@ -61,10 +61,6 @@ #include <stdbool.h> #endif -#ifdef SYSCTL_PRIVATE -#include <sys/cprng.h> -#endif - /* * Definitions for sysctl call. The sysctl call uses a hierarchical name * for objects that can be examined or modified. The name is expressed as @@ -1251,10 +1247,6 @@ MALLOC_DECLARE(M_SYSCTLDATA); extern const u_int sysctl_lwpflagmap[]; -#ifdef SYSCTL_PRIVATE -extern cprng_strong_t *sysctl_prng; -#endif - #else /* !_KERNEL */ #include <sys/cdefs.h>