Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_jail.c
Show First 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | static struct bool_flags pr_flag_allow[NBBY * NBPW] = { | ||||
{"allow.chflags", "allow.nochflags", PR_ALLOW_CHFLAGS}, | {"allow.chflags", "allow.nochflags", PR_ALLOW_CHFLAGS}, | ||||
{"allow.mount", "allow.nomount", PR_ALLOW_MOUNT}, | {"allow.mount", "allow.nomount", PR_ALLOW_MOUNT}, | ||||
{"allow.quotas", "allow.noquotas", PR_ALLOW_QUOTAS}, | {"allow.quotas", "allow.noquotas", PR_ALLOW_QUOTAS}, | ||||
{"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", | |||||
PR_ALLOW_UNPRIV_DEBUG}, | |||||
}; | }; | ||||
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 | PR_ALLOW_RESERVED_PORTS) | #define JAIL_DEFAULT_ALLOW (PR_ALLOW_SET_HOSTNAME | \ | ||||
PR_ALLOW_RESERVED_PORTS | \ | |||||
PR_ALLOW_UNPRIV_DEBUG) | |||||
#define JAIL_DEFAULT_ENFORCE_STATFS 2 | #define JAIL_DEFAULT_ENFORCE_STATFS 2 | ||||
#define JAIL_DEFAULT_DEVFS_RSNUM 0 | #define JAIL_DEFAULT_DEVFS_RSNUM 0 | ||||
static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW; | static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW; | ||||
static int jail_default_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS; | static int jail_default_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS; | ||||
static int jail_default_devfs_rsnum = JAIL_DEFAULT_DEVFS_RSNUM; | static int jail_default_devfs_rsnum = JAIL_DEFAULT_DEVFS_RSNUM; | ||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
static unsigned jail_max_af_ips = 255; | static unsigned jail_max_af_ips = 255; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 284 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
int ip4s, redo_ip4; | int ip4s, redo_ip4; | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
int ip6s, redo_ip6; | int ip6s, redo_ip6; | ||||
#endif | #endif | ||||
uint64_t pr_allow, ch_allow, pr_flags, ch_flags; | uint64_t pr_allow, ch_allow, pr_flags, ch_flags; | ||||
uint64_t pr_allow_diff; | |||||
unsigned tallow; | unsigned tallow; | ||||
char numbuf[12]; | char numbuf[12]; | ||||
error = priv_check(td, PRIV_JAIL_SET); | error = priv_check(td, PRIV_JAIL_SET); | ||||
if (!error && (flags & JAIL_ATTACH)) | if (!error && (flags & JAIL_ATTACH)) | ||||
error = priv_check(td, PRIV_JAIL_ATTACH); | error = priv_check(td, PRIV_JAIL_ATTACH); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 1,016 Lines • ▼ Show 20 Lines | if (namelc != NULL) { | ||||
FOREACH_PRISON_DESCENDANT(pr, tpr, descend) { | FOREACH_PRISON_DESCENDANT(pr, tpr, descend) { | ||||
if (strlen(tpr->pr_name) + (namelen - onamelen) >= | if (strlen(tpr->pr_name) + (namelen - onamelen) >= | ||||
sizeof(pr->pr_name)) { | sizeof(pr->pr_name)) { | ||||
error = ENAMETOOLONG; | error = ENAMETOOLONG; | ||||
goto done_deref_locked; | goto done_deref_locked; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (pr_allow & ~ppr->pr_allow) { | pr_allow_diff = pr_allow & ~ppr->pr_allow; | ||||
if (pr_allow_diff & ~PR_ALLOW_DIFFERENCES) { | |||||
error = EPERM; | error = EPERM; | ||||
goto done_deref_locked; | goto done_deref_locked; | ||||
} | } | ||||
/* | /* | ||||
* Let modules check their parameters. This requires unlocking and | * Let modules check their parameters. This requires unlocking and | ||||
* then re-locking the prison, but this is still a valid state as long | * then re-locking the prison, but this is still a valid state as long | ||||
* as allprison_lock remains xlocked. | * as allprison_lock remains xlocked. | ||||
▲ Show 20 Lines • Show All 2,236 Lines • ▼ Show 20 Lines | |||||
SYSCTL_JAIL_PARAM(_allow, socket_af, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, socket_af, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail may create sockets other than just UNIX/IPv4/IPv6/route"); | "B", "Jail may create sockets other than just UNIX/IPv4/IPv6/route"); | ||||
SYSCTL_JAIL_PARAM(_allow, mlock, CTLTYPE_INT | CTLFLAG_RW, | SYSCTL_JAIL_PARAM(_allow, mlock, CTLTYPE_INT | CTLFLAG_RW, | ||||
"B", "Jail may lock (unlock) physical pages in memory"); | "B", "Jail may lock (unlock) physical pages in memory"); | ||||
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, | |||||
"B", "Unprivileged processes may use process debugging facilities"); | |||||
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 All 35 Lines | if (strcmp(bf->name, allow_name) == 0) { | ||||
goto no_add; | goto no_add; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Find a free bit in prison0's pr_allow, failing if there are none | * Find a free bit in prison0's pr_allow, failing if there are none | ||||
* (which shouldn't happen as long as we keep track of how many | * (which shouldn't happen as long as we keep track of how many | ||||
* potential dynamic flags exist). | * potential dynamic flags exist). | ||||
* | |||||
* Due to per-jail unprivileged process debugging support | |||||
* using pr_allow, also verify against PR_ALLOW_ALL_STATIC. | |||||
* prison0 may have unprivileged process debugging unset. | |||||
*/ | */ | ||||
for (allow_flag = 1;; allow_flag <<= 1) { | for (allow_flag = 1;; allow_flag <<= 1) { | ||||
if (allow_flag == 0) | if (allow_flag == 0) | ||||
goto no_add; | goto no_add; | ||||
if (allow_flag & PR_ALLOW_ALL_STATIC) | |||||
continue; | |||||
if ((prison0.pr_allow & allow_flag) == 0) | if ((prison0.pr_allow & allow_flag) == 0) | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Note the parameter in the next open slot in pr_flag_allow. | * Note the parameter in the next open slot in pr_flag_allow. | ||||
* Set the flag last so code that checks pr_flag_allow can do so | * Set the flag last so code that checks pr_flag_allow can do so | ||||
* without locking. | * without locking. | ||||
▲ Show 20 Lines • Show All 375 Lines • Show Last 20 Lines |