Put jail(2) under COMPAT_FREEBSD11. It has been the "old" way of creating

jails since FreeBSD 7.

Along with the system call, put the various security.jail.allow_foo and
security.jail.foo_allowed sysctls partly under COMPAT_FREEBSD11 (or
BURN_BRIDGES).  These sysctls had two disparate uses: on the system side,
they were global permissions for jails created via jail(2) which lacked
fine-grained permission controls; inside a jail, they're read-only
descriptions of what the current jail is allowed to do.  The first use
is obsolete along with jail(2), but keep them for the second-read-only use.

Differential Revision:	D14791
This commit is contained in:
jamie 2018-08-16 18:40:16 +00:00
parent 5f1af1a0a1
commit 94a36bb7c1
23 changed files with 153 additions and 251 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)kvm_getvfsbyname.3 8.3 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd August 30, 2016
.Dd August 16, 2018
.Dt GETVFSBYNAME 3
.Os
.Sh NAME
@ -83,9 +83,10 @@ aliases some other mounted FS
stores file names as Unicode
.It Dv VFCF_JAIL
can be mounted from within a jail if
.Va security.jail.mount_allowed
sysctl is set to
.Dv 1
.Va allow.mount
and
.Va allow.mount.<vfc_name>
jail parameters are set
.It Dv VFCF_DELEGADMIN
supports delegated administration if
.Va vfs.usermount

View File

@ -25,11 +25,10 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 8, 2012
.Dd August 16, 2018
.Dt JAIL 2
.Os
.Sh NAME
.Nm jail ,
.Nm jail_get ,
.Nm jail_set ,
.Nm jail_remove ,
@ -41,8 +40,6 @@
.In sys/param.h
.In sys/jail.h
.Ft int
.Fn jail "struct jail *jail"
.Ft int
.Fn jail_attach "int jid"
.Ft int
.Fn jail_remove "int jid"
@ -53,73 +50,6 @@
.Fn jail_set "struct iovec *iov" "u_int niov" "int flags"
.Sh DESCRIPTION
The
.Fn jail
system call sets up a jail and locks the current process in it.
.Pp
The argument is a pointer to a structure describing the prison:
.Bd -literal -offset indent
struct jail {
uint32_t version;
char *path;
char *hostname;
char *jailname;
unsigned int ip4s;
unsigned int ip6s;
struct in_addr *ip4;
struct in6_addr *ip6;
};
.Ed
.Pp
.Dq Li version
defines the version of the API in use.
.Dv JAIL_API_VERSION
is defined for the current version.
.Pp
The
.Dq Li path
pointer should be set to the directory which is to be the root of the
prison.
.Pp
The
.Dq Li hostname
pointer can be set to the hostname of the prison.
This can be changed
from the inside of the prison.
.Pp
The
.Dq Li jailname
pointer is an optional name that can be assigned to the jail
for example for management purposes.
.Pp
The
.Dq Li ip4s
and
.Dq Li ip6s
give the numbers of IPv4 and IPv6 addresses that will be passed
via their respective pointers.
.Pp
The
.Dq Li ip4
and
.Dq Li ip6
pointers can be set to an arrays of IPv4 and IPv6 addresses to be assigned to
the prison, or NULL if none.
IPv4 addresses must be in network byte order.
.Pp
This is equivalent to, and deprecated in favor of, the
.Fn jail_set
system call (see below), with the parameters
.Va path ,
.Va host.hostname ,
.Va name ,
.Va ip4.addr ,
and
.Va ip6.addr ,
and with the
.Dv JAIL_ATTACH
flag.
.Pp
The
.Fn jail_set
system call creates a new jail, or modifies an existing one, and optionally
locks the current process in it.
@ -146,13 +76,19 @@ The current set of available parameters, and their formats, can be
retrieved via the
.Va security.jail.param
sysctl MIB entry.
Notable parameters include those mentioned in the
.Fn jail
description above, as well as
Notable parameters include
.Va jid
and
.Va name ,
which identify the jail being created or modified.
.Va name
which identify the jail being created or modified,
.Va path
(the root directory of the jail),
.Va host.hostname
(the hostname of the jail), and
.Va ip4.addr
and
.Va ip6.addr
(IP addresses to assign to the jail).
See
.Xr jail 8
for more information on the core jail parameters.
@ -237,8 +173,7 @@ It will kill all processes belonging to the jail, and remove any children
of that jail.
.Sh RETURN VALUES
If successful,
.Fn jail ,
.Fn jail_set ,
.Fn jail_set
and
.Fn jail_get
return a non-negative integer, termed the jail identifier (JID).
@ -249,25 +184,6 @@ to indicate the error.
.Rv -std jail_attach jail_remove
.Sh ERRORS
The
.Fn jail
system call
will fail if:
.Bl -tag -width Er
.It Bq Er EPERM
This process is not allowed to create a jail, either because it is not
the super-user, or because it would exceed the jail's
.Va children.max
limit.
.It Bq Er EFAULT
.Fa jail
points to an address outside the allocated address space of the process.
.It Bq Er EINVAL
The version number of the argument is not correct.
.It Bq Er EAGAIN
No free JID could be found.
.El
.Pp
The
.Fn jail_set
system call
will fail if:
@ -371,8 +287,7 @@ does not exist.
.El
.Pp
Further
.Fn jail ,
.Fn jail_set ,
.Fn jail_set
and
.Fn jail_attach
call
@ -386,7 +301,7 @@ manual page for details.
.Xr chroot 2 ,
.Xr jail 8
.Sh HISTORY
The
The now-deprecated
.Fn jail
system call appeared in
.Fx 4.0 .

