summaryrefslogtreecommitdiffstats
path: root/usr.sbin/jail
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2015-05-27 01:19:58 +0000
committersjg <sjg@FreeBSD.org>2015-05-27 01:19:58 +0000
commit65145fa4c81da358fcbc3b650156dab705dfa34e (patch)
tree55c065b6730aaac2afb6c29933ee6ec5fa4c4249 /usr.sbin/jail
parent60ff4eb0dff94a04d75d0d52a3957aaaf5f8c693 (diff)
parente6b664c390af88d4a87208bc042ce503da664c3b (diff)
downloadFreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.zip
FreeBSD-src-65145fa4c81da358fcbc3b650156dab705dfa34e.tar.gz
Merge sync of head
Diffstat (limited to 'usr.sbin/jail')
-rw-r--r--usr.sbin/jail/Makefile3
-rw-r--r--usr.sbin/jail/Makefile.depend1
-rw-r--r--usr.sbin/jail/command.c142
-rw-r--r--usr.sbin/jail/config.c1
-rw-r--r--usr.sbin/jail/jail.832
-rw-r--r--usr.sbin/jail/jail.c16
-rw-r--r--usr.sbin/jail/jailp.h1
-rw-r--r--usr.sbin/jail/state.c13
8 files changed, 135 insertions, 74 deletions
diff --git a/usr.sbin/jail/Makefile b/usr.sbin/jail/Makefile
index 58324ac..9dfdee5 100644
--- a/usr.sbin/jail/Makefile
+++ b/usr.sbin/jail/Makefile
@@ -6,8 +6,7 @@ PROG= jail
MAN= jail.8 jail.conf.5
SRCS= jail.c command.c config.c state.c jailp.h jaillex.l jailparse.y y.tab.h
-DPADD= ${LIBJAIL} ${LIBKVM} ${LIBUTIL} ${LIBL}
-LDADD= -ljail -lkvm -lutil -ll
+LIBADD= jail kvm util l
NO_WMISSING_VARIABLE_DECLARATIONS=
diff --git a/usr.sbin/jail/Makefile.depend b/usr.sbin/jail/Makefile.depend
index 4dabb74..b624768 100644
--- a/usr.sbin/jail/Makefile.depend
+++ b/usr.sbin/jail/Makefile.depend
@@ -15,6 +15,7 @@ DIRDEPS = \
lib/libkvm \
lib/libutil \
usr.bin/lex/lib \
+ usr.bin/yacc.host \
.include <dirdeps.mk>
diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c
index 0d1c898..f6f9db3 100644
--- a/usr.sbin/jail/command.c
+++ b/usr.sbin/jail/command.c
@@ -112,6 +112,12 @@ next_command(struct cfjail *j)
if (!bool_param(j->intparams[IP_MOUNT_FDESCFS]))
continue;
j->comstring = &dummystring;
+ break;
+ case IP_MOUNT_PROCFS:
+ if (!bool_param(j->intparams[IP_MOUNT_PROCFS]))
+ continue;
+ j->comstring = &dummystring;
+ break;
case IP__OP:
case IP_STOP_TIMEOUT:
j->comstring = &dummystring;
@@ -260,8 +266,8 @@ run_command(struct cfjail *j)
const struct passwd *pwd;
const struct cfstring *comstring, *s;
login_cap_t *lcap;
- char **argv;
- char *cs, *comcs, *devpath;
+ const char **argv;
+ char *acs, *cs, *comcs, *devpath;
const char *jidstr, *conslog, *path, *ruleset, *term, *username;
enum intparam comparam;
size_t comlen;
@@ -332,27 +338,26 @@ run_command(struct cfjail *j)
}
argv = alloca((8 + argc) * sizeof(char *));
- *(const char **)&argv[0] = _PATH_IFCONFIG;
+ argv[0] = _PATH_IFCONFIG;
if ((cs = strchr(val, '|'))) {
- argv[1] = alloca(cs - val + 1);
- strlcpy(argv[1], val, cs - val + 1);
+ argv[1] = acs = alloca(cs - val + 1);
+ strlcpy(acs, val, cs - val + 1);
addr = cs + 1;
} else {
- *(const char **)&argv[1] =
- string_param(j->intparams[IP_INTERFACE]);
+ argv[1] = string_param(j->intparams[IP_INTERFACE]);
addr = val;
}
- *(const char **)&argv[2] = "inet";
+ argv[2] = "inet";
if (!(cs = strchr(addr, '/'))) {
argv[3] = addr;
- *(const char **)&argv[4] = "netmask";
- *(const char **)&argv[5] = "255.255.255.255";
+ argv[4] = "netmask";
+ argv[5] = "255.255.255.255";
argc = 6;
} else if (strchr(cs + 1, '.')) {
- argv[3] = alloca(cs - addr + 1);
- strlcpy(argv[3], addr, cs - addr + 1);
- *(const char **)&argv[4] = "netmask";
- *(const char **)&argv[5] = cs + 1;
+ argv[3] = acs = alloca(cs - addr + 1);
+ strlcpy(acs, addr, cs - addr + 1);
+ argv[4] = "netmask";
+ argv[5] = cs + 1;
argc = 6;
} else {
argv[3] = addr;
@@ -360,14 +365,15 @@ run_command(struct cfjail *j)
}
if (!down) {
- for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) {
+ for (cs = strtok(extrap, " "); cs;
+ cs = strtok(NULL, " ")) {
size_t len = strlen(cs) + 1;
- argv[argc] = alloca(len);
- strlcpy(argv[argc++], cs, len);
+ argv[argc++] = acs = alloca(len);
+ strlcpy(acs, cs, len);
}
}
- *(const char **)&argv[argc] = down ? "-alias" : "alias";
+ argv[argc] = down ? "-alias" : "alias";
argv[argc + 1] = NULL;
break;
#endif
@@ -389,46 +395,45 @@ run_command(struct cfjail *j)
}
argv = alloca((8 + argc) * sizeof(char *));
- *(const char **)&argv[0] = _PATH_IFCONFIG;
+ argv[0] = _PATH_IFCONFIG;
if ((cs = strchr(val, '|'))) {
- argv[1] = alloca(cs - val + 1);
- strlcpy(argv[1], val, cs - val + 1);
+ argv[1] = acs = alloca(cs - val + 1);
+ strlcpy(acs, val, cs - val + 1);
addr = cs + 1;
} else {
- *(const char **)&argv[1] =
- string_param(j->intparams[IP_INTERFACE]);
+ argv[1] = string_param(j->intparams[IP_INTERFACE]);
addr = val;
}
- *(const char **)&argv[2] = "inet6";
+ argv[2] = "inet6";
argv[3] = addr;
if (!(cs = strchr(addr, '/'))) {
- *(const char **)&argv[4] = "prefixlen";
- *(const char **)&argv[5] = "128";
+ argv[4] = "prefixlen";
+ argv[5] = "128";
argc = 6;
} else
argc = 4;
if (!down) {
- for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) {
+ for (cs = strtok(extrap, " "); cs;
+ cs = strtok(NULL, " ")) {
size_t len = strlen(cs) + 1;
- argv[argc] = alloca(len);
- strlcpy(argv[argc++], cs, len);
+ argv[argc++] = acs = alloca(len);
+ strlcpy(acs, cs, len);
}
}
- *(const char **)&argv[argc] = down ? "-alias" : "alias";
+ argv[argc] = down ? "-alias" : "alias";
argv[argc + 1] = NULL;
break;
#endif
case IP_VNET_INTERFACE:
argv = alloca(5 * sizeof(char *));
- *(const char **)&argv[0] = _PATH_IFCONFIG;
+ argv[0] = _PATH_IFCONFIG;
argv[1] = comstring->s;
- *(const char **)&argv[2] = down ? "-vnet" : "vnet";
+ argv[2] = down ? "-vnet" : "vnet";
jidstr = string_param(j->intparams[KP_JID]);
- *(const char **)&argv[3] =
- jidstr ? jidstr : string_param(j->intparams[KP_NAME]);
+ argv[3] = jidstr ? jidstr : string_param(j->intparams[KP_NAME]);
argv[4] = NULL;
break;
@@ -454,22 +459,22 @@ run_command(struct cfjail *j)
if (down) {
argv[4] = NULL;
argv[3] = argv[1];
- *(const char **)&argv[0] = "/sbin/umount";
+ argv[0] = "/sbin/umount";
} else {
if (argc == 4) {
argv[7] = NULL;
argv[6] = argv[1];
argv[5] = argv[0];
argv[4] = argv[3];
- *(const char **)&argv[3] = "-o";
+ argv[3] = "-o";
} else {
argv[5] = NULL;
argv[4] = argv[1];
argv[3] = argv[0];
}
- *(const char **)&argv[0] = _PATH_MOUNT;
+ argv[0] = _PATH_MOUNT;
}
- *(const char **)&argv[1] = "-t";
+ argv[1] = "-t";
break;
case IP_MOUNT_DEVFS:
@@ -485,19 +490,19 @@ run_command(struct cfjail *j)
down ? "devfs" : NULL) < 0)
return -1;
if (down) {
- *(const char **)&argv[0] = "/sbin/umount";
+ argv[0] = "/sbin/umount";
argv[1] = devpath;
argv[2] = NULL;
} else {
- *(const char **)&argv[0] = _PATH_MOUNT;
- *(const char **)&argv[1] = "-t";
- *(const char **)&argv[2] = "devfs";
+ argv[0] = _PATH_MOUNT;
+ argv[1] = "-t";
+ argv[2] = "devfs";
ruleset = string_param(j->intparams[KP_DEVFS_RULESET]);
if (!ruleset)
ruleset = "4"; /* devfsrules_jail */
- argv[3] = alloca(11 + strlen(ruleset));
- sprintf(argv[3], "-oruleset=%s", ruleset);
- *(const char **)&argv[4] = ".";
+ argv[3] = acs = alloca(11 + strlen(ruleset));
+ sprintf(acs, "-oruleset=%s", ruleset);
+ argv[4] = ".";
argv[5] = devpath;
argv[6] = NULL;
}
@@ -516,14 +521,40 @@ run_command(struct cfjail *j)
down ? "fdescfs" : NULL) < 0)
return -1;
if (down) {
- *(const char **)&argv[0] = "/sbin/umount";
+ argv[0] = "/sbin/umount";
+ argv[1] = devpath;
+ argv[2] = NULL;
+ } else {
+ argv[0] = _PATH_MOUNT;
+ argv[1] = "-t";
+ argv[2] = "fdescfs";
+ argv[3] = ".";
+ argv[4] = devpath;
+ argv[5] = NULL;
+ }
+ break;
+
+ case IP_MOUNT_PROCFS:
+ argv = alloca(7 * sizeof(char *));
+ path = string_param(j->intparams[KP_PATH]);
+ if (path == NULL) {
+ jail_warnx(j, "mount.procfs: no path");
+ return -1;
+ }
+ devpath = alloca(strlen(path) + 6);
+ sprintf(devpath, "%s/proc", path);
+ if (check_path(j, "mount.procfs", devpath, 0,
+ down ? "procfs" : NULL) < 0)
+ return -1;
+ if (down) {
+ argv[0] = "/sbin/umount";
argv[1] = devpath;
argv[2] = NULL;
} else {
- *(const char **)&argv[0] = _PATH_MOUNT;
- *(const char **)&argv[1] = "-t";
- *(const char **)&argv[2] = "fdescfs";
- *(const char **)&argv[3] = ".";
+ argv[0] = _PATH_MOUNT;
+ argv[1] = "-t";
+ argv[2] = "procfs";
+ argv[3] = ".";
argv[4] = devpath;
argv[5] = NULL;
}
@@ -548,8 +579,8 @@ run_command(struct cfjail *j)
if ((cs = strpbrk(comstring->s, "!\"$&'()*;<>?[\\]`{|}~")) &&
!(cs[0] == '&' && cs[1] == '\0')) {
argv = alloca(4 * sizeof(char *));
- *(const char **)&argv[0] = _PATH_BSHELL;
- *(const char **)&argv[1] = "-c";
+ argv[0] = _PATH_BSHELL;
+ argv[1] = "-c";
argv[2] = comstring->s;
argv[3] = NULL;
} else {
@@ -668,6 +699,11 @@ run_command(struct cfjail *j)
if (term != NULL)
setenv("TERM", term, 1);
}
+ if (setgid(pwd->pw_gid) < 0) {
+ jail_warnx(j, "setgid %d: %s", pwd->pw_gid,
+ strerror(errno));
+ exit(1);
+ }
if (setusercontext(lcap, pwd, pwd->pw_uid, username
? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN
: LOGIN_SETPATH | LOGIN_SETENV) < 0) {
@@ -693,7 +729,7 @@ run_command(struct cfjail *j)
exit(1);
}
closefrom(3);
- execvp(argv[0], argv);
+ execvp(argv[0], __DECONST(char *const*, argv));
jail_warnx(j, "exec %s: %s", argv[0], strerror(errno));
exit(1);
}
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
index cd02a50..5820209 100644
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -84,6 +84,7 @@ static const struct ipspec intparams[] = {
[IP_MOUNT] = {"mount", PF_INTERNAL | PF_REV},
[IP_MOUNT_DEVFS] = {"mount.devfs", PF_INTERNAL | PF_BOOL},
[IP_MOUNT_FDESCFS] = {"mount.fdescfs", PF_INTERNAL | PF_BOOL},
+ [IP_MOUNT_PROCFS] = {"mount.procfs", PF_INTERNAL | PF_BOOL},
[IP_MOUNT_FSTAB] = {"mount.fstab", PF_INTERNAL},
[IP_STOP_TIMEOUT] = {"stop.timeout", PF_INTERNAL | PF_INT},
[IP_VNET_INTERFACE] = {"vnet.interface", PF_INTERNAL},
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 927e2bb..189fa36 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 4, 2014
+.Dd February 25, 2015
.Dt JAIL 8
.Os
.Sh NAME
@@ -276,7 +276,7 @@ Then there are pseudo-parameters that are only used by
.Nm
itself.
.Pp
-Jails have a set a core parameters, and kernel modules can add their own
+Jails have a set of core parameters, and kernel modules can add their own
jail parameters.
The current set of available parameters can be retrieved via
.Dq Nm sysctl Fl d Va security.jail.param .
@@ -362,7 +362,7 @@ A set of IPv6 options for the jail, the counterparts to
and
.Va ip4
above.
-.It vnet
+.It Va vnet
Create the jail with its own virtual network stack,
with its own network interfaces, addresses, routing table, etc.
The kernel must have been compiled with the
@@ -471,6 +471,14 @@ The
.Va jid
of the parent of this jail, or zero if this is a top-level jail
(read-only).
+.It Va osrelease
+The string for the jail's
+.Va kern.osrelease
+sysctl and uname -r.
+.It Va osreldate
+The number for the jail's
+.Va kern.osreldate
+and uname -K.
.It Va allow.*
Some restrictions of the jail environment may be set on a per-jail
basis.
@@ -531,6 +539,14 @@ is set to a value lower than 2.
The devfs ruleset should be restricted from the default by using the
.Va devfs_ruleset
option.
+.It Va allow.mount.fdescfs
+privileged users inside the jail will be able to mount and unmount the
+fdescfs file system.
+This permission is effective only together with
+.Va allow.mount
+and only when
+.Va enforce_statfs
+is set to a value lower than 2.
.It Va allow.mount.nullfs
privileged users inside the jail will be able to mount and unmount the
nullfs file system.
@@ -687,7 +703,7 @@ jail is created, and will be removed from the interface after the
jail is removed.
.It Va ip4.addr
In addition to the IP addresses that are passed to the kernel, an
-interface, netmask and additional paramters (as supported by
+interface, netmask and additional parameters (as supported by
.Xr ifconfig 8 Ns )
may also be specified, in the form
.Dq Ar interface Ns | Ns Ar ip-address Ns / Ns Ar netmask param ... .
@@ -745,6 +761,12 @@ Mount a
filesystem on the chrooted
.Pa /dev/fd
directory.
+.It Va mount.procfs
+Mount a
+.Xr procfs 5
+filesystem on the chrooted
+.Pa /proc
+directory.
.It Va allow.dying
Allow making changes to a
.Va dying
@@ -1183,7 +1205,6 @@ environment of the first jail.
.Xr pkill 1 ,
.Xr ps 1 ,
.Xr quota 1 ,
-.Xr ifconfig 8 ,
.Xr jail_set 2 ,
.Xr devfs 5 ,
.Xr fdescfs 5 ,
@@ -1194,6 +1215,7 @@ environment of the first jail.
.Xr chroot 8 ,
.Xr devfs 8 ,
.Xr halt 8 ,
+.Xr ifconfig 8 ,
.Xr inetd 8 ,
.Xr jexec 8 ,
.Xr jls 8 ,
diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c
index 661c4ad..e42afa4 100644
--- a/usr.sbin/jail/jail.c
+++ b/usr.sbin/jail/jail.c
@@ -93,6 +93,7 @@ static const enum intparam startcommands[] = {
IP__MOUNT_FROM_FSTAB,
IP_MOUNT_DEVFS,
IP_MOUNT_FDESCFS,
+ IP_MOUNT_PROCFS,
IP_EXEC_PRESTART,
IP__OP,
IP_VNET_INTERFACE,
@@ -109,6 +110,7 @@ static const enum intparam stopcommands[] = {
IP_STOP_TIMEOUT,
IP__OP,
IP_EXEC_POSTSTOP,
+ IP_MOUNT_PROCFS,
IP_MOUNT_FDESCFS,
IP_MOUNT_DEVFS,
IP__MOUNT_FROM_FSTAB,
@@ -656,11 +658,11 @@ create_jail(struct cfjail *j)
* The jail already exists, but may be dying.
* Make sure it is, in which case an update is appropriate.
*/
- *(const void **)&jiov[0].iov_base = "jid";
+ jiov[0].iov_base = __DECONST(char *, "jid");
jiov[0].iov_len = sizeof("jid");
jiov[1].iov_base = &jid;
jiov[1].iov_len = sizeof(jid);
- *(const void **)&jiov[2].iov_base = "dying";
+ jiov[2].iov_base = __DECONST(char *, "dying");
jiov[2].iov_len = sizeof("dying");
jiov[3].iov_base = &dying;
jiov[3].iov_len = sizeof(dying);
@@ -721,11 +723,11 @@ clear_persist(struct cfjail *j)
if (!(j->flags & JF_PERSIST))
return;
j->flags &= ~JF_PERSIST;
- *(const void **)&jiov[0].iov_base = "jid";
+ jiov[0].iov_base = __DECONST(char *, "jid");
jiov[0].iov_len = sizeof("jid");
jiov[1].iov_base = &j->jid;
jiov[1].iov_len = sizeof(j->jid);
- *(const void **)&jiov[2].iov_base = "nopersist";
+ jiov[2].iov_base = __DECONST(char *, "nopersist");
jiov[2].iov_len = sizeof("nopersist");
jiov[3].iov_base = NULL;
jiov[3].iov_len = 0;
@@ -849,12 +851,12 @@ running_jid(struct cfjail *j, int dflag)
j->jid = -1;
return;
}
- *(const void **)&jiov[0].iov_base = "jid";
+ jiov[0].iov_base = __DECONST(char *, "jid");
jiov[0].iov_len = sizeof("jid");
jiov[1].iov_base = &jid;
jiov[1].iov_len = sizeof(jid);
} else if ((pval = string_param(j->intparams[KP_NAME]))) {
- *(const void **)&jiov[0].iov_base = "name";
+ jiov[0].iov_base = __DECONST(char *, "name");
jiov[0].iov_len = sizeof("name");
jiov[1].iov_len = strlen(pval) + 1;
jiov[1].iov_base = alloca(jiov[1].iov_len);
@@ -880,7 +882,7 @@ jail_quoted_warnx(const struct cfjail *j, const char *name_msg,
}
/*
- * Set jail parameters and possible print them out.
+ * Set jail parameters and possibly print them out.
*/
static int
jailparam_set_note(const struct cfjail *j, struct jailparam *jp, unsigned njp,
diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h
index 3f89392..bfefca5 100644
--- a/usr.sbin/jail/jailp.h
+++ b/usr.sbin/jail/jailp.h
@@ -96,6 +96,7 @@ enum intparam {
IP_MOUNT, /* Mount points in fstab(5) form */
IP_MOUNT_DEVFS, /* Mount /dev under prison root */
IP_MOUNT_FDESCFS, /* Mount /dev/fd under prison root */
+ IP_MOUNT_PROCFS, /* Mount /proc under prison root */
IP_MOUNT_FSTAB, /* A standard fstab(5) file */
IP_STOP_TIMEOUT, /* Time to wait after sending SIGTERM */
IP_VNET_INTERFACE, /* Assign interface(s) to vnet jail */
diff --git a/usr.sbin/jail/state.c b/usr.sbin/jail/state.c
index 17b2a0c..b3eb942 100644
--- a/usr.sbin/jail/state.c
+++ b/usr.sbin/jail/state.c
@@ -60,7 +60,7 @@ dep_setup(int docf)
const char *cs;
char *pname;
size_t plen;
- int error, deps, ldeps;
+ int deps, ldeps;
if (!docf) {
/*
@@ -88,7 +88,6 @@ dep_setup(int docf)
TAILQ_FOREACH(j, &cfjails, tq)
jails_byname[njails++] = j;
qsort(jails_byname, njails, sizeof(struct cfjail *), cmp_jailptr);
- error = 0;
deps = 0;
ldeps = 0;
plen = 0;
@@ -331,15 +330,15 @@ start_state(const char *target, int docf, unsigned state, int running)
* -R matches its wildcards against currently running
* jails, not against the config file.
*/
- *(const void **)&jiov[0].iov_base = "lastjid";
+ jiov[0].iov_base = __DECONST(char *, "lastjid");
jiov[0].iov_len = sizeof("lastjid");
jiov[1].iov_base = &jid;
jiov[1].iov_len = sizeof(jid);
- *(const void **)&jiov[2].iov_base = "jid";
+ jiov[2].iov_base = __DECONST(char *, "jid");
jiov[2].iov_len = sizeof("jid");
jiov[3].iov_base = &jid;
jiov[3].iov_len = sizeof(jid);
- *(const void **)&jiov[4].iov_base = "name";
+ jiov[4].iov_base = __DECONST(char *, "name");
jiov[4].iov_len = sizeof("name");
jiov[5].iov_base = &namebuf;
jiov[5].iov_len = sizeof(namebuf);
@@ -454,12 +453,12 @@ running_jid(const char *name, int flags)
int jid;
if ((jid = strtol(name, &ep, 10)) && !*ep) {
- *(const void **)&jiov[0].iov_base = "jid";
+ jiov[0].iov_base = __DECONST(char *, "jid");
jiov[0].iov_len = sizeof("jid");
jiov[1].iov_base = &jid;
jiov[1].iov_len = sizeof(jid);
} else {
- *(const void **)&jiov[0].iov_base = "name";
+ jiov[0].iov_base = __DECONST(char *, "name");
jiov[0].iov_len = sizeof("name");
jiov[1].iov_len = strlen(name) + 1;
jiov[1].iov_base = alloca(jiov[1].iov_len);
OpenPOWER on IntegriCloud