Introduce the extensible jail framework, using the same "name=value"

interface as nmount(2).  Three new system calls are added:
* jail_set, to create jails and change the parameters of existing jails.
  This replaces jail(2).
* jail_get, to read the parameters of existing jails.  This replaces the
  security.jail.list sysctl.
* jail_remove to kill off a jail's processes and remove the jail.
Most jail parameters may now be changed after creation, and jails may be
set to exist without any attached processes.  The current jail(2) system
call still exists, though it is now a stub to jail_set(2).

Approved by:	bz (mentor)
This commit is contained in:
jamie 2009-04-29 21:14:15 +00:00
parent 32a71137f0
commit 453b86f943
13 changed files with 2136 additions and 565 deletions

@ -137,7 +137,10 @@ MLINKS+=getsockopt.2 setsockopt.2
MLINKS+=gettimeofday.2 settimeofday.2
MLINKS+=getuid.2 geteuid.2
MLINKS+=intro.2 errno.2
MLINKS+=jail.2 jail_attach.2
MLINKS+=jail.2 jail_attach.2 \
jail.2 jail_get.2 \
jail.2 jail_remove.2 \
jail.2 jail_set.2
MLINKS+=kldunload.2 kldunloadf.2
MLINKS+=kqueue.2 kevent.2
MLINKS+=link.2 linkat.2

