Changeset View
Standalone View
sys/kern/kern_jail.c
Show First 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | static struct bool_flags pr_flag_allow[NBBY * NBPW] = { | ||||
{"allow.socket_af", "allow.nosocket_af", PR_ALLOW_SOCKET_AF}, | {"allow.socket_af", "allow.nosocket_af", PR_ALLOW_SOCKET_AF}, | ||||
{"allow.mlock", "allow.nomlock", PR_ALLOW_MLOCK}, | {"allow.mlock", "allow.nomlock", PR_ALLOW_MLOCK}, | ||||
{"allow.reserved_ports", "allow.noreserved_ports", | {"allow.reserved_ports", "allow.noreserved_ports", | ||||
PR_ALLOW_RESERVED_PORTS}, | PR_ALLOW_RESERVED_PORTS}, | ||||
{"allow.read_msgbuf", "allow.noread_msgbuf", PR_ALLOW_READ_MSGBUF}, | {"allow.read_msgbuf", "allow.noread_msgbuf", PR_ALLOW_READ_MSGBUF}, | ||||
{"allow.unprivileged_proc_debug", "allow.nounprivileged_proc_debug", | {"allow.unprivileged_proc_debug", "allow.nounprivileged_proc_debug", | ||||
PR_ALLOW_UNPRIV_DEBUG}, | PR_ALLOW_UNPRIV_DEBUG}, | ||||
{"allow.suser", "allow.nosuser", PR_ALLOW_SUSER}, | {"allow.suser", "allow.nosuser", PR_ALLOW_SUSER}, | ||||
{"allow.nfsd", "allow.nonfsd", PR_ALLOW_NFSD}, | |||||
}; | }; | ||||
static unsigned pr_allow_all = PR_ALLOW_ALL_STATIC; | static unsigned pr_allow_all = PR_ALLOW_ALL_STATIC; | ||||
const size_t pr_flag_allow_size = sizeof(pr_flag_allow); | const size_t pr_flag_allow_size = sizeof(pr_flag_allow); | ||||
#define JAIL_DEFAULT_ALLOW (PR_ALLOW_SET_HOSTNAME | \ | #define JAIL_DEFAULT_ALLOW (PR_ALLOW_SET_HOSTNAME | \ | ||||
PR_ALLOW_RESERVED_PORTS | \ | PR_ALLOW_RESERVED_PORTS | \ | ||||
PR_ALLOW_UNPRIV_DEBUG | \ | PR_ALLOW_UNPRIV_DEBUG | \ | ||||
PR_ALLOW_SUSER) | PR_ALLOW_SUSER) | ||||
▲ Show 20 Lines • Show All 3,230 Lines • ▼ Show 20 Lines | |||||
prison_check(struct ucred *cred1, struct ucred *cred2) | prison_check(struct ucred *cred1, struct ucred *cred2) | ||||
{ | { | ||||
return ((cred1->cr_prison == cred2->cr_prison || | return ((cred1->cr_prison == cred2->cr_prison || | ||||
prison_ischild(cred1->cr_prison, cred2->cr_prison)) ? 0 : ESRCH); | prison_ischild(cred1->cr_prison, cred2->cr_prison)) ? 0 : ESRCH); | ||||
} | } | ||||
/* | /* | ||||
* For mountd/nfsd to run within a prison, it must be: | |||||
* - A vnet prison. | |||||
* - PR_ALLOW_NFSD must be set on it. | |||||
* - The root directory (pr_root) of the prison must be | |||||
* a file system mount point, so the mountd can hang | |||||
* export information on it. | |||||
*/ | |||||
bool | |||||
prison_check_nfsd(struct ucred *cred) | |||||
{ | |||||
if (!jailed(cred)) | |||||
return (false); | |||||
if (jailed_without_vnet(cred)) | |||||
return (false); | |||||
if (!prison_allow(cred, PR_ALLOW_NFSD)) | |||||
return (false); | |||||
if ((cred->cr_prison->pr_root->v_vflag & VV_ROOT) == 0) | |||||
return (false); | |||||
return (true); | |||||
} | |||||
rmacklem: Btw. If jamie is ok with only enabling "allow.nfsd" when
VIMAGE is defined, we could just drop… | |||||
Not Done Inline Actions
I'm fine with that, or only when VNET_NFSD is defined.
No - they are allowed to be, but it's controlled on a per-prison basis.
Allowing non-jails to pass would then mean that prison0 isn't constrained to the pr_root test. It doesn't really matter if it's never called in the prison0 case, but I like it there for neatness/safety. jamie: > Btw. If jamie is ok with only enabling "allow.nfsd" when
> VIMAGE is defined, we could just… | |||||
/* | |||||
* Return 1 if p2 is a child of p1, otherwise 0. | * Return 1 if p2 is a child of p1, otherwise 0. | ||||
*/ | */ | ||||
int | int | ||||
prison_ischild(struct prison *pr1, struct prison *pr2) | prison_ischild(struct prison *pr1, struct prison *pr2) | ||||
{ | { | ||||
for (pr2 = pr2->pr_parent; pr2 != NULL; pr2 = pr2->pr_parent) | for (pr2 = pr2->pr_parent; pr2 != NULL; pr2 = pr2->pr_parent) | ||||
if (pr1 == pr2) | if (pr1 == pr2) | ||||
▲ Show 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | |||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
/* | /* | ||||
* Privileges specific to prisons with a virtual network stack. | * Privileges specific to prisons with a virtual network stack. | ||||
* There might be a duplicate entry here in case the privilege | * There might be a duplicate entry here in case the privilege | ||||
* is only granted conditionally in the legacy jail case. | * is only granted conditionally in the legacy jail case. | ||||
*/ | */ | ||||
switch (priv) { | switch (priv) { | ||||
#ifdef notyet | |||||
/* | /* | ||||
* NFS-specific privileges. | * NFS-specific privileges. | ||||
*/ | */ | ||||
case PRIV_NFS_DAEMON: | case PRIV_NFS_DAEMON: | ||||
case PRIV_VFS_GETFH: | |||||
#ifdef VNET_NFSD | |||||
if (!prison_allow(cred, PR_ALLOW_NFSD) || | |||||
(cred->cr_prison->pr_root->v_vflag & VV_ROOT) == 0) | |||||
#else | |||||
printf("running nfsd in a prison requires a kernel " | |||||
"built with ''options VNET_NFSD''\n"); | |||||
#endif | |||||
return (EPERM); | |||||
#ifdef notyet | |||||
case PRIV_NFS_LOCKD: | case PRIV_NFS_LOCKD: | ||||
#endif | #endif | ||||
/* | /* | ||||
* Network stack privileges. | * Network stack privileges. | ||||
*/ | */ | ||||
case PRIV_NET_BRIDGE: | case PRIV_NET_BRIDGE: | ||||
case PRIV_NET_GRE: | case PRIV_NET_GRE: | ||||
case PRIV_NET_BPF: | case PRIV_NET_BPF: | ||||
▲ Show 20 Lines • Show All 734 Lines • ▼ Show 20 Lines | |||||
SYSCTL_JAIL_PARAM(_allow, reserved_ports, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, reserved_ports, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail may bind sockets to reserved ports"); | "B", "Jail may bind sockets to reserved ports"); | ||||
SYSCTL_JAIL_PARAM(_allow, read_msgbuf, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, read_msgbuf, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail may read the kernel message buffer"); | "B", "Jail may read the kernel message buffer"); | ||||
SYSCTL_JAIL_PARAM(_allow, unprivileged_proc_debug, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, unprivileged_proc_debug, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Unprivileged processes may use process debugging facilities"); | "B", "Unprivileged processes may use process debugging facilities"); | ||||
SYSCTL_JAIL_PARAM(_allow, suser, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, suser, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Processes in jail with uid 0 have privilege"); | "B", "Processes in jail with uid 0 have privilege"); | ||||
SYSCTL_JAIL_PARAM(_allow, nfsd, CTLTYPE_INT | CTLFLAG_RW, | |||||
"B", "Mountd/nfsd may run in the jail"); | |||||
SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags"); | SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags"); | ||||
SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail may mount/unmount jail-friendly file systems in general"); | "B", "Jail may mount/unmount jail-friendly file systems in general"); | ||||
/* | /* | ||||
* Add a dynamic parameter allow.<name>, or allow.<prefix>.<name>. Return | * Add a dynamic parameter allow.<name>, or allow.<prefix>.<name>. Return | ||||
* its associated bit in the pr_allow bitmask, or zero if the parameter was | * its associated bit in the pr_allow bitmask, or zero if the parameter was | ||||
▲ Show 20 Lines • Show All 450 Lines • Show Last 20 Lines |
Btw. If jamie is ok with only enabling "allow.nfsd" when
VIMAGE is defined, we could just drop the first two
tests.
NFS is only going to be called when it is in a jail and
if PR_ALLOW_NFSD is set, VIMAGE must have been defined
so all prisons are vnet prisons, I think?
It is the test for PR_ALLOW_NFSD and pr_root being a file
system mount point that matter to the NFS code.
(Or I can just put the test in the NFS code and throw this
function away. I just thought it was cleaner to have a function
here in kern_jail.c to do the tests.)