Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Jul 2011 23:05:24 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r224159 - in head/sys: kern sys
Message-ID:  <201107172305.p6HN5OP2094848@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Sun Jul 17 23:05:24 2011
New Revision: 224159
URL: http://svn.freebsd.org/changeset/base/224159

Log:
  Define two new sysctl node flags: CTLFLAG_CAPRD and CTLFLAG_CAPRW, which
  may be jointly referenced via the mask CTLFLAG_CAPRW.  Sysctls with these
  flags are available in Capsicum's capability mode; other sysctl nodes are
  not.
  
  Flag several useful sysctls as available in capability mode, such as memory
  layout sysctls required by the run-time linker and malloc(3).  Also expose
  access to randomness and available kernel features.
  
  A few sysctls are enabled to support name->MIB conversion; these may leak
  information to capability mode by virtue of providing resolution on names
  not flagged for access in capability mode.  This is, generally, not a huge
  problem, but might be something to resolve in the future.  Flag these cases
  with XXX comments.
  
  Submitted by:	jonathan
  Sponsored by:	Google, Inc.

Modified:
  head/sys/kern/kern_exec.c
  head/sys/kern/kern_mib.c
  head/sys/kern/kern_sysctl.c
  head/sys/kern/posix4_mib.c
  head/sys/kern/subr_smp.c
  head/sys/sys/sysctl.h

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/kern/kern_exec.c	Sun Jul 17 23:05:24 2011	(r224159)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/capability.h>
 #include <sys/systm.h>
+#include <sys/capability.h>
 #include <sys/eventhandler.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -113,8 +114,8 @@ SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_s
     NULL, 0, sysctl_kern_ps_strings, "LU", "");
 
 /* XXX This should be vm_size_t. */
-SYSCTL_PROC(_kern, KERN_USRSTACK, usrstack, CTLTYPE_ULONG|CTLFLAG_RD,
-    NULL, 0, sysctl_kern_usrstack, "LU", "");
+SYSCTL_PROC(_kern, KERN_USRSTACK, usrstack, CTLTYPE_ULONG|CTLFLAG_RD|
+    CTLFLAG_CAPRD, NULL, 0, sysctl_kern_usrstack, "LU", "");
 
 SYSCTL_PROC(_kern, OID_AUTO, stackprot, CTLTYPE_INT|CTLFLAG_RD,
     NULL, 0, sysctl_kern_stackprot, "I", "");

Modified: head/sys/kern/kern_mib.c
==============================================================================
--- head/sys/kern/kern_mib.c	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/kern/kern_mib.c	Sun Jul 17 23:05:24 2011	(r224159)
@@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$");
 
 SYSCTL_NODE(, 0,	  sysctl, CTLFLAG_RW, 0,
 	"Sysctl internal magic");
-SYSCTL_NODE(, CTL_KERN,	  kern,   CTLFLAG_RW, 0,
+SYSCTL_NODE(, CTL_KERN,	  kern,   CTLFLAG_RW|CTLFLAG_CAPRD, 0,
 	"High kernel, proc, limits &c");
 SYSCTL_NODE(, CTL_VM,	  vm,     CTLFLAG_RW, 0,
 	"Virtual memory");
@@ -90,23 +90,23 @@ SYSCTL_NODE(, OID_AUTO, regression, CTLF
 SYSCTL_STRING(_kern, OID_AUTO, ident, CTLFLAG_RD|CTLFLAG_MPSAFE,
     kern_ident, 0, "Kernel identifier");
 
-SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD|CTLFLAG_MPSAFE,
-    osrelease, 0, "Operating system release");
+SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD|CTLFLAG_MPSAFE|
+    CTLFLAG_CAPRD, osrelease, 0, "Operating system release");
 
-SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, BSD, "Operating system revision");
 
 SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD|CTLFLAG_MPSAFE,
     version, 0, "Kernel version");
 
-SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD|CTLFLAG_MPSAFE,
-    ostype, 0, "Operating system type");
+SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD|CTLFLAG_MPSAFE|
+    CTLFLAG_CAPRD, ostype, 0, "Operating system type");
 
 /*
  * NOTICE: The *userland* release date is available in
  * /usr/include/osreldate.h
  */
-SYSCTL_INT(_kern, KERN_OSRELDATE, osreldate, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_OSRELDATE, osreldate, CTLFLAG_RD|CTLFLAG_CAPRD,
     &osreldate, 0, "Kernel release date");
 
 SYSCTL_INT(_kern, KERN_MAXPROC, maxproc, CTLFLAG_RDTUN,
@@ -118,24 +118,24 @@ SYSCTL_INT(_kern, KERN_MAXPROCPERUID, ma
 SYSCTL_INT(_kern, OID_AUTO, maxusers, CTLFLAG_RDTUN,
     &maxusers, 0, "Hint for kernel tuning");
 
-SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, ARG_MAX, "Maximum bytes of argument to execve(2)");
 
-SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, _POSIX_VERSION, "Version of POSIX attempting to comply to");
 
-SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RDTUN,
+SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RDTUN|CTLFLAG_CAPRD,
     &ngroups_max, 0,
     "Maximum number of supplemental groups a user can belong to");
 
-SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, 1, "Whether job control is available");
 
 #ifdef _POSIX_SAVED_IDS
-SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, 1, "Whether saved set-group/user ID is available");
 #else
-SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD,
+SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, 0, "Whether saved set-group/user ID is available");
 #endif
 
@@ -144,13 +144,13 @@ char kernelname[MAXPATHLEN] = "/kernel";
 SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW,
     kernelname, sizeof kernelname, "Name of kernel file booted");
 
-SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD,
+SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD|CTLFLAG_CAPRD,
     &mp_ncpus, 0, "Number of active CPUs");
 
-SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD,
+SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, BYTE_ORDER, "System byte order");
 
-SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD,
+SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD|CTLFLAG_CAPRD,
     0, PAGE_SIZE, "System memory page size");
 
 static int
@@ -167,7 +167,7 @@ sysctl_kern_arnd(SYSCTL_HANDLER_ARGS)
 }
 
 SYSCTL_PROC(_kern, KERN_ARND, arandom,
-    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, NULL, 0,
     sysctl_kern_arnd, "", "arc4rand");
 
 static int
@@ -448,6 +448,8 @@ FEATURE(compat_freebsd7, "Compatible wit
  * This is really cheating.  These actually live in the libc, something
  * which I'm not quite sure is a good idea anyway, but in order for
  * getnext and friends to actually work, we define dummies here.
+ *
+ * XXXRW: These probably should be CTLFLAG_CAPRD.
  */
 SYSCTL_STRING(_user, USER_CS_PATH, cs_path, CTLFLAG_RD,
     "", 0, "PATH that finds all the standard utilities");

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/kern/kern_sysctl.c	Sun Jul 17 23:05:24 2011	(r224159)
@@ -38,12 +38,14 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_capsicum.h"
 #include "opt_compat.h"
 #include "opt_ktrace.h"
 
 #include <sys/param.h>
 #include <sys/fail.h>
 #include <sys/systm.h>
+#include <sys/capability.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
@@ -725,7 +727,12 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
 	return (error);
 }
 
-static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD, sysctl_sysctl_name, "");
+/*
+ * XXXRW/JA: Shouldn't return name data for nodes that we don't permit in
+ * capability mode.
+ */
+static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD | CTLFLAG_CAPRD,
+    sysctl_sysctl_name, "");
 
 static int
 sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, 
@@ -806,7 +813,12 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
 	return (error);
 }
 
-static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, "");
+/*
+ * XXXRW/JA: Shouldn't return next data for nodes that we don't permit in
+ * capability mode.
+ */
+static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD | CTLFLAG_CAPRD,
+    sysctl_sysctl_next, "");
 
 static int
 name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
@@ -902,9 +914,13 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_AR
 	return (error);
 }
 
+/*
+ * XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in
+ * capability mode.
+ */
 SYSCTL_PROC(_sysctl, 3, name2oid,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
-    0, 0, sysctl_sysctl_name2oid, "I", "");
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE
+    | CTLFLAG_CAPRW, 0, 0, sysctl_sysctl_name2oid, "I", "");
 
 static int
 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
@@ -931,7 +947,7 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS
 }
 
 
-static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE,
+static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD,
     sysctl_sysctl_oidfmt, "");
 
 static int
@@ -955,7 +971,8 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_AR
 	return (error);
 }
 
-static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD, sysctl_sysctl_oiddescr, "");
+static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD|CTLFLAG_CAPRD,
+    sysctl_sysctl_oiddescr, "");
 
 /*
  * Default "handler" functions.
@@ -1429,6 +1446,19 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
 
 	KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
 
+#ifdef CAPABILITY_MODE
+	/*
+	 * If the process is in capability mode, then don't permit reading or
+	 * writing unless specifically granted for the node.
+	 */
+	if (IN_CAPABILITY_MODE(req->td)) {
+		if (req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD))
+			return (EPERM);
+		if (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))
+			return (EPERM);
+	}
+#endif
+
 	/* Is this sysctl sensitive to securelevels? */
 	if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) {
 		lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE;

Modified: head/sys/kern/posix4_mib.c
==============================================================================
--- head/sys/kern/posix4_mib.c	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/kern/posix4_mib.c	Sun Jul 17 23:05:24 2011	(r224159)
@@ -57,7 +57,8 @@ static int p31b_sysctl_proc(SYSCTL_HANDL
 SYSCTL_DECL(_p1003_1b);
 
 #define P1B_SYSCTL(num, name)  \
-	SYSCTL_INT(_p1003_1b, num, name, CTLFLAG_RD, facility + num - 1, 0, "");
+	SYSCTL_INT(_p1003_1b, num, name, CTLFLAG_RD | CTLFLAG_CAPRD, \
+	facility + num - 1, 0, "");
 #define P1B_SYSCTL_RW(num, name)  \
 	SYSCTL_PROC(_p1003_1b, num, name, CTLTYPE_INT | CTLFLAG_RW, NULL, num, \
 	    p31b_sysctl_proc, "I", "");
@@ -67,7 +68,7 @@ SYSCTL_DECL(_p1003_1b);
 SYSCTL_DECL(_kern_p1003_1b);
 
 #define P1B_SYSCTL(num, name)  \
-	SYSCTL_INT(_kern_p1003_1b, OID_AUTO, name, CTLFLAG_RD, \
+	SYSCTL_INT(_kern_p1003_1b, OID_AUTO, name, CTLFLAG_RD | CTLFLAG_CAPRD, \
 	    facility + num - 1, 0, "");
 #define P1B_SYSCTL_RW(num, name)  \
 	SYSCTL_PROC(_p1003_1b, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW, NULL, \

Modified: head/sys/kern/subr_smp.c
==============================================================================
--- head/sys/kern/subr_smp.c	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/kern/subr_smp.c	Sun Jul 17 23:05:24 2011	(r224159)
@@ -70,25 +70,25 @@ int mp_maxcpus = MAXCPU;
 volatile int smp_started;
 u_int mp_maxid;
 
-SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD, NULL, "Kernel SMP");
+SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD|CTLFLAG_CAPRD, NULL, "Kernel SMP");
 
-SYSCTL_UINT(_kern_smp, OID_AUTO, maxid, CTLFLAG_RD, &mp_maxid, 0,
+SYSCTL_INT(_kern_smp, OID_AUTO, maxid, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxid, 0,
     "Max CPU ID.");
 
-SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD, &mp_maxcpus, 0,
-    "Max number of CPUs that the system was compiled for.");
+SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxcpus,
+    0, "Max number of CPUs that the system was compiled for.");
 
 int smp_active = 0;	/* are the APs allowed to run? */
 SYSCTL_INT(_kern_smp, OID_AUTO, active, CTLFLAG_RW, &smp_active, 0,
     "Number of Auxillary Processors (APs) that were successfully started");
 
 int smp_disabled = 0;	/* has smp been disabled? */
-SYSCTL_INT(_kern_smp, OID_AUTO, disabled, CTLFLAG_RDTUN, &smp_disabled, 0,
-    "SMP has been disabled from the loader");
+SYSCTL_INT(_kern_smp, OID_AUTO, disabled, CTLFLAG_RDTUN|CTLFLAG_CAPRD,
+    &smp_disabled, 0, "SMP has been disabled from the loader");
 TUNABLE_INT("kern.smp.disabled", &smp_disabled);
 
 int smp_cpus = 1;	/* how many cpu's running */
-SYSCTL_INT(_kern_smp, OID_AUTO, cpus, CTLFLAG_RD, &smp_cpus, 0,
+SYSCTL_INT(_kern_smp, OID_AUTO, cpus, CTLFLAG_RD|CTLFLAG_CAPRD, &smp_cpus, 0,
     "Number of CPUs online");
 
 int smp_topology = 0;	/* Which topology we're using. */

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h	Sun Jul 17 21:57:10 2011	(r224158)
+++ head/sys/sys/sysctl.h	Sun Jul 17 23:05:24 2011	(r224159)
@@ -88,6 +88,9 @@ struct ctlname {
 #define CTLFLAG_VNET	0x00020000	/* Prisons with vnet can fiddle */
 #define CTLFLAG_RDTUN	(CTLFLAG_RD|CTLFLAG_TUN)
 #define	CTLFLAG_DYING	0x00010000	/* oid is being removed */
+#define CTLFLAG_CAPRD	0x00008000	/* Can be read in capability mode */
+#define CTLFLAG_CAPWR	0x00004000	/* Can be written in capability mode */
+#define CTLFLAG_CAPRW	(CTLFLAG_CAPRD|CTLFLAG_CAPWR)
 
 /*
  * Secure level.   Note that CTLFLAG_SECURE == CTLFLAG_SECURE1.  
@@ -407,7 +410,8 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a
  * kernel features.
  */
 #define	FEATURE(name, desc)						\
-	SYSCTL_INT(_kern_features, OID_AUTO, name, CTLFLAG_RD, 0, 1, desc)
+	SYSCTL_INT(_kern_features, OID_AUTO, name, CTLFLAG_RD | CTLFLAG_CAPRD, \
+	    0, 1, desc)
 
 #endif /* _KERNEL */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107172305.p6HN5OP2094848>