@ -344,6 +344,9 @@ FBSD_1.1 {
fexecve;
fstatat;
futimesat;
jail_get;
jail_set;
jail_remove;
linkat;
mkdirat;
mkfifoat;

@ -1,4 +1,5 @@
.\" Copyright (c) 1999 Poul-Henning Kamp.
.\" Copyright (c) 2009 James Gritton.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -24,12 +25,16 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 6, 2009
.Dd April 29, 2009
.Dt JAIL 2
.Os
.Sh NAME
.Nm jail , jail_attach
.Nd imprison current process and future descendants
.Nm jail ,
.Nm jail_get ,
.Nm jail_set ,
.Nm jail_remove ,
.Nm jail_attach
.Nd create and manage system jails
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@ -39,6 +44,13 @@
.Fn jail "struct jail *jail"
.Ft int
.Fn jail_attach "int jid"
.Ft int
.Fn jail_remove "int jid"
.In sys/uio.h
.Ft int
.Fn jail_get "struct iovec *iov" "u_int niov" "int flags"
.Ft int
.Fn jail_set "struct iovec *iov" "u_int niov" "int flags"
.Sh DESCRIPTION
The
.Fn jail
@ -94,20 +106,147 @@ 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 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.
Jail parameters are passed as an array of name-value pairs in the array
.Fa iov ,
containing
.Fa niov
elements.
Parameter names are a null-terminated string, and values may be strings,
integers, or other arbitrary data.
Some parameters are boolean, and do not have a value (their length is zero)
but are set by the name alone with or without a
.Dq no
prefix, e.g.
.Va persist
or
.Va nopersist .
Any parameters not set will be given default values, generally based on
the current environment.
.Pp
Jails have a set of core parameters, and modules can add their own jail
parameters.
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
.Va jid
and
.Va name ,
which identify the jail being created or modified.
See
.Xr jail 8
for more information on the core jail parameters.
.Pp
The
.Fa flags
arguments consists of one or more of the following flags:
.Bl -tag -width indent
.It Dv JAIL_CREATE
Create a new jail.
If a
.Va jid
or
.Va name
parameters exists, they must not refer to an existing jail.
.It Dv JAIL_UPDATE
Modify an existing jail.
One of the
.Va jid
or
.Va name
parameters must exist, and must refer to an existing jail.
If both
.Dv JAIL_CREATE
and
.Dv JAIL_UPDATE
are set, a jail will be created if it does not yet exist, and modified if it
does exist.
.It Dv JAIL_ATTACH
In addition to creating or modifying the jail, attach the current process to
it, as with the
.Fn jail_attach
system call.
.It Dv JAIL_DYING
Allow setting a jail that is in the process of being removed.
.El
.Pp
The
.Fn jail_get
system call retrieves jail parameters, using the same name-value list as
.Fn jail_set
in the
.Fa iov
and
.Fa niov
arguments.
The jail to read can be specified by either
.Va jid
or
.Va name
by including those parameters in the list.
If they are included but are not intended to be the search key, they
should be cleared (zero and the empty string respectively).
.Pp
The special parameter
.Va lastjid
can be used to retrieve a list of all jails.
It will fetch the jail with the jid above and closest to the passed value.
The first jail (usually but not always jid 1) can be found by passing a
.Va lastjid
of zero.
.Pp
The
.Fa flags
arguments consists of one or more following flags:
.Bl -tag -width indent
.It Dv JAIL_DYING
Allow getting a jail that is in the process of being removed.
.El
.Pp
The
.Fn jail_attach
system call attaches the current process to an existing jail,
identified by
.Fa jid .
.Pp
The
.Fn jail_remove
system call removes the jail identified by
.Fa jid .
It will kill all processes belonging to the jail, and remove any children
of that jail.
.Sh RETURN VALUES
If successful,
.Fn jail
returns a non-negative integer, termed the jail identifier (JID).
It returns \-1 on failure, and sets
.Fn jail ,
.Fn jail_set ,
and
.Fn jail_get
return a non-negative integer, termed the jail identifier (JID).
They return \-1 on failure, and set
.Va errno
to indicate the error.
.Pp
.Rv -std jail_attach
.Rv -std jail_attach jail_remove
.Sh PRISON?
Once a process has been put in a prison, it and its descendants cannot escape
the prison.
@ -152,15 +291,111 @@ The
system call
will fail if:
.Bl -tag -width Er
.It Bq Er EPERM
This process is not allowed to create a jail.
.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:
.Bl -tag -width Er
.It Bq Er EPERM
This process is not allowed to create a jail.
.It Bq Er EPERM
A jail parameter was set to a less restrictive value then the current
environment.
.It Bq Er EFAULT
.Fa Iov ,
or one of the addresses contained within it,
points to an address outside the allocated address space of the process.
.It Bq Er ENOENT
The jail referred to by a
.Va jid
or
.Va name
parameter does not exist, and the
.Dv JAIL_CREATE
flag is not set.
.It Bq Er EEXIST
The jail referred to by a
.Va jid
or
.Va name
parameter exists, and the
.Dv JAIL_UPDATE
flag is not set.
.It Bq Er EINVAL
A supplied parameter is the wrong size.
.It Bq Er EINVAL
A supplied parameter is out of range.
.It Bq Er EINVAL
A supplied string parameter is not null-terminated.
.It Bq Er EINVAL
A supplied parameter name does not match any known parameters.
.It Bq Er EINVAL
One of the
.Dv JAIL_CREATE
or
.Dv JAIL_UPDATE
flags is not set.
.It Bq Er ENAMETOOLONG
A supplied string parameter is longer than allowed.
.It Bq Er EAGAIN
There are no jail IDs left.
.El
.Pp
The
.Fn jail_get
system call
will fail if:
.Bl -tag -width Er
.It Bq Er EFAULT
.Fa Iov ,
or one of the addresses contained within it,
points to an address outside the allocated address space of the process.
.It Bq Er ENOENT
The jail referred to by a
.Va jid
or
.Va name
parameter does not exist.
.It Bq Er ENOENT
The
.Va lastjid
parameter is greater than the highest current jail ID.
.It Bq Er EINVAL
A supplied parameter is the wrong size.
.It Bq Er EINVAL
A supplied parameter name does not match any known parameters.
.El
.Pp
The
.Fn jail_attach
and
.Fn jail_remove
system calls
will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The jail specified by
.Fa jid
does not exist.
.El
.Pp
Further
.Fn jail
calls
.Fn jail ,
.Fn jail_set ,
and
.Fn jail_attach
call
.Xr chroot 2
internally, so it can fail for all the same reasons.
Please consult the
@ -168,7 +403,8 @@ Please consult the
manual page for details.
.Sh SEE ALSO
.Xr chdir 2 ,
.Xr chroot 2
.Xr chroot 2 ,
.Xr jail 8
.Sh HISTORY
The
.Fn jail
@ -178,6 +414,13 @@ The
.Fn jail_attach
system call appeared in
.Fx 5.1 .
The
.Fn jail_set ,
.Fn jail_get ,
and
.Fn jail_remove
system calls appeared in
.Fx 8.0 .
.Sh AUTHORS
The jail feature was written by
.An Poul-Henning Kamp
@ -185,3 +428,5 @@ for R&D Associates
.Dq Li http://www.rndassociates.com/
who contributed it to
.Fx .
.An James Gritton
added the extensible jail parameters.

@ -233,7 +233,7 @@ static void
zone_sysinit(void *arg __unused)
{
zone_slot = osd_jail_register(zone_destroy);
zone_slot = osd_jail_register(zone_destroy, NULL);
}
static void

@ -28,6 +28,8 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/bus.h>
@ -76,6 +78,10 @@ __FBSDID("$FreeBSD$");
#include <sys/sem.h>
#include <sys/shm.h>
#ifdef INET
#include <netinet/in.h>
#endif
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_param.h>
@ -106,6 +112,8 @@ CTASSERT(sizeof(struct msghdr32) == 28);
CTASSERT(sizeof(struct stat32) == 96);
CTASSERT(sizeof(struct sigaction32) == 24);
extern int jail_max_af_ips;
static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
@ -2036,9 +2044,17 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
int
freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
{
struct iovec optiov[10];
struct uio opt;
char *u_path, *u_hostname, *u_name;
#ifdef INET
struct in_addr *u_ip4;
#endif
#ifdef INET6
struct in6_addr *u_ip6;
#endif
uint32_t version;
int error;
struct jail j;
error = copyin(uap->jail, &version, sizeof(uint32_t));
if (error)
@ -2050,14 +2066,45 @@ freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
/* FreeBSD single IPv4 jails. */
struct jail32_v0 j32_v0;
bzero(&j, sizeof(struct jail));
error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
if (error)
return (error);
CP(j32_v0, j, version);
PTRIN_CP(j32_v0, j, path);
PTRIN_CP(j32_v0, j, hostname);
j.ip4s = j32_v0.ip_number;
u_path = malloc(MAXPATHLEN + MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
u_hostname = u_path + MAXPATHLEN;
opt.uio_iov = optiov;
opt.uio_iovcnt = 4;
opt.uio_offset = -1;
opt.uio_resid = -1;
opt.uio_segflg = UIO_SYSSPACE;
opt.uio_rw = UIO_READ;
opt.uio_td = td;
optiov[0].iov_base = "path";
optiov[0].iov_len = sizeof("path");
optiov[1].iov_base = u_path;
error = copyinstr(PTRIN(j32_v0.path), u_path, MAXPATHLEN,
&optiov[1].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
optiov[2].iov_base = "host.hostname";
optiov[2].iov_len = sizeof("host.hostname");
optiov[3].iov_base = u_hostname;
error = copyinstr(PTRIN(j32_v0.hostname), u_hostname,
MAXHOSTNAMELEN, &optiov[3].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
#ifdef INET
optiov[opt.uio_iovcnt].iov_base = "ip4.addr";
optiov[opt.uio_iovcnt].iov_len = sizeof("ip4.addr");
opt.uio_iovcnt++;
optiov[opt.uio_iovcnt].iov_base = &j32_v0.ip_number;
j32_v0.ip_number = htonl(j32_v0.ip_number);
optiov[opt.uio_iovcnt].iov_len = sizeof(j32_v0.ip_number);
opt.uio_iovcnt++;
#endif
break;
}
@ -2072,18 +2119,109 @@ freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
{
/* FreeBSD multi-IPv4/IPv6,noIP jails. */
struct jail32 j32;
size_t tmplen;
error = copyin(uap->jail, &j32, sizeof(struct jail32));
if (error)
return (error);
CP(j32, j, version);
PTRIN_CP(j32, j, path);
PTRIN_CP(j32, j, hostname);
PTRIN_CP(j32, j, jailname);
CP(j32, j, ip4s);
CP(j32, j, ip6s);
PTRIN_CP(j32, j, ip4);
PTRIN_CP(j32, j, ip6);
tmplen = MAXPATHLEN + MAXHOSTNAMELEN + MAXHOSTNAMELEN;
#ifdef INET
if (j32.ip4s > jail_max_af_ips)
return (EINVAL);
tmplen += j32.ip4s * sizeof(struct in_addr);
#else
if (j32.ip4s > 0)
return (EINVAL);
#endif
#ifdef INET6
if (j32.ip6s > jail_max_af_ips)
return (EINVAL);
tmplen += j32.ip6s * sizeof(struct in6_addr);
#else
if (j32.ip6s > 0)
return (EINVAL);
#endif
u_path = malloc(tmplen, M_TEMP, M_WAITOK);
u_hostname = u_path + MAXPATHLEN;
u_name = u_hostname + MAXHOSTNAMELEN;
#ifdef INET
u_ip4 = (struct in_addr *)(u_name + MAXHOSTNAMELEN);
#endif
#ifdef INET6
#ifdef INET
u_ip6 = (struct in6_addr *)(u_ip4 + j32.ip4s);
#else
u_ip6 = (struct in6_addr *)(u_name + MAXHOSTNAMELEN);
#endif
#endif
opt.uio_iov = optiov;
opt.uio_iovcnt = 4;
opt.uio_offset = -1;
opt.uio_resid = -1;
opt.uio_segflg = UIO_SYSSPACE;
opt.uio_rw = UIO_READ;
opt.uio_td = td;
optiov[0].iov_base = "path";
optiov[0].iov_len = sizeof("path");
optiov[1].iov_base = u_path;
error = copyinstr(PTRIN(j32.path), u_path, MAXPATHLEN,
&optiov[1].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
optiov[2].iov_base = "host.hostname";
optiov[2].iov_len = sizeof("host.hostname");
optiov[3].iov_base = u_hostname;
error = copyinstr(PTRIN(j32.hostname), u_hostname,
MAXHOSTNAMELEN, &optiov[3].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
if (PTRIN(j32.jailname) != NULL) {
optiov[opt.uio_iovcnt].iov_base = "name";
optiov[opt.uio_iovcnt].iov_len = sizeof("name");
opt.uio_iovcnt++;
optiov[opt.uio_iovcnt].iov_base = u_name;
error = copyinstr(PTRIN(j32.jailname), u_name,
MAXHOSTNAMELEN, &optiov[opt.uio_iovcnt].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
opt.uio_iovcnt++;
}
#ifdef INET
optiov[opt.uio_iovcnt].iov_base = "ip4.addr";
optiov[opt.uio_iovcnt].iov_len = sizeof("ip4.addr");
opt.uio_iovcnt++;
optiov[opt.uio_iovcnt].iov_base = u_ip4;
optiov[opt.uio_iovcnt].iov_len =
j32.ip4s * sizeof(struct in_addr);
error = copyin(PTRIN(j32.ip4), u_ip4,
optiov[opt.uio_iovcnt].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
opt.uio_iovcnt++;
#endif
#ifdef INET6
optiov[opt.uio_iovcnt].iov_base = "ip6.addr";
optiov[opt.uio_iovcnt].iov_len = sizeof("ip6.addr");
opt.uio_iovcnt++;
optiov[opt.uio_iovcnt].iov_base = u_ip6;
optiov[opt.uio_iovcnt].iov_len =
j32.ip6s * sizeof(struct in6_addr);
error = copyin(PTRIN(j32.ip6), u_ip6,
optiov[opt.uio_iovcnt].iov_len);
if (error) {
free(u_path, M_TEMP);
return (error);
}
opt.uio_iovcnt++;
#endif
break;
}
@ -2091,7 +2229,54 @@ freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
/* Sci-Fi jails are not supported, sorry. */
return (EINVAL);
}
return (kern_jail(td, &j));
error = kern_jail_set(td, &opt, JAIL_CREATE | JAIL_ATTACH);
free(u_path, M_TEMP);
return (error);
}
int
freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
{
struct uio *auio;
int error;
/* Check that we have an even number of iovecs. */
if (uap->iovcnt & 1)
return (EINVAL);
error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
if (error)
return (error);
error = kern_jail_set(td, auio, uap->flags);
free(auio, M_IOV);
return (error);
}
int
freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
{
struct iovec32 iov32;
struct uio *auio;
int error, i;
/* Check that we have an even number of iovecs. */
if (uap->iovcnt & 1)
return (EINVAL);
error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
if (error)
return (error);
error = kern_jail_get(td, auio, uap->flags);
if (error == 0)
for (i = 0; i < uap->iovcnt; i++) {
PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
CP(auio->uio_iov[i], iov32, iov_len);
error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
if (error != 0)
break;
}
free(auio, M_IOV);
return (error);
}
int

@ -870,3 +870,8 @@
504 AUE_POSIX_OPENPT NOPROTO { int posix_openpt(int flags); }
; 505 is initialised by the kgssapi code, if present.
505 AUE_NULL UNIMPL gssd_syscall
506 AUE_NULL STD { int freebsd32_jail_get(struct iovec32 *iovp, \
unsigned int iovcnt, int flags); }
507 AUE_NULL STD { int freebsd32_jail_set(struct iovec32 *iovp, \
unsigned int iovcnt, int flags); }
508 AUE_NULL NOPROTO { int jail_remove(int jid); }

File diff suppressed because it is too large Load Diff

@ -72,7 +72,9 @@ static LIST_HEAD(, osd) osd_list[OSD_LAST + 1]; /* (m) */
static osd_method_t *osd_methods[OSD_LAST + 1]; /* (m) */
static u_int osd_nslots[OSD_LAST + 1]; /* (m) */
static osd_destructor_t *osd_destructors[OSD_LAST + 1]; /* (o) */
static const u_int osd_nmethods[OSD_LAST + 1];
static const u_int osd_nmethods[OSD_LAST + 1] = {
[OSD_JAIL] = 5,
};
static struct sx osd_module_lock[OSD_LAST + 1];
static struct rmlock osd_object_lock[OSD_LAST + 1];
@ -345,9 +347,9 @@ osd_call(u_int type, u_int method, void *obj, void *data)
*/
error = 0;
sx_slock(&osd_module_lock[type]);
for (i = 1; i <= osd_nslots[type]; i++) {
for (i = 0; i < osd_nslots[type]; i++) {
methodfun =
osd_methods[type][(i - 1) * osd_nmethods[type] + method];
osd_methods[type][i * osd_nmethods[type] + method];
if (methodfun != NULL && (error = methodfun(obj, data)) != 0)
break;
}

@ -897,5 +897,10 @@
504 AUE_POSIX_OPENPT STD { int posix_openpt(int flags); }
; 505 is initialised by the kgssapi code, if present.
505 AUE_NULL NOSTD { int gssd_syscall(char *path); }
506 AUE_NULL STD { int jail_get(struct iovec *iovp, \
unsigned int iovcnt, int flags); }
507 AUE_NULL STD { int jail_set(struct iovec *iovp, \
unsigned int iovcnt, int flags); }
508 AUE_NULL STD { int jail_remove(int jid); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master

@ -1,5 +1,6 @@
/*-
* Copyright (c) 1999 Poul-Henning Kamp.
* Copyright (c) 2009 James Gritton.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -97,15 +98,30 @@ static const struct prison_state {
{ PRISON_STATE_DYING, "DYING" },
};
/*
* Flags for jail_set and jail_get.
*/
#define JAIL_CREATE 0x01 /* Create jail if it doesn't exist */
#define JAIL_UPDATE 0x02 /* Update parameters of existing jail */
#define JAIL_ATTACH 0x04 /* Attach to jail upon creation */
#define JAIL_DYING 0x08 /* Allow getting a dying jail */
#define JAIL_SET_MASK 0x0f
#define JAIL_GET_MASK 0x08
#ifndef _KERNEL
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);
int jail_remove(int);
#else /* _KERNEL */
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/_task.h>
@ -136,29 +152,44 @@ struct cpuset;
* (d) set only during destruction of jail, no mutex needed
*/
struct prison {
LIST_ENTRY(prison) pr_list; /* (a) all prisons */
TAILQ_ENTRY(prison) pr_list; /* (a) all prisons */
int pr_id; /* (c) prison id */
int pr_ref; /* (p) refcount */
int pr_state; /* (p) prison state */
int pr_nprocs; /* (p) process count */
int pr_uref; /* (p) user (alive) refcount */
unsigned pr_flags; /* (p) PR_* flags */
char pr_path[MAXPATHLEN]; /* (c) chroot path */
struct cpuset *pr_cpuset; /* (p) cpuset */
struct vnode *pr_root; /* (c) vnode to rdir */
char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname */
char pr_name[MAXHOSTNAMELEN]; /* (c) admin jail name */
char pr_name[MAXHOSTNAMELEN]; /* (p) admin jail name */
void *pr_linux; /* (p) linux abi */
int pr_securelevel; /* (p) securelevel */
struct task pr_task; /* (d) destroy task */
struct mtx pr_mtx;
struct osd pr_osd; /* (p) additional data */
int pr_ip4s; /* (c) number of v4 IPs */
struct in_addr *pr_ip4; /* (c) v4 IPs of jail */
int pr_ip6s; /* (c) number of v6 IPs */
struct in6_addr *pr_ip6; /* (c) v6 IPs of jail */
int pr_ip4s; /* (p) number of v4 IPs */
struct in_addr *pr_ip4; /* (p) v4 IPs of jail */
int pr_ip6s; /* (p) number of v6 IPs */
struct in6_addr *pr_ip6; /* (p) v6 IPs of jail */
};
#endif /* _KERNEL || _WANT_PRISON */
#ifdef _KERNEL
/*
* Flag bits set via options or internally
*/
#define PR_PERSIST 0x00000001 /* Can exist without processes */
#define PR_REMOVE 0x01000000 /* In process of being removed */
/*
* OSD methods
*/
#define PR_METHOD_CREATE 0
#define PR_METHOD_GET 1
#define PR_METHOD_SET 2
#define PR_METHOD_CHECK 3
#define PR_METHOD_ATTACH 4
/*
* Sysctl-set variables that determine global jail policy
*
@ -171,10 +202,29 @@ extern int jail_getfsstat_jailrootonly;
extern int jail_allow_raw_sockets;
extern int jail_chflags_allowed;
LIST_HEAD(prisonlist, prison);
TAILQ_HEAD(prisonlist, prison);
extern struct prisonlist allprison;
extern struct sx allprison_lock;
/*
* Sysctls to describe jail parameters.
*/
SYSCTL_DECL(_security_jail_param);
#define SYSCTL_JAIL_PARAM(module, param, type, fmt, descr) \
SYSCTL_PROC(_security_jail_param ## module, OID_AUTO, param, \
(type) | CTLFLAG_MPSAFE, NULL, 0, sysctl_jail_param, fmt, descr)
#define SYSCTL_JAIL_PARAM_STRING(module, param, access, len, descr) \
SYSCTL_PROC(_security_jail_param ## module, OID_AUTO, param, \
CTLTYPE_STRING | CTLFLAG_MPSAFE | (access), NULL, len, \
sysctl_jail_param, "A", descr)
#define SYSCTL_JAIL_PARAM_STRUCT(module, param, access, len, fmt, descr)\
SYSCTL_PROC(_security_jail_param ## module, OID_AUTO, param, \
CTLTYPE_STRUCT | CTLFLAG_MPSAFE | (access), NULL, len, \
sysctl_jail_param, fmt, descr)
#define SYSCTL_JAIL_PARAM_NODE(module, descr) \
SYSCTL_NODE(_security_jail_param, OID_AUTO, module, CTLFLAG_RW, 0, descr)
/*
* Kernel support functions for jail().
*/
@ -182,8 +232,6 @@ struct ucred;
struct mount;
struct sockaddr;
struct statfs;
struct thread;
int kern_jail(struct thread *, struct jail *);
int jailed(struct ucred *cred);
void getcredhostname(struct ucred *cred, char *, size_t);
int prison_check(struct ucred *cred1, struct ucred *cred2);
@ -191,6 +239,7 @@ int prison_canseemount(struct ucred *cred, struct mount *mp);
void prison_enforce_statfs(struct ucred *cred, struct mount *mp,
struct statfs *sp);
struct prison *prison_find(int prid);
struct prison *prison_find_name(const char *name);
void prison_free(struct prison *pr);
void prison_free_locked(struct prison *pr);
void prison_hold(struct prison *pr);
@ -210,6 +259,7 @@ int prison_check_ip6(struct ucred *, struct in6_addr *);
int prison_check_af(struct ucred *cred, int af);
int prison_if(struct ucred *cred, struct sockaddr *sa);
int prison_priv_check(struct ucred *cred, int priv);
int sysctl_jail_param(struct sysctl_oid *, void *, int , struct sysctl_req *);
#endif /* _KERNEL */
#endif /* !_SYS_JAIL_H_ */

@ -81,8 +81,8 @@ void osd_exit(u_int type, struct osd *osd);
#define osd_thread_exit(td) \
osd_exit(OSD_THREAD, &(td)->td_osd)
#define osd_jail_register(destructor) \
osd_register(OSD_JAIL, (destructor), NULL)
#define osd_jail_register(destructor, methods) \
osd_register(OSD_JAIL, (destructor), (methods))
#define osd_jail_deregister(slot) \
osd_deregister(OSD_JAIL, (slot))
#define osd_jail_set(pr, slot, value) \

@ -128,6 +128,8 @@
* Jail privileges.
*/
#define PRIV_JAIL_ATTACH 110 /* Attach to a jail. */
#define PRIV_JAIL_SET 111 /* Set jail parameters. */
#define PRIV_JAIL_REMOVE 112 /* Remove a jail. */
/*
* Kernel environment priveleges.

@ -105,6 +105,8 @@ 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_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,
struct kevent_copyops *k_ops, const struct timespec *timeout);
int kern_kldload(struct thread *td, const char *file, int *fileid);