View File

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 21, 2013
.Dd August 16, 2018
.Dt VFS_SET 9
.Os
.Sh NAME
@ -72,9 +72,10 @@ Loopback file system layer.
File names are stored as Unicode.
.It Dv VFCF_JAIL
Can be mounted from within a jail if
.Va security.jail.mount_allowed
sysctl is set to
.Dv 1 .
.Va allow.mount
and
.Va allow.mount.<fsname>
jail parameters are set.
.It Dv VFCF_DELEGADMIN
Supports delegated administration if
.Va vfs.usermount

View File

@ -5195,9 +5195,8 @@ zfs_freebsd_setattr(ap)
* Privileged non-jail processes may not modify system flags
* if securelevel > 0 and any existing system flags are set.
* Privileged jail processes behave like privileged non-jail
* processes if the security.jail.chflags_allowed sysctl is
* is non-zero; otherwise, they behave like unprivileged
* processes.
* processes if the PR_ALLOW_CHFLAGS permission bit is set;
* otherwise, they behave like unprivileged processes.
*/
if (secpolicy_fs_owner(vp->v_mount, cred) == 0 ||
priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0) == 0) {

View File

@ -2289,8 +2289,10 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
return (0);
}
#ifdef COMPAT_FREEBSD11
int
freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
freebsd11_freebsd32_jail(struct thread *td,
struct freebsd11_freebsd32_jail_args *uap)
{
uint32_t version;
int error;
@ -2347,8 +2349,9 @@ freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
/* Sci-Fi jails are not supported, sorry. */
return (EINVAL);
}
return (kern_jail(td, &j));
return (freebsd11_kern_jail(td, &j));
}
#endif /* COMPAT_FREEBSD11 */
int
freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)

View File

@ -283,9 +283,6 @@ struct freebsd32_sched_rr_get_interval_args {
char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)];
char interval_l_[PADL_(struct timespec32 *)]; struct timespec32 * interval; char interval_r_[PADR_(struct timespec32 *)];
};
struct freebsd32_jail_args {
char jail_l_[PADL_(struct jail32 *)]; struct jail32 * jail; char jail_r_[PADR_(struct jail32 *)];
};
struct freebsd32_sigtimedwait_args {
char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)];
char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)];
@ -761,7 +758,6 @@ int freebsd32_aio_return(struct thread *, struct freebsd32_aio_return_args *);
int freebsd32_aio_suspend(struct thread *, struct freebsd32_aio_suspend_args *);
int freebsd32_aio_error(struct thread *, struct freebsd32_aio_error_args *);
int freebsd32_sched_rr_get_interval(struct thread *, struct freebsd32_sched_rr_get_interval_args *);
int freebsd32_jail(struct thread *, struct freebsd32_jail_args *);
int freebsd32_sigtimedwait(struct thread *, struct freebsd32_sigtimedwait_args *);
int freebsd32_sigwaitinfo(struct thread *, struct freebsd32_sigwaitinfo_args *);
int freebsd32_aio_waitcomplete(struct thread *, struct freebsd32_aio_waitcomplete_args *);
@ -1184,6 +1180,9 @@ struct freebsd11_freebsd32_fhstat_args {
char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)];
char sb_l_[PADL_(struct freebsd11_stat32 *)]; struct freebsd11_stat32 * sb; char sb_r_[PADR_(struct freebsd11_stat32 *)];
};
struct freebsd11_freebsd32_jail_args {
char jail_l_[PADL_(struct jail32 *)]; struct jail32 * jail; char jail_r_[PADR_(struct jail32 *)];
};
struct freebsd11_freebsd32_kevent_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char changelist_l_[PADL_(const struct kevent32_freebsd11 *)]; const struct kevent32_freebsd11 * changelist; char changelist_r_[PADR_(const struct kevent32_freebsd11 *)];
@ -1223,6 +1222,7 @@ int freebsd11_freebsd32_lstat(struct thread *, struct freebsd11_freebsd32_lstat_
int freebsd11_freebsd32_getdirentries(struct thread *, struct freebsd11_freebsd32_getdirentries_args *);
int freebsd11_freebsd32_getdents(struct thread *, struct freebsd11_freebsd32_getdents_args *);
int freebsd11_freebsd32_fhstat(struct thread *, struct freebsd11_freebsd32_fhstat_args *);
int freebsd11_freebsd32_jail(struct thread *, struct freebsd11_freebsd32_jail_args *);
int freebsd11_freebsd32_kevent(struct thread *, struct freebsd11_freebsd32_kevent_args *);
int freebsd11_freebsd32_fstatat(struct thread *, struct freebsd11_freebsd32_fstatat_args *);
int freebsd11_freebsd32_mknodat(struct thread *, struct freebsd11_freebsd32_mknodat_args *);
@ -1317,7 +1317,7 @@ int freebsd11_freebsd32_mknodat(struct thread *, struct freebsd11_freebsd32_mkno
#define FREEBSD32_SYS_AUE_freebsd6_freebsd32_lio_listio AUE_LIO_LISTIO
#define FREEBSD32_SYS_AUE_freebsd32_sched_rr_get_interval AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd4_freebsd32_sendfile AUE_SENDFILE
#define FREEBSD32_SYS_AUE_freebsd32_jail AUE_JAIL
#define FREEBSD32_SYS_AUE_freebsd11_freebsd32_jail AUE_JAIL
#define FREEBSD32_SYS_AUE_freebsd4_freebsd32_sigaction AUE_SIGACTION
#define FREEBSD32_SYS_AUE_freebsd4_freebsd32_sigreturn AUE_SIGRETURN
#define FREEBSD32_SYS_AUE_freebsd32_sigtimedwait AUE_SIGWAIT

View File

@ -275,7 +275,7 @@
#define FREEBSD32_SYS_utrace 335
/* 336 is freebsd4 freebsd32_sendfile */
#define FREEBSD32_SYS_kldsym 337
#define FREEBSD32_SYS_freebsd32_jail 338
#define FREEBSD32_SYS_freebsd11_freebsd32_jail 338
#define FREEBSD32_SYS_sigprocmask 340
#define FREEBSD32_SYS_sigsuspend 341
/* 342 is freebsd4 freebsd32_sigaction */

View File

@ -347,7 +347,7 @@ const char *freebsd32_syscallnames[] = {
"utrace", /* 335 = utrace */
"compat4.freebsd32_sendfile", /* 336 = freebsd4 freebsd32_sendfile */
"kldsym", /* 337 = kldsym */
"freebsd32_jail", /* 338 = freebsd32_jail */
"compat11.freebsd32_jail", /* 338 = freebsd11 freebsd32_jail */
"#339", /* 339 = pioctl */
"sigprocmask", /* 340 = sigprocmask */
"sigsuspend", /* 341 = sigsuspend */

View File

@ -394,7 +394,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(utrace_args), (sy_call_t *)sys_utrace, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 335 = utrace */
{ compat4(AS(freebsd4_freebsd32_sendfile_args),freebsd32_sendfile), AUE_SENDFILE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 336 = freebsd4 freebsd32_sendfile */
{ AS(kldsym_args), (sy_call_t *)sys_kldsym, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = kldsym */
{ AS(freebsd32_jail_args), (sy_call_t *)freebsd32_jail, AUE_JAIL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = freebsd32_jail */
{ compat11(AS(freebsd11_freebsd32_jail_args),freebsd32_jail), AUE_JAIL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = freebsd11 freebsd32_jail */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 339 = pioctl */
{ AS(sigprocmask_args), (sy_call_t *)sys_sigprocmask, AUE_SIGPROCMASK, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 340 = sigprocmask */
{ AS(sigsuspend_args), (sy_call_t *)sys_sigsuspend, AUE_SIGSUSPEND, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 341 = sigsuspend */

View File

@ -1559,13 +1559,6 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 3;
break;
}
/* freebsd32_jail */
case 338: {
struct freebsd32_jail_args *p = params;
uarg[0] = (intptr_t) p->jail; /* struct jail32 * */
*n_args = 1;
break;
}
/* sigprocmask */
case 340: {
struct sigprocmask_args *p = params;
@ -5711,16 +5704,6 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* freebsd32_jail */
case 338:
switch(ndx) {
case 0:
p = "userland struct jail32 *";
break;
default:
break;
};
break;
/* sigprocmask */
case 340:
switch(ndx) {
@ -9673,11 +9656,6 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* freebsd32_jail */
case 338:
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* sigprocmask */
case 340:
if (ndx == 0 || ndx == 1)

View File

@ -601,7 +601,7 @@
off_t *sbytes, int flags); }
337 AUE_NULL NOPROTO { int kldsym(int fileid, int cmd, \
void *data); }
338 AUE_JAIL STD { int freebsd32_jail(struct jail32 *jail); }
338 AUE_JAIL COMPAT11 { int freebsd32_jail(struct jail32 *jail); }
339 AUE_NULL UNIMPL pioctl
340 AUE_SIGPROCMASK NOPROTO { int sigprocmask(int how, \
const sigset_t *set, sigset_t *oset); }

View File

@ -834,9 +834,8 @@ nandfs_setattr(struct vop_setattr_args *ap)
* Privileged non-jail processes may not modify system flags
* if securelevel > 0 and any existing system flags are set.
* Privileged jail processes behave like privileged non-jail
* processes if the security.jail.chflags_allowed sysctl is
* is non-zero; otherwise, they behave like unprivileged
* processes.
* processes if the PR_ALLOW_CHFLAGS permission bit is set;
* otherwise, they behave like unprivileged processes.
*/
flags = inode->i_flags;

View File

@ -387,7 +387,7 @@ struct sysent sysent[] = {
{ AS(utrace_args), (sy_call_t *)sys_utrace, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 335 = utrace */
{ compat4(AS(freebsd4_sendfile_args),sendfile), AUE_SENDFILE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 336 = freebsd4 sendfile */
{ AS(kldsym_args), (sy_call_t *)sys_kldsym, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = kldsym */
{ AS(jail_args), (sy_call_t *)sys_jail, AUE_JAIL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = jail */
{ compat11(AS(freebsd11_jail_args),jail), AUE_JAIL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = freebsd11 jail */
{ AS(nnpfs_syscall_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 339 = nnpfs_syscall */
{ AS(sigprocmask_args), (sy_call_t *)sys_sigprocmask, AUE_SIGPROCMASK, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 340 = sigprocmask */
{ AS(sigsuspend_args), (sy_call_t *)sys_sigsuspend, AUE_SIGSUSPEND, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 341 = sigsuspend */

View File

@ -74,6 +74,14 @@ __FBSDID("$FreeBSD$");
#include <security/mac/mac_framework.h>
/*
* The old jail(2) interface will exist under COMPAT_FREEBSD11, but the global
* permission sysctls are slated to go away sometime (even with COMPAT).
*/
#if defined(COMPAT_FREEBSD11) && !defined(BURN_BRIDGES)
#define PR_GLOBAL_ALLOW
#endif
#define DEFAULT_HOSTUUID "00000000-0000-0000-0000-000000000000"
MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
@ -199,9 +207,11 @@ 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_ENFORCE_STATFS 2
#define JAIL_DEFAULT_DEVFS_RSNUM 0
#ifdef PR_GLOBAL_ALLOW
static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW;
static int jail_default_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
static int jail_default_devfs_rsnum = JAIL_DEFAULT_DEVFS_RSNUM;
#endif
#if defined(INET) || defined(INET6)
static unsigned jail_max_af_ips = 255;
#endif
@ -219,13 +229,14 @@ prison0_init(void)
strlcpy(prison0.pr_osrelease, osrelease, sizeof(prison0.pr_osrelease));
}
#ifdef COMPAT_FREEBSD11
/*
* struct jail_args {
* struct jail *jail;
* };
*/
int
sys_jail(struct thread *td, struct jail_args *uap)
freebsd11_jail(struct thread *td, struct freebsd11_jail_args *uap)
{
uint32_t version;
int error;
@ -270,13 +281,16 @@ sys_jail(struct thread *td, struct jail_args *uap)
/* Sci-Fi jails are not supported, sorry. */
return (EINVAL);
}
return (kern_jail(td, &j));
return (freebsd11_kern_jail(td, &j));
}
int
kern_jail(struct thread *td, struct jail *j)
freebsd11_kern_jail(struct thread *td, struct jail *j)
{
struct iovec optiov[2 * (4 + nitems(pr_flag_allow)
struct iovec optiov[2 * (3
#ifdef PR_GLOBAL_ALLOW
+ 1 + nitems(pr_flag_allow)
#endif
#ifdef INET
+ 1
#endif
@ -286,7 +300,10 @@ kern_jail(struct thread *td, struct jail *j)
)];
struct uio opt;
char *u_path, *u_hostname, *u_name;
#ifdef PR_GLOBAL_ALLOW
struct bool_flags *bf;
int enforce_statfs;
#endif
#ifdef INET
uint32_t ip4s;
struct in_addr *u_ip4;
@ -295,7 +312,7 @@ kern_jail(struct thread *td, struct jail *j)
struct in6_addr *u_ip6;
#endif
size_t tmplen;
int error, enforce_statfs;
int error;
bzero(&optiov, sizeof(optiov));
opt.uio_iov = optiov;
@ -306,6 +323,7 @@ kern_jail(struct thread *td, struct jail *j)
opt.uio_rw = UIO_READ;
opt.uio_td = td;
#ifdef PR_GLOBAL_ALLOW
/* Set permissions for top-level jails from sysctls. */
if (!jailed(td->td_ucred)) {
for (bf = pr_flag_allow;
@ -327,6 +345,7 @@ kern_jail(struct thread *td, struct jail *j)
optiov[opt.uio_iovcnt].iov_len = sizeof(enforce_statfs);
opt.uio_iovcnt++;
}
#endif
tmplen = MAXPATHLEN + MAXHOSTNAMELEN + MAXHOSTNAMELEN;
#ifdef INET
@ -430,6 +449,7 @@ kern_jail(struct thread *td, struct jail *j)
free(u_path, M_TEMP);
return (error);
}
#endif /* COMPAT_FREEBSD11 */
/*
@ -1247,7 +1267,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
pr->pr_securelevel = ppr->pr_securelevel;
pr->pr_allow = JAIL_DEFAULT_ALLOW & ppr->pr_allow;
#ifdef PR_GLOBAL_ALLOW
pr->pr_enforce_statfs = jail_default_enforce_statfs;
#else
pr->pr_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
#endif
pr->pr_devfs_rsnum = ppr->pr_devfs_rsnum;
pr->pr_osreldate = osreldt ? osreldt : ppr->pr_osreldate;
@ -3415,6 +3439,7 @@ prison_path(struct prison *pr1, struct prison *pr2)
static SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0,
"Jails");
#ifdef COMPAT_FREEBSD11
static int
sysctl_jail_list(SYSCTL_HANDLER_ARGS)
{
@ -3518,6 +3543,7 @@ sysctl_jail_list(SYSCTL_HANDLER_ARGS)
SYSCTL_OID(_security_jail, OID_AUTO, list,
CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
sysctl_jail_list, "S", "List of active jails");
#endif /* COMPAT_FREEBSD11 */
static int
sysctl_jail_jailed(SYSCTL_HANDLER_ARGS)
@ -3557,13 +3583,14 @@ 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 (deprecated)");
"Number of IP addresses a jail may have at most per address family");
#endif
/*
* Default parameters for jail(2) compatibility. For historical reasons,
* the sysctl names have varying similarity to the parameter names. Prisons
* just see their own parameters, and can't change them.
* Jail permissions - jailed processes can read these to find out what they are
* allowed to do. A deprecated use is to set default permissions for prisons
* created via jail(2). For historical reasons, the sysctl names have varying
* similarity to the parameter names.
*/
static int
sysctl_jail_default_allow(SYSCTL_HANDLER_ARGS)
@ -3572,52 +3599,68 @@ sysctl_jail_default_allow(SYSCTL_HANDLER_ARGS)
int allow, error, i;
pr = req->td->td_ucred->cr_prison;
#ifdef PR_GLOBAL_ALLOW
allow = (pr == &prison0) ? jail_default_allow : pr->pr_allow;
#else
allow = pr->pr_allow;
#endif
/* Get the current flag value, and convert it to a boolean. */
i = (allow & arg2) ? 1 : 0;
if (arg1 != NULL)
i = !i;
error = sysctl_handle_int(oidp, &i, 0, req);
if (error || !req->newptr)
if (error)
return (error);
i = i ? arg2 : 0;
if (arg1 != NULL)
i ^= arg2;
/*
* The sysctls don't have CTLFLAGS_PRISON, so assume prison0
* for writing.
*/
mtx_lock(&prison0.pr_mtx);
jail_default_allow = (jail_default_allow & ~arg2) | i;
mtx_unlock(&prison0.pr_mtx);
#ifdef PR_GLOBAL_ALLOW
if (req->newptr) {
i = i ? arg2 : 0;
if (arg1 != NULL)
i ^= arg2;
/*
* The sysctls don't have CTLFLAGS_PRISON, so assume prison0
* for writing.
*/
mtx_lock(&prison0.pr_mtx);
jail_default_allow = (jail_default_allow & ~arg2) | i;
mtx_unlock(&prison0.pr_mtx);
}
#endif
return (0);
}
#ifdef PR_GLOBAL_ALLOW
#define CTLFLAG_GLOBAL_ALLOW (CTLFLAG_RW | CTLFLAG_MPSAFE)
#define ADDR_GLOBAL_ALLOW(i) &i
#else
#define CTLFLAG_GLOBAL_ALLOW (CTLFLAG_RD | CTLFLAG_MPSAFE)
#define ADDR_GLOBAL_ALLOW(i) NULL
#endif
SYSCTL_PROC(_security_jail, OID_AUTO, set_hostname_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
NULL, PR_ALLOW_SET_HOSTNAME, sysctl_jail_default_allow, "I",
"Processes in jail can set their hostnames (deprecated)");
"Processes in jail can set their hostnames");
SYSCTL_PROC(_security_jail, OID_AUTO, socket_unixiproute_only,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
(void *)1, PR_ALLOW_SOCKET_AF, sysctl_jail_default_allow, "I",
"Processes in jail are limited to creating UNIX/IP/route sockets only (deprecated)");
"Processes in jail are limited to creating UNIX/IP/route sockets only");
SYSCTL_PROC(_security_jail, OID_AUTO, sysvipc_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
NULL, PR_ALLOW_SYSVIPC, sysctl_jail_default_allow, "I",
"Processes in jail can use System V IPC primitives (deprecated)");
"Processes in jail can use System V IPC primitives");
SYSCTL_PROC(_security_jail, OID_AUTO, allow_raw_sockets,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
NULL, PR_ALLOW_RAW_SOCKETS, sysctl_jail_default_allow, "I",
"Prison root can create raw sockets (deprecated)");
"Prison root can create raw sockets");
SYSCTL_PROC(_security_jail, OID_AUTO, chflags_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
NULL, PR_ALLOW_CHFLAGS, sysctl_jail_default_allow, "I",
"Processes in jail can alter system file flags (deprecated)");
"Processes in jail can alter system file flags");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
NULL, PR_ALLOW_MOUNT, sysctl_jail_default_allow, "I",
"Processes in jail can mount/unmount jail-friendly file systems (deprecated)");
"Processes in jail can mount/unmount jail-friendly file systems");
static int
sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
@ -3626,25 +3669,33 @@ sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
int level, error;
pr = req->td->td_ucred->cr_prison;
#ifdef PR_GLOBAL_ALLOW
level = (pr == &prison0) ? *(int *)arg1 : *(int *)((char *)pr + arg2);
#else
level = *(int *)((char *)pr + arg2);
#endif
error = sysctl_handle_int(oidp, &level, 0, req);
if (error || !req->newptr)
if (error)
return (error);
*(int *)arg1 = level;
#ifdef PR_GLOBAL_ALLOW
if (req->newptr)
*(int *)arg1 = level;
#endif
return (0);
}
SYSCTL_PROC(_security_jail, OID_AUTO, enforce_statfs,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
&jail_default_enforce_statfs, offsetof(struct prison, pr_enforce_statfs),
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
ADDR_GLOBAL_ALLOW(jail_default_enforce_statfs),
offsetof(struct prison, pr_enforce_statfs),
sysctl_jail_default_level, "I",
"Processes in jail cannot see all mounted file systems (deprecated)");
"Processes in jail cannot see all mounted file systems");
SYSCTL_PROC(_security_jail, OID_AUTO, devfs_ruleset,
CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&jail_default_devfs_rsnum, offsetof(struct prison, pr_devfs_rsnum),
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW,
ADDR_GLOBAL_ALLOW(jail_default_devfs_rsnum),
offsetof(struct prison, pr_devfs_rsnum),
sysctl_jail_default_level, "I",
"Ruleset for the devfs filesystem in jail (deprecated)");
"Ruleset for the devfs filesystem in jail");
/*
* Nodes to describe jail parameters. Maximum length of string parameters
@ -3785,9 +3836,6 @@ prison_add_allow(const char *prefix, const char *name, const char *prefix_descr,
struct bool_flags *bf;
struct sysctl_oid *parent;
char *allow_name, *allow_noname, *allowed;
#ifndef NO_SYSCTL_DESCR
char *descr_deprecated;
#endif
unsigned allow_flag;
if (prefix
@ -3844,10 +3892,7 @@ prison_add_allow(const char *prefix, const char *name, const char *prefix_descr,
bf->flag = allow_flag;
mtx_unlock(&prison0.pr_mtx);
/*
* Create sysctls for the paramter, and the back-compat global
* permission.
*/
/* Create sysctls for the paramter, and the current permission. */
parent = prefix
? SYSCTL_ADD_NODE(NULL,
SYSCTL_CHILDREN(&sysctl___security_jail_param_allow),
@ -3859,17 +3904,10 @@ prison_add_allow(const char *prefix, const char *name, const char *prefix_descr,
if ((prefix
? asprintf(&allowed, M_TEMP, "%s_%s_allowed", prefix, name)
: asprintf(&allowed, M_TEMP, "%s_allowed", name)) >= 0) {
#ifndef NO_SYSCTL_DESCR
(void)asprintf(&descr_deprecated, M_TEMP, "%s (deprecated)",
descr);
#endif
(void)SYSCTL_ADD_PROC(NULL,
SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO, allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, allow_flag,
sysctl_jail_default_allow, "I", descr_deprecated);
#ifndef NO_SYSCTL_DESCR
free(descr_deprecated, M_TEMP);
#endif
CTLTYPE_INT | CTLFLAG_GLOBAL_ALLOW, NULL, allow_flag,
sysctl_jail_default_allow, "I", descr);
free(allowed, M_TEMP);
}
return allow_flag;

View File

@ -344,7 +344,7 @@ const char *syscallnames[] = {
"utrace", /* 335 = utrace */
"compat4.sendfile", /* 336 = freebsd4 sendfile */
"kldsym", /* 337 = kldsym */
"jail", /* 338 = jail */
"compat11.jail", /* 338 = freebsd11 jail */
"nnpfs_syscall", /* 339 = nnpfs_syscall */
"sigprocmask", /* 340 = sigprocmask */
"sigsuspend", /* 341 = sigsuspend */

View File

@ -738,7 +738,7 @@
_Out_opt_ off_t *sbytes, int flags); }
337 AUE_NULL STD { int kldsym(int fileid, int cmd, \
_In_ void *data); }
338 AUE_JAIL STD { int jail( \
338 AUE_JAIL COMPAT11 { int jail( \
_In_ struct jail *jail); }
339 AUE_NULL NOSTD|NOTSTATIC { int nnpfs_syscall(int operation, \

View File

@ -1593,13 +1593,6 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 3;
break;
}
/* jail */
case 338: {
struct jail_args *p = params;
uarg[0] = (intptr_t) p->jail; /* struct jail * */
*n_args = 1;
break;
}
/* nnpfs_syscall */
case 339: {
struct nnpfs_syscall_args *p = params;
@ -5772,16 +5765,6 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* jail */
case 338:
switch(ndx) {
case 0:
p = "userland struct jail *";
break;
default:
break;
};
break;
/* nnpfs_syscall */
case 339:
switch(ndx) {
@ -9647,11 +9630,6 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* jail */
case 338:
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* nnpfs_syscall */
case 339:
if (ndx == 0 || ndx == 1)

View File

@ -32,6 +32,7 @@
#ifndef _SYS_JAIL_H_
#define _SYS_JAIL_H_
#ifdef COMPAT_FREEBSD11
#ifdef _KERNEL
struct jail_v0 {
u_int32_t version;
@ -57,16 +58,6 @@ struct jail {
* For all xprison structs, always keep the pr_version an int and
* the first variable so userspace can easily distinguish them.
*/
#ifndef _KERNEL
struct xprison_v1 {
int pr_version;
int pr_id;
char pr_path[MAXPATHLEN];
char pr_host[MAXHOSTNAMELEN];
u_int32_t pr_ip;
};
#endif
struct xprison {
int pr_version;
int pr_id;
@ -91,6 +82,7 @@ struct xprison {
#define PRISON_STATE_INVALID 0
#define PRISON_STATE_ALIVE 1
#define PRISON_STATE_DYING 2
#endif /* COMPAT_FREEBSD11 */
/*
* Flags for jail_set and jail_get.
@ -110,7 +102,6 @@ struct xprison {
struct iovec;
int jail(struct jail *);
int jail_set(struct iovec *, unsigned int, int);
int jail_get(struct iovec *, unsigned int, int);
int jail_attach(int);

View File

@ -280,7 +280,7 @@
#define SYS_utrace 335
/* 336 is freebsd4 sendfile */
#define SYS_kldsym 337
#define SYS_jail 338
#define SYS_freebsd11_jail 338
#define SYS_nnpfs_syscall 339
#define SYS_sigprocmask 340
#define SYS_sigsuspend 341

View File

@ -209,7 +209,7 @@ MIASM = \
sched_rr_get_interval.o \
utrace.o \
kldsym.o \
jail.o \
freebsd11_jail.o \
nnpfs_syscall.o \
sigprocmask.o \
sigsuspend.o \

View File

@ -143,7 +143,6 @@ int kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
int kern_getsockopt(struct thread *td, int s, int level, int name,
void *optval, enum uio_seg valseg, socklen_t *valsize);
int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data);
int kern_jail(struct thread *td, struct jail *j);
int kern_jail_get(struct thread *td, struct uio *options, int flags);
int kern_jail_set(struct thread *td, struct uio *options, int flags);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
@ -308,5 +307,6 @@ struct freebsd11_dirent;
int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int
count, long *basep, void (*func)(struct freebsd11_dirent *));
int freebsd11_kern_jail(struct thread *td, struct jail *j);
#endif /* !_SYS_SYSCALLSUBR_H_ */

View File

@ -849,9 +849,6 @@ struct kldsym_args {
char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
};
struct jail_args {
char jail_l_[PADL_(struct jail *)]; struct jail * jail; char jail_r_[PADR_(struct jail *)];
};
struct nnpfs_syscall_args {
char operation_l_[PADL_(int)]; int operation; char operation_r_[PADR_(int)];
char a_pathP_l_[PADL_(char *)]; char * a_pathP; char a_pathP_r_[PADR_(char *)];
@ -1961,7 +1958,6 @@ int sys_sched_get_priority_min(struct thread *, struct sched_get_priority_min_ar
int sys_sched_rr_get_interval(struct thread *, struct sched_rr_get_interval_args *);
int sys_utrace(struct thread *, struct utrace_args *);
int sys_kldsym(struct thread *, struct kldsym_args *);
int sys_jail(struct thread *, struct jail_args *);
int sys_nnpfs_syscall(struct thread *, struct nnpfs_syscall_args *);
int sys_sigprocmask(struct thread *, struct sigprocmask_args *);
int sys_sigsuspend(struct thread *, struct sigsuspend_args *);
@ -2531,6 +2527,9 @@ struct freebsd11_fhstat_args {
char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)];
char sb_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * sb; char sb_r_[PADR_(struct freebsd11_stat *)];
};
struct freebsd11_jail_args {
char jail_l_[PADL_(struct jail *)]; struct jail * jail; char jail_r_[PADR_(struct jail *)];
};
struct freebsd11_kevent_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char changelist_l_[PADL_(struct kevent_freebsd11 *)]; struct kevent_freebsd11 * changelist; char changelist_r_[PADR_(struct kevent_freebsd11 *)];
@ -2579,6 +2578,7 @@ int freebsd11_nstat(struct thread *, struct freebsd11_nstat_args *);
int freebsd11_nfstat(struct thread *, struct freebsd11_nfstat_args *);
int freebsd11_nlstat(struct thread *, struct freebsd11_nlstat_args *);
int freebsd11_fhstat(struct thread *, struct freebsd11_fhstat_args *);
int freebsd11_jail(struct thread *, struct freebsd11_jail_args *);
int freebsd11_kevent(struct thread *, struct freebsd11_kevent_args *);
int freebsd11_getfsstat(struct thread *, struct freebsd11_getfsstat_args *);
int freebsd11_statfs(struct thread *, struct freebsd11_statfs_args *);
@ -2849,7 +2849,7 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *);
#define SYS_AUE_utrace AUE_NULL
#define SYS_AUE_freebsd4_sendfile AUE_SENDFILE
#define SYS_AUE_kldsym AUE_NULL
#define SYS_AUE_jail AUE_JAIL
#define SYS_AUE_freebsd11_jail AUE_JAIL
#define SYS_AUE_nnpfs_syscall AUE_NULL
#define SYS_AUE_sigprocmask AUE_SIGPROCMASK
#define SYS_AUE_sigsuspend AUE_SIGSUSPEND

View File

@ -550,9 +550,8 @@ ufs_setattr(ap)
* Privileged non-jail processes may not modify system flags
* if securelevel > 0 and any existing system flags are set.
* Privileged jail processes behave like privileged non-jail
* processes if the security.jail.chflags_allowed sysctl is
* is non-zero; otherwise, they behave like unprivileged
* processes.
* processes if the PR_ALLOW_CHFLAGS permission bit is set;
* otherwise, they behave like unprivileged processes.
*/
if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0)) {
if (ip->i_flags &