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.
This commit is contained in:
parent
8c65d0122a
commit
7c21db8ed3
@ -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_strings, CTLTYPE_ULONG|CTLFLAG_RD,
|
||||
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", "");
|
||||
|
@ -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, CTLFLAG_RW, 0,
|
||||
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, maxprocperuid, CTLFLAG_RW,
|
||||
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"; /* XXX bloat */
|
||||
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 with FreeBSD 7");
|
||||
* 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");
|
||||
|
@ -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_ARGS)
|
||||
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_ARGS)
|
||||
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;
|
||||
|
@ -57,7 +57,8 @@ static int p31b_sysctl_proc(SYSCTL_HANDLER_ARGS);
|
||||
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, \
|
||||
|
@ -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. */
|
||||
|
@ -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; unsigned long long *b; );
|
||||
* 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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user