summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_jail.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_jail.c')
-rw-r--r--sys/kern/kern_jail.c159
1 files changed, 81 insertions, 78 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 0ea7276..a0e4c61 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -932,6 +932,46 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
}
#endif
+ error = vfs_getopt(opts, "osrelease", (void **)&osrelstr, &len);
+ if (error == ENOENT)
+ osrelstr = NULL;
+ else if (error != 0)
+ goto done_free;
+ else {
+ if (flags & JAIL_UPDATE) {
+ error = EINVAL;
+ vfs_opterror(opts,
+ "osrelease cannot be changed after creation");
+ goto done_errmsg;
+ }
+ if (len == 0 || len >= OSRELEASELEN) {
+ error = EINVAL;
+ vfs_opterror(opts,
+ "osrelease string must be 1-%d bytes long",
+ OSRELEASELEN - 1);
+ goto done_errmsg;
+ }
+ }
+
+ error = vfs_copyopt(opts, "osreldate", &osreldt, sizeof(osreldt));
+ if (error == ENOENT)
+ osreldt = 0;
+ else if (error != 0)
+ goto done_free;
+ else {
+ if (flags & JAIL_UPDATE) {
+ error = EINVAL;
+ vfs_opterror(opts,
+ "osreldate cannot be changed after creation");
+ goto done_errmsg;
+ }
+ if (osreldt == 0) {
+ error = EINVAL;
+ vfs_opterror(opts, "osreldate cannot be 0");
+ goto done_errmsg;
+ }
+ }
+
fullpath_disabled = 0;
root = NULL;
error = vfs_getopt(opts, "path", (void **)&path, &len);
@@ -982,51 +1022,12 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
if (len + (path[0] == '/' && strcmp(mypr->pr_path, "/")
? strlen(mypr->pr_path) : 0) > MAXPATHLEN) {
error = ENAMETOOLONG;
+ vrele(root);
goto done_free;
}
}
}
- error = vfs_getopt(opts, "osrelease", (void **)&osrelstr, &len);
- if (error == ENOENT)
- osrelstr = NULL;
- else if (error != 0)
- goto done_free;
- else {
- if (flags & JAIL_UPDATE) {
- error = EINVAL;
- vfs_opterror(opts,
- "osrelease cannot be changed after creation");
- goto done_errmsg;
- }
- if (len == 0 || len >= OSRELEASELEN) {
- error = EINVAL;
- vfs_opterror(opts,
- "osrelease string must be 1-%d bytes long",
- OSRELEASELEN - 1);
- goto done_errmsg;
- }
- }
-
- error = vfs_copyopt(opts, "osreldate", &osreldt, sizeof(osreldt));
- if (error == ENOENT)
- osreldt = 0;
- else if (error != 0)
- goto done_free;
- else {
- if (flags & JAIL_UPDATE) {
- error = EINVAL;
- vfs_opterror(opts,
- "osreldate cannot be changed after creation");
- goto done_errmsg;
- }
- if (osreldt == 0) {
- error = EINVAL;
- vfs_opterror(opts, "osreldate cannot be 0");
- goto done_errmsg;
- }
- }
-
/*
* Find the specified jail, or at least its parent.
* This abuses the file error codes ENOENT and EEXIST.
@@ -1943,19 +1944,17 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
vrele(root);
done_errmsg:
if (error) {
- vfs_getopt(opts, "errmsg", (void **)&errmsg, &errmsg_len);
- if (errmsg_len > 0) {
+ if (vfs_getopt(opts, "errmsg", (void **)&errmsg,
+ &errmsg_len) == 0 && errmsg_len > 0) {
errmsg_pos = 2 * vfs_getopt_pos(opts, "errmsg") + 1;
- if (errmsg_pos > 0) {
- if (optuio->uio_segflg == UIO_SYSSPACE)
- bcopy(errmsg,
- optuio->uio_iov[errmsg_pos].iov_base,
- errmsg_len);
- else
- copyout(errmsg,
- optuio->uio_iov[errmsg_pos].iov_base,
- errmsg_len);
- }
+ if (optuio->uio_segflg == UIO_SYSSPACE)
+ bcopy(errmsg,
+ optuio->uio_iov[errmsg_pos].iov_base,
+ errmsg_len);
+ else
+ copyout(errmsg,
+ optuio->uio_iov[errmsg_pos].iov_base,
+ errmsg_len);
}
}
done_free:
@@ -2400,7 +2399,14 @@ sys_jail_attach(struct thread *td, struct jail_attach_args *uap)
if (error)
return (error);
- sx_slock(&allprison_lock);
+ /*
+ * Start with exclusive hold on allprison_lock to ensure that a possible
+ * PR_METHOD_REMOVE call isn't concurrent with jail_set or jail_remove.
+ * But then immediately downgrade it since we don't need to stop
+ * readers.
+ */
+ sx_xlock(&allprison_lock);
+ sx_downgrade(&allprison_lock);
pr = prison_find_child(td->td_ucred->cr_prison, uap->jid);
if (pr == NULL) {
sx_sunlock(&allprison_lock);
@@ -2618,9 +2624,11 @@ prison_complete(void *context, int pending)
{
struct prison *pr = context;
+ sx_xlock(&allprison_lock);
mtx_lock(&pr->pr_mtx);
prison_deref(pr, pr->pr_uref
- ? PD_DEREF | PD_DEUREF | PD_LOCKED : PD_LOCKED);
+ ? PD_DEREF | PD_DEUREF | PD_LOCKED | PD_LIST_XLOCKED
+ : PD_LOCKED | PD_LIST_XLOCKED);
}
/*
@@ -2664,13 +2672,8 @@ prison_deref(struct prison *pr, int flags)
*/
if (lasturef) {
if (!(flags & (PD_LIST_SLOCKED | PD_LIST_XLOCKED))) {
- if (ref > 1) {
- sx_slock(&allprison_lock);
- flags |= PD_LIST_SLOCKED;
- } else {
- sx_xlock(&allprison_lock);
- flags |= PD_LIST_XLOCKED;
- }
+ sx_xlock(&allprison_lock);
+ flags |= PD_LIST_XLOCKED;
}
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
mtx_lock(&pr->pr_mtx);
@@ -4306,7 +4309,7 @@ SYSCTL_PROC(_security_jail, OID_AUTO, vnet,
#if defined(INET) || defined(INET6)
SYSCTL_UINT(_security_jail, OID_AUTO, jail_max_af_ips, CTLFLAG_RW,
&jail_max_af_ips, 0,
- "Number of IP addresses a jail may have at most per address family");
+ "Number of IP addresses a jail may have at most per address family (deprecated)");
#endif
/*
@@ -4346,59 +4349,59 @@ sysctl_jail_default_allow(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_security_jail, OID_AUTO, set_hostname_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_SET_HOSTNAME, sysctl_jail_default_allow, "I",
- "Processes in jail can set their hostnames");
+ "Processes in jail can set their hostnames (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, socket_unixiproute_only,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
(void *)1, PR_ALLOW_SOCKET_AF, sysctl_jail_default_allow, "I",
- "Processes in jail are limited to creating UNIX/IP/route sockets only");
+ "Processes in jail are limited to creating UNIX/IP/route sockets only (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, sysvipc_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_SYSVIPC, sysctl_jail_default_allow, "I",
- "Processes in jail can use System V IPC primitives");
+ "Processes in jail can use System V IPC primitives (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, allow_raw_sockets,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_RAW_SOCKETS, sysctl_jail_default_allow, "I",
- "Prison root can create raw sockets");
+ "Prison root can create raw sockets (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, chflags_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_CHFLAGS, sysctl_jail_default_allow, "I",
- "Processes in jail can alter system file flags");
+ "Processes in jail can alter system file flags (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT, sysctl_jail_default_allow, "I",
- "Processes in jail can mount/unmount jail-friendly file systems");
+ "Processes in jail can mount/unmount jail-friendly file systems (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_devfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_DEVFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the devfs file system");
+ "Processes in jail can mount the devfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_fdescfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_FDESCFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the fdescfs file system");
+ "Processes in jail can mount the fdescfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_nullfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_NULLFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the nullfs file system");
+ "Processes in jail can mount the nullfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_procfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_PROCFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the procfs file system");
+ "Processes in jail can mount the procfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_linprocfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_LINPROCFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the linprocfs file system");
+ "Processes in jail can mount the linprocfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_linsysfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_LINSYSFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the linsysfs file system");
+ "Processes in jail can mount the linsysfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_tmpfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_TMPFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the tmpfs file system");
+ "Processes in jail can mount the tmpfs file system (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_zfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_ZFS, sysctl_jail_default_allow, "I",
- "Processes in jail can mount the zfs file system");
+ "Processes in jail can mount the zfs file system (deprecated)");
static int
sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
@@ -4419,13 +4422,13 @@ SYSCTL_PROC(_security_jail, OID_AUTO, enforce_statfs,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
&jail_default_enforce_statfs, offsetof(struct prison, pr_enforce_statfs),
sysctl_jail_default_level, "I",
- "Processes in jail cannot see all mounted file systems");
+ "Processes in jail cannot see all mounted file systems (deprecated)");
SYSCTL_PROC(_security_jail, OID_AUTO, devfs_ruleset,
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&jail_default_devfs_rsnum, offsetof(struct prison, pr_devfs_rsnum),
sysctl_jail_default_level, "I",
- "Ruleset for the devfs filesystem in jail");
+ "Ruleset for the devfs filesystem in jail (deprecated)");
/*
* Nodes to describe jail parameters. Maximum length of string parameters
OpenPOWER on IntegriCloud