aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/ps/print.c4
-rw-r--r--bin/ps/ps.17
-rw-r--r--lib/libc/sys/Makefile.inc4
-rw-r--r--lib/libc/sys/jail.287
-rw-r--r--share/man/man9/suser.955
-rw-r--r--sys/conf/files1
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c10
-rw-r--r--sys/fs/procfs/procfs.h5
-rw-r--r--sys/fs/procfs/procfs_status.c8
-rw-r--r--sys/fs/procfs/procfs_vnops.c13
-rw-r--r--sys/gnu/ext2fs/ext2_vnops.c2
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c2
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/init_sysent.c3
-rw-r--r--sys/kern/kern_exit.c9
-rw-r--r--sys/kern/kern_fork.c8
-rw-r--r--sys/kern/kern_jail.c114
-rw-r--r--sys/kern/kern_ktrace.c4
-rw-r--r--sys/kern/kern_mib.c26
-rw-r--r--sys/kern/kern_proc.c7
-rw-r--r--sys/kern/kern_prot.c46
-rw-r--r--sys/kern/kern_resource.c4
-rw-r--r--sys/kern/kern_sig.c6
-rw-r--r--sys/kern/kern_sysctl.c5
-rw-r--r--sys/kern/kern_xxx.c4
-rw-r--r--sys/kern/sys_process.c4
-rw-r--r--sys/kern/syscalls.c3
-rw-r--r--sys/kern/uipc_usrreq.c15
-rw-r--r--sys/kern/vfs_extattr.c30
-rw-r--r--sys/kern/vfs_syscalls.c30
-rw-r--r--sys/kern/vfs_vnops.c4
-rw-r--r--sys/miscfs/devfs/devfs_vnops.c14
-rw-r--r--sys/miscfs/procfs/procfs.h5
-rw-r--r--sys/miscfs/procfs/procfs_status.c8
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c13
-rw-r--r--sys/msdosfs/msdosfs_vnops.c10
-rw-r--r--sys/net/bpf.c9
-rw-r--r--sys/net/if.c29
-rw-r--r--sys/net/if.h3
-rw-r--r--sys/net/rtsock.c4
-rw-r--r--sys/netinet/in.h5
-rw-r--r--sys/netinet/in_pcb.c30
-rw-r--r--sys/netinet/in_pcb.h3
-rw-r--r--sys/netinet/tcp_subr.c4
-rw-r--r--sys/netinet/tcp_timewait.c4
-rw-r--r--sys/netinet/tcp_usrreq.c4
-rw-r--r--sys/netinet/udp_usrreq.c10
-rw-r--r--sys/nfs/nfs_serv.c6
-rw-r--r--sys/nfsserver/nfs_serv.c6
-rw-r--r--sys/sys/jail.h41
-rw-r--r--sys/sys/proc.h17
-rw-r--r--sys/sys/syscall-hide.h3
-rw-r--r--sys/sys/syscall.h5
-rw-r--r--sys/sys/syscall.mk5
-rw-r--r--sys/sys/sysctl.h3
-rw-r--r--sys/sys/sysproto.h6
-rw-r--r--sys/sys/ucred.h5
-rw-r--r--sys/sys/unpcb.h3
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c4
-rw-r--r--sys/ufs/ufs/ufs_vnops.c12
-rw-r--r--usr.sbin/Makefile3
-rw-r--r--usr.sbin/jail/Makefile4
-rw-r--r--usr.sbin/jail/jail.832
-rw-r--r--usr.sbin/jail/jail.c32
64 files changed, 710 insertions, 157 deletions
diff --git a/bin/ps/print.c b/bin/ps/print.c
index 19560ce2c25b..f60cab6e5034 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -36,7 +36,7 @@
static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94";
#endif
static const char rcsid[] =
- "$Id: print.c,v 1.33 1998/11/25 09:34:00 dfr Exp $";
+ "$Id: print.c,v 1.34 1999/04/06 03:17:57 peter Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -222,6 +222,8 @@ state(k, ve)
*cp++ = 's';
if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid)
*cp++ = '+';
+ if (flag & P_JAILED)
+ *cp++ = 'J';
*cp = '\0';
(void)printf("%-*s", v->width, buf);
}
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index cfdbe2078d3e..5283558524ee 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
-.\" $Id: ps.1,v 1.19 1998/06/04 07:02:59 jkoshy Exp $
+.\" $Id: ps.1,v 1.20 1999/04/06 03:18:57 peter Exp $
.\"
.Dd April 18, 1994
.Dt PS 1
@@ -243,6 +243,11 @@ The first letter indicates the run state of the process:
Marks a process in disk (or other short term, uninterruptible) wait.
.It I
Marks a process that is idle (sleeping for longer than about 20 seconds).
+.It J
+Marks a process which is in
+.Xr jail 2 .
+The hostname of the prison can be found in
+.Ql Li /proc/<pid>/status .
.It R
Marks a runnable process.
.It S
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index dd065f196f84..292860dccc93 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -1,5 +1,5 @@
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
-# $Id: Makefile.inc,v 1.60 1999/04/05 07:38:07 bde Exp $
+# $Id: Makefile.inc,v 1.61 1999/04/11 21:14:40 dt Exp $
# sys sources
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys
@@ -82,7 +82,7 @@ MAN2+= _exit.2 accept.2 access.2 acct.2 adjtime.2 aio_read.2 \
getpeername.2 getpgrp.2 getpid.2 getpriority.2 getrlimit.2 \
getrusage.2 getsid.2 getsockname.2 \
getsockopt.2 gettimeofday.2 getuid.2 \
- intro.2 ioctl.2 issetugid.2 kill.2 \
+ intro.2 ioctl.2 issetugid.2 jail.2 kill.2 \
kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldunload.2 \
ktrace.2 link.2 listen.2 lseek.2 \
madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \
diff --git a/lib/libc/sys/jail.2 b/lib/libc/sys/jail.2
new file mode 100644
index 000000000000..0fe73989c163
--- /dev/null
+++ b/lib/libc/sys/jail.2
@@ -0,0 +1,87 @@
+.\"
+.\"----------------------------------------------------------------------------
+.\""THE BEER-WARE LICENSE" (Revision 42):
+.\"<phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+.\"can do whatever you want with this stuff. If we meet some day, and you think
+.\"this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+.\"----------------------------------------------------------------------------
+.\"
+.\"$Id: malloc.c,v 1.44 1999/03/28 14:16:05 phk Exp $
+.\"
+.\"
+.Dd April 28, 1999
+.Dt JAIL 2
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm jail
+.Nd Imprison current process and future decendants.
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/jail.h>
+.Ft int
+.Fn jail "struct *jail"
+.Sh DESCRIPTION
+The
+.Nm
+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 {
+ char *path;
+ char *hostname;
+ u_int32_t ip_number;
+};
+.Ed
+.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 the hostname of the prison. This can be changed
+from the inside of the prison.
+.Pp
+The
+.Dq Li ip_number
+can be set to the IP number assigned to the prison.
+.Sh PRISON ?
+Once a process has been put in a prison, it and its decendants cannot escape
+the prison. It is not possible to add a process to a preexisting prison.
+.Pp
+Inside the prison, the concept of "superuser" is very diluted, in general
+it can be assumed that nothing can be mangled from inside a prison, that
+doesn't exist inside that prison (ie: the directory tree below
+.Dq Li path .
+.Pp
+All IP activity will be forced to happen to/from the IP number specified,
+which should be an alias on one of the systems interfaces.
+.Pp
+It is possible to identify a process as jailed by examining
+.Dq Li /proc/<pid>/status :
+it will show a field near the end of the line, either as
+a single hyphen for a process at large, or the hostname currently
+set for the prison for jailed processes.
+.Sh ERRORS
+.Fn Jail
+calls
+.Xr chroot 2
+internally, so the it can fail for all the same reasons.
+Please consult the
+.Xr chroot 2
+manual page for details.
+.Sh SEE ALSO
+.Xr chroot 2
+.Xr chdir 2
+.Sh HISTORY
+The
+.Fn jail
+function call appeared in
+.Fx 4.0 .
+.Pp
+The jail feature was written by Poul-Henning Kamp for
+R&D Associates
+.Dq Li http://www.rndassociates.com/
+who contributed it to FreeBSD.
diff --git a/share/man/man9/suser.9 b/share/man/man9/suser.9
index 916ceec50233..39d5ed369157 100644
--- a/share/man/man9/suser.9
+++ b/share/man/man9/suser.9
@@ -31,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: suser.9,v 1.4 1997/03/07 02:53:37 jmg Exp $
+.\" $Id: suser.9,v 1.5 1998/01/16 18:06:23 bde Exp $
.\"
.Dd Oct 15, 1996
.Dt SUSER 9
@@ -43,25 +43,60 @@
.Fd #include <sys/param.h>
.Fd #include <sys/ucred.h>
.Ft int
-.Fn suser "struct ucred *cred, u_short *acflag"
+.Fn suser "struct proc *proc"
+.Ft int
+.Fn suser_xxx "struct ucred *cred, struct proc *proc, int flags"
.Sh DESCRIPTION
The
.Nm
-function checks if the credentials given include superuser powers.
+and
+.Nm suser_xxx
+functions checks if the credentials given include superuser powers.
+.Pp
+The
+.Nm
+function is the most common, and should be used unless special
+circumstances dictate otherwise.
+.Pp
+The
+.Nm suser_xxx
+function should be used when the credentials to be checked are
+not the process' own, when there is no process or when superuser
+powers should be extended to prisoned roots.
+.Pp
+By default a process does not command superuser powers if it has
+been imprisoned by the
+.Xr jail 2
+system call.
+There are cases however where this is appropriate, and this can
+be done by setting the
+.Ql PRISON_ROOT
+bit in the flags argument to the
+.Nm suser_xxx
+function. It is important to review carefully in each case that
+this does not weaken the prison. Generally only where the action
+is protected by the
+.Xr chroot 2
+implicit in
+.Xr jail 2
+call should such powers be granted.
.Pp
The
.Nm
-routine notes the fact that superuser powers have been used in the
-word pointed to by the second argument which should be a pointer to
-the p_acflags word of the proc structure. If the second argument is NULL
-then the usage is not noted. Because part of it's function is to notice
+and
+.Nm suser_xxx
+functions notes the fact that superuser powers have been used in the
+process structure of the process specified.
+Because part of its function is to notice
whether super powers have been used,
-.Nm
-should be called after other permission possibilities have been exhausted.
+the functions should only be called after other permission
+possibilities have been exhausted.
.Sh RETURN VALUES
The
.Nm
-function returns 0 if the user has super powers and EPERM otherwise.
+and
+.Nm suser_xxx
+functions returns 0 if the user has super powers and EPERM otherwise.
This is the
.Em reverse logic
of some other implementations of
diff --git a/sys/conf/files b/sys/conf/files
index bbf2f6a07a06..e06b7b2c28fd 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -275,6 +275,7 @@ kern/kern_environment.c standard
kern/kern_exec.c standard
kern/kern_exit.c standard
kern/kern_fork.c standard
+kern/kern_jail.c standard
kern/kern_ktrace.c standard
kern/kern_lock.c standard
kern/kern_lockf.c standard
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 00f576b9fc33..108aab0ffad8 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -1,4 +1,4 @@
-/* $Id: msdosfs_vnops.c,v 1.81 1999/01/27 22:42:09 dillon Exp $ */
+/* $Id: msdosfs_vnops.c,v 1.82 1999/04/27 11:16:51 phk Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */
/*-
@@ -431,7 +431,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return (error);
/*
* We are very inconsistent about handling unsupported
@@ -472,7 +472,7 @@ msdosfs_setattr(ap)
gid = pmp->pm_gid;
if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid ||
(gid != pmp->pm_gid && !groupmember(gid, cred))) &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return error;
if (uid != pmp->pm_uid || gid != pmp->pm_gid)
return EINVAL;
@@ -504,7 +504,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)) &&
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
return (error);
@@ -527,7 +527,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return (error);
if (vp->v_type != VDIR) {
/* We ignore the read and execute bits. */
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h
index 180a47f5ad8b..d9b333bda765 100644
--- a/sys/fs/procfs/procfs.h
+++ b/sys/fs/procfs/procfs.h
@@ -37,7 +37,7 @@
* @(#)procfs.h 8.9 (Berkeley) 5/14/95
*
* From:
- * $Id: procfs.h,v 1.21 1999/01/05 03:53:06 peter Exp $
+ * $Id: procfs.h,v 1.22 1999/04/27 11:16:35 phk Exp $
*/
/*
@@ -92,7 +92,8 @@ struct pfsnode {
* Evaluates to 1 if access is allowed.
*/
#define CHECKIO(p1, p2) \
- ((((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
+ (PRISON_CHECK(p1, p2) && \
+ (((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \
((p2)->p_flag & P_SUGID) == 0) || (suser((p1)) == 0))
diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c
index 3176a6440064..ba1abe42be04 100644
--- a/sys/fs/procfs/procfs_status.c
+++ b/sys/fs/procfs/procfs_status.c
@@ -37,12 +37,13 @@
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*
* From:
- * $Id: procfs_status.c,v 1.11 1998/07/11 07:45:45 bde Exp $
+ * $Id: procfs_status.c,v 1.12 1999/01/05 03:53:06 peter Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/jail.h>
#include <sys/vnode.h>
#include <sys/tty.h>
#include <sys/resourcevar.h>
@@ -134,6 +135,11 @@ procfs_dostatus(curp, p, pfs, uio)
for (i = 0; i < cr->cr_ngroups; i++)
ps += sprintf(ps, ",%lu", (u_long)cr->cr_groups[i]);
+
+ if (p->p_prison)
+ ps += sprintf(ps, " %s", p->p_prison->pr_host);
+ else
+ ps += sprintf(ps, " -");
ps += sprintf(ps, "\n");
xlen = ps - psbuf;
diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c
index ffab3e8a02fa..4f0b8fefb107 100644
--- a/sys/fs/procfs/procfs_vnops.c
+++ b/sys/fs/procfs/procfs_vnops.c
@@ -36,7 +36,7 @@
*
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
*
- * $Id: procfs_vnops.c,v 1.64 1999/01/27 22:42:07 dillon Exp $
+ * $Id: procfs_vnops.c,v 1.65 1999/04/27 11:16:39 phk Exp $
*/
/*
@@ -134,6 +134,8 @@ procfs_open(ap)
p2 = PFIND(pfs->pfs_pid);
if (p2 == NULL)
return (ENOENT);
+ if (!PRISON_CHECK(ap->a_p, p2))
+ return (ENOENT);
switch (pfs->pfs_type) {
case Pmem:
@@ -835,6 +837,8 @@ procfs_readdir(ap)
p = PFIND(pfs->pfs_pid);
if (p == NULL)
break;
+ if (!PRISON_CHECK(curproc, p))
+ break;
for (pt = &proc_targets[i];
uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
@@ -893,7 +897,14 @@ procfs_readdir(ap)
default:
while (pcnt < i) {
+ p = p->p_list.le_next;
+ if (!p)
+ goto done;
+ if (!PRISON_CHECK(curproc, p))
+ continue;
pcnt++;
+ }
+ while (!PRISON_CHECK(curproc, p)) {
p = p->p_list.le_next;
if (!p)
goto done;
diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c
index 9f6a965b7833..c3b1263830f3 100644
--- a/sys/gnu/ext2fs/ext2_vnops.c
+++ b/sys/gnu/ext2fs/ext2_vnops.c
@@ -1157,7 +1157,7 @@ ext2_makeinode(mode, dvp, vpp, cnp)
tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
ip->i_nlink = 1;
if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
- suser_xxx(cnp->cn_cred, NULL))
+ suser_xxx(cnp->cn_cred, 0, PRISON_ROOT))
ip->i_mode &= ~ISGID;
if (cnp->cn_flags & ISWHITEOUT)
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index 9f6a965b7833..c3b1263830f3 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -1157,7 +1157,7 @@ ext2_makeinode(mode, dvp, vpp, cnp)
tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
ip->i_nlink = 1;
if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
- suser_xxx(cnp->cn_cred, NULL))
+ suser_xxx(cnp->cn_cred, 0, PRISON_ROOT))
ip->i_mode &= ~ISGID;
if (cnp->cn_flags & ISWHITEOUT)
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index bf6ec7f4b4eb..ed93f6f5647b 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
- * $Id: init_main.c,v 1.113 1999/04/24 18:50:48 dt Exp $
+ * $Id: init_main.c,v 1.114 1999/04/28 01:04:25 luoqi Exp $
*/
#include "opt_devfs.h"
@@ -409,6 +409,9 @@ proc0_init(dummy)
p->p_ucred = crget();
p->p_ucred->cr_ngroups = 1; /* group 0 */
+ /* Don't jail it */
+ p->p_prison = 0;
+
/* Create procsig. */
p->p_procsig = &procsig0;
p->p_procsig->ps_refcnt = 1;
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 3a8b931d4d54..43b325dbab9c 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -2,7 +2,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+ * created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
*/
#include "opt_compat.h"
@@ -357,4 +357,5 @@ struct sysent sysent[] = {
{ 2, (sy_call_t *)utrace }, /* 335 = utrace */
{ 8, (sy_call_t *)sendfile }, /* 336 = sendfile */
{ 3, (sy_call_t *)kldsym }, /* 337 = kldsym */
+ { 1, (sy_call_t *)jail }, /* 338 = jail */
};
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 0e97656ce99f..fd66be8cad01 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.78 1999/04/17 08:36:04 peter Exp $
+ * $Id: kern_exit.c,v 1.79 1999/04/28 01:04:26 luoqi Exp $
*/
#include "opt_compat.h"
@@ -60,6 +60,7 @@
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/aio.h>
+#include <sys/jail.h>
#ifdef COMPAT_43
#include <machine/reg.h>
@@ -508,6 +509,12 @@ loop:
}
/*
+ * Destroy empty prisons
+ */
+ if (p->p_prison && !--p->p_prison->pr_ref)
+ FREE(p->p_prison, M_PRISON);
+
+ /*
* Finally finished with old proc entry.
* Unlink it from its process group and free it.
*/
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d3f40ea68514..d5870b50494d 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
- * $Id: kern_fork.c,v 1.59 1999/04/24 11:25:01 dt Exp $
+ * $Id: kern_fork.c,v 1.60 1999/04/28 01:04:27 luoqi Exp $
*/
#include "opt_ktrace.h"
@@ -54,6 +54,7 @@
#include <sys/acct.h>
#include <sys/ktrace.h>
#include <sys/unistd.h>
+#include <sys/jail.h>
#include <vm/vm.h>
#include <sys/lock.h>
@@ -308,6 +309,11 @@ again:
p2->p_cred->p_refcnt = 1;
crhold(p1->p_ucred);
+ if (p2->p_prison) {
+ p2->p_prison->pr_ref++;
+ p2->p_flag |= P_JAILED;
+ }
+
if (flags & RFSIGSHARE) {
p2->p_procsig = p1->p_procsig;
p2->p_procsig->ps_refcnt++;
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
new file mode 100644
index 000000000000..20cb89412e38
--- /dev/null
+++ b/sys/kern/kern_jail.c
@@ -0,0 +1,114 @@
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/sysproto.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/jail.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
+
+int
+jail(p, uap)
+ struct proc *p;
+ struct jail_args /* {
+ syscallarg(struct jail *) jail;
+ } */ *uap;
+{
+ int error;
+ struct prison *pr;
+ struct jail j;
+ struct chroot_args ca;
+
+ error = suser(p);
+ if (error)
+ return (error);
+ error = copyin(uap->jail, &j, sizeof j);
+ if (error)
+ return (error);
+ MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
+ bzero((caddr_t)pr, sizeof *pr);
+ error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
+ if (error)
+ goto bail;
+ pr->pr_ip = j.ip_number;
+
+ ca.path = j.path;
+ error = chroot(p, &ca);
+ if (error)
+ goto bail;
+
+ pr->pr_ref++;
+ p->p_prison = pr;
+ p->p_flag |= P_JAILED;
+ return (0);
+
+bail:
+ FREE(pr, M_PRISON);
+ return (error);
+}
+
+int
+prison_ip(struct proc *p, int flag, u_int32_t *ip)
+{
+ u_int32_t tmp;
+
+ if (!p->p_prison)
+ return (0);
+ if (flag)
+ tmp = *ip;
+ else
+ tmp = ntohl(*ip);
+ if (tmp == INADDR_ANY) {
+ if (flag)
+ *ip = p->p_prison->pr_ip;
+ else
+ *ip = htonl(p->p_prison->pr_ip);
+ return (0);
+ }
+ if (p->p_prison->pr_ip != tmp)
+ return (1);
+ return (0);
+}
+
+void
+prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
+{
+ u_int32_t tmp;
+
+ if (!p->p_prison)
+ return;
+ if (flag)
+ tmp = *ip;
+ else
+ tmp = ntohl(*ip);
+ if (tmp == 0x7f000001) {
+ if (flag)
+ *ip = p->p_prison->pr_ip;
+ else
+ *ip = htonl(p->p_prison->pr_ip);
+ return;
+ }
+ return;
+}
+
+int
+prison_if(struct proc *p, struct sockaddr *sa)
+{
+ struct sockaddr_in *sai = (struct sockaddr_in*) sa;
+ int ok;
+
+ if (sai->sin_family != AF_INET)
+ ok = 0;
+ else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
+ ok = 1;
+ else
+ ok = 0;
+ return (ok);
+}
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 7a6d237a8f48..86579cb5caa7 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_ktrace.c 8.2 (Berkeley) 9/23/93
- * $Id: kern_ktrace.c,v 1.24 1998/11/10 09:16:29 peter Exp $
+ * $Id: kern_ktrace.c,v 1.25 1998/12/10 01:47:41 rvb Exp $
*/
#include "opt_ktrace.h"
@@ -515,6 +515,8 @@ ktrcanset(callp, targetp)
register struct pcred *caller = callp->p_cred;
register struct pcred *target = targetp->p_cred;
+ if (!PRISON_CHECK(callp, targetp))
+ return (0);
if ((caller->pc_ucred->cr_uid == target->p_ruid &&
target->p_ruid == target->p_svuid &&
caller->p_rgid == target->p_rgid && /* XXX */
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 9a8f65c46aac..90afa9f38321 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
- * $Id: kern_mib.c,v 1.17 1999/01/25 18:26:09 dillon Exp $
+ * $Id: kern_mib.c,v 1.18 1999/01/26 07:37:11 dillon Exp $
*/
#include <sys/param.h>
@@ -45,6 +45,7 @@
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <sys/jail.h>
#include <sys/unistd.h>
#if defined(SMP)
@@ -73,6 +74,9 @@ SYSCTL_NODE(, CTL_USER, user, CTLFLAG_RW, 0,
SYSCTL_NODE(, CTL_P1003_1B, p1003_1b, CTLFLAG_RW, 0,
"p1003_1b, (see p1003_1b.h)");
+SYSCTL_NODE(_kern, OID_AUTO, prison, CTLFLAG_RW, 0,
+ "Prison rules");
+
SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD, osrelease, 0, "");
SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD, 0, BSD, "");
@@ -124,8 +128,24 @@ SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
char hostname[MAXHOSTNAMELEN];
-SYSCTL_STRING(_kern, KERN_HOSTNAME, hostname, CTLFLAG_RW,
- hostname, sizeof(hostname), "");
+static int
+sysctl_hostname SYSCTL_HANDLER_ARGS
+{
+ int error;
+
+ if (req->p->p_prison)
+ error = sysctl_handle_string(oidp,
+ req->p->p_prison->pr_host,
+ sizeof req->p->p_prison->pr_host, req);
+ else
+ error = sysctl_handle_string(oidp,
+ hostname, sizeof hostname, req);
+ return (error);
+}
+
+SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
+ CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_PRISON,
+ 0, 0, sysctl_hostname, "A", "");
int securelevel = -1;
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index bfb7df99a388..3dfbfab4dcc7 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
- * $Id: kern_proc.c,v 1.45 1999/01/28 00:57:47 dillon Exp $
+ * $Id: kern_proc.c,v 1.46 1999/02/19 14:25:34 luoqi Exp $
*/
#include <sys/param.h>
@@ -500,6 +500,8 @@ sysctl_kern_proc SYSCTL_HANDLER_ARGS
p = pfind((pid_t)name[0]);
if (!p)
return (0);
+ if (!PRISON_CHECK(curproc, p))
+ return (0);
error = sysctl_out_proc(p, req, 0);
return (error);
}
@@ -561,6 +563,9 @@ sysctl_kern_proc SYSCTL_HANDLER_ARGS
break;
}
+ if (!PRISON_CHECK(curproc, p))
+ continue;
+
error = sysctl_out_proc(p, req, doingzomb);
if (error)
return (error);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 56606f42f50b..e4ad6f5c5801 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
- * $Id: kern_prot.c,v 1.45 1999/04/27 11:16:01 phk Exp $
+ * $Id: kern_prot.c,v 1.46 1999/04/27 12:21:06 phk Exp $
*/
/*
@@ -395,7 +395,7 @@ setuid(p, uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */
#endif
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
#ifdef _POSIX_SAVED_IDS
@@ -407,7 +407,7 @@ setuid(p, uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
uid == pc->pc_ucred->cr_uid ||
#endif
- suser(p) == 0) /* we are using privs */
+ suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
#endif
{
/*
@@ -467,7 +467,7 @@ seteuid(p, uap)
euid = uap->euid;
if (euid != pc->p_ruid && /* allow seteuid(getuid()) */
euid != pc->p_svuid && /* allow seteuid(saved uid) */
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
/*
* Everything's okay, do it. Copy credentials so other references do
@@ -515,7 +515,7 @@ setgid(p, uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
#endif
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
#ifdef _POSIX_SAVED_IDS
@@ -527,7 +527,7 @@ setgid(p, uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
gid == pc->pc_ucred->cr_groups[0] ||
#endif
- suser(p) == 0) /* we are using privs */
+ suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
#endif
{
/*
@@ -579,7 +579,7 @@ setegid(p, uap)
egid = uap->egid;
if (egid != pc->p_rgid && /* allow setegid(getgid()) */
egid != pc->p_svgid && /* allow setegid(saved gid) */
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
if (pc->pc_ucred->cr_groups[0] != egid) {
pc->pc_ucred = crcopy(pc->pc_ucred);
@@ -605,7 +605,7 @@ setgroups(p, uap)
register u_int ngrp;
int error;
- if ((error = suser(p)))
+ if ((error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
ngrp = uap->gidsetsize;
if (ngrp > NGROUPS)
@@ -654,7 +654,7 @@ setreuid(p, uap)
if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
(euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
euid != pc->p_ruid && euid != pc->p_svuid)) &&
- (error = suser(p)) != 0)
+ (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
return (error);
if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
@@ -697,7 +697,7 @@ setregid(p, uap)
if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
(egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
egid != pc->p_rgid && egid != pc->p_svgid)) &&
- (error = suser(p)) != 0)
+ (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
return (error);
if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
@@ -769,20 +769,28 @@ int
suser(p)
struct proc *p;
{
- return suser_xxx(p->p_ucred, &p->p_acflag);
+ return suser_xxx(0, p, 0);
}
int
-suser_xxx(cred, acflag)
+suser_xxx(cred, proc, flag)
struct ucred *cred;
- u_short *acflag;
+ struct proc *proc;
+ int flag;
{
- if (cred->cr_uid == 0) {
- if (acflag)
- *acflag |= ASU;
- return (0);
+ if (!cred && !proc) {
+ printf("suser_xxx(): THINK!\n");
+ return (EPERM);
}
- return (EPERM);
+ if (!cred)
+ cred = proc->p_ucred;
+ if (cred->cr_uid != 0)
+ return (EPERM);
+ if (proc && proc->p_prison && !(flag & PRISON_ROOT))
+ return (EPERM);
+ if (proc)
+ proc->p_acflag |= ASU;
+ return (0);
}
/*
@@ -883,7 +891,7 @@ setlogin(p, uap)
int error;
char logintmp[MAXLOGNAME];
- if ((error = suser(p)))
+ if ((error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
sizeof(logintmp), (size_t *)0);
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index bd074110a3e3..811ccf479b5f 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_resource.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_resource.c,v 1.46 1999/04/27 11:16:02 phk Exp $
+ * $Id: kern_resource.c,v 1.47 1999/04/27 12:21:07 phk Exp $
*/
#include "opt_compat.h"
@@ -387,7 +387,7 @@ dosetrlimit(p, which, limp)
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
- if ((error = suser(p)))
+ if ((error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
if (limp->rlim_cur > limp->rlim_max)
limp->rlim_cur = limp->rlim_max;
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 5da472523c66..6749e76f8a28 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
- * $Id: kern_sig.c,v 1.53 1999/01/10 01:58:24 eivind Exp $
+ * $Id: kern_sig.c,v 1.54 1999/01/26 02:38:10 julian Exp $
*/
#include "opt_compat.h"
@@ -79,12 +79,12 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0,
* Can process p, with pcred pc, send the signal signum to process q?
*/
#define CANSIGNAL(p, pc, q, signum) \
- ((pc)->pc_ucred->cr_uid == 0 || \
+ (PRISON_CHECK(p, q) && ((pc)->pc_ucred->cr_uid == 0 || \
(pc)->p_ruid == (q)->p_cred->p_ruid || \
(pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
(pc)->p_ruid == (q)->p_ucred->cr_uid || \
(pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
- ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
+ ((signum) == SIGCONT && (q)->p_session == (p)->p_session)))
/*
* Policy -- Can real uid ruid with ucred uc send a signal to process q?
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index fc0a20489be2..15f53598b0a0 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
- * $Id: kern_sysctl.c,v 1.86 1999/03/30 09:00:45 phk Exp $
+ * $Id: kern_sysctl.c,v 1.87 1999/04/27 11:16:05 phk Exp $
*/
#include "opt_compat.h"
@@ -764,7 +764,8 @@ found:
/* Most likely only root can write */
if (!(oid->oid_kind & CTLFLAG_ANYBODY) &&
req->newptr && req->p &&
- (i = suser(req->p)))
+ (i = suser_xxx(0, req->p,
+ (oid->oid_kind & CTLFLAG_PRISON) ? PRISON_ROOT : 0)))
return (i);
if (!oid->oid_handler)
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c
index 42b563f3ebb8..92b26cee0cea 100644
--- a/sys/kern/kern_xxx.c
+++ b/sys/kern/kern_xxx.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93
- * $Id: kern_xxx.c,v 1.28 1998/08/24 08:39:38 dfr Exp $
+ * $Id: kern_xxx.c,v 1.29 1999/04/27 11:16:09 phk Exp $
*/
#include "opt_compat.h"
@@ -85,7 +85,7 @@ osethostname(p, uap)
name[0] = CTL_KERN;
name[1] = KERN_HOSTNAME;
- if ((error = suser(p)))
+ if ((error = suser_xxx(0, p, PRISON_ROOT)))
return (error);
return (userland_sysctl(p, name, 2, 0, 0, 0,
uap->hostname, uap->len, 0));
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 62e67361993c..6ed8ef1a78f8 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sys_process.c,v 1.43 1999/03/29 08:29:22 dfr Exp $
+ * $Id: sys_process.c,v 1.44 1999/04/27 11:16:13 phk Exp $
*/
#include <sys/param.h>
@@ -218,6 +218,8 @@ ptrace(curp, uap)
if ((p = pfind(uap->pid)) == NULL)
return ESRCH;
}
+ if (!PRISON_CHECK(curp, p))
+ return (ESRCH);
/*
* Permissions check
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index bd4940984292..1359833e8f9f 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -2,7 +2,7 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+ * created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
*/
char *syscallnames[] = {
@@ -344,4 +344,5 @@ char *syscallnames[] = {
"utrace", /* 335 = utrace */
"sendfile", /* 336 = sendfile */
"kldsym", /* 337 = kldsym */
+ "jail", /* 338 = jail */
};
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 292ce700de01..52823bee2c65 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
- * $Id: uipc_usrreq.c,v 1.41 1999/04/11 02:17:47 eivind Exp $
+ * $Id: uipc_usrreq.c,v 1.42 1999/04/12 14:34:52 eivind Exp $
*/
#include <sys/param.h>
@@ -490,6 +490,7 @@ unp_attach(so)
unp_count++;
LIST_INIT(&unp->unp_refs);
unp->unp_socket = so;
+ unp->unp_rvnode = curproc->p_fd->fd_rdir;
LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
: &unp_shead, unp, unp_link);
so->so_pcb = (caddr_t)unp;
@@ -710,6 +711,16 @@ unp_abort(unp)
#endif
static int
+prison_unpcb(struct proc *p, struct unpcb *unp)
+{
+ if (!p->p_prison)
+ return (0);
+ if (p->p_fd->fd_rdir == unp->unp_rvnode)
+ return (0);
+ return (1);
+}
+
+static int
unp_pcblist SYSCTL_HANDLER_ARGS
{
int error, i, n;
@@ -754,7 +765,7 @@ unp_pcblist SYSCTL_HANDLER_ARGS
for (unp = head->lh_first, i = 0; unp && i < n;
unp = unp->unp_link.le_next) {
- if (unp->unp_gencnt <= gencnt)
+ if (unp->unp_gencnt <= gencnt && !prison_unpcb(req->p, unp))
unp_list[i++] = unp;
}
n = i; /* in case we lost some during malloc */
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 43c0bccc1547..dd464d71e493 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
- * $Id: vfs_syscalls.c,v 1.121 1999/03/23 14:26:40 phk Exp $
+ * $Id: vfs_syscalls.c,v 1.122 1999/04/27 11:16:25 phk Exp $
*/
/* For 4.3 integer FS ID compatibility */
@@ -132,7 +132,7 @@ mount(p, uap)
/*
* Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
*/
- if (suser_xxx(p->p_ucred, (u_short *)NULL))
+ if (suser_xxx(p->p_ucred, 0, 0))
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
/*
* Get vnode to be covered
@@ -562,6 +562,12 @@ sync(p, uap)
return (0);
}
+/* XXX PRISON: could be per prison flag */
+static int prison_quotas;
+#if 0
+SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
+#endif
+
/*
* Change filesystem quotas.
*/
@@ -588,6 +594,8 @@ quotactl(p, uap)
int error;
struct nameidata nd;
+ if (p->p_prison && !prison_quotas)
+ return (EPERM);
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
@@ -631,7 +639,7 @@ statfs(p, uap)
if (error)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- if (suser_xxx(p->p_ucred, (u_short *)NULL)) {
+ if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
@@ -671,7 +679,7 @@ fstatfs(p, uap)
if (error)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- if (suser_xxx(p->p_ucred, (u_short *)NULL)) {
+ if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
@@ -886,7 +894,7 @@ chroot(p, uap)
int error;
struct nameidata nd;
- error = suser(p);
+ error = suser_xxx(0, p, PRISON_ROOT);
if (error)
return (error);
if (chroot_allow_open_directories == 0 ||
@@ -1076,7 +1084,15 @@ mknod(p, uap)
int whiteout = 0;
struct nameidata nd;
- error = suser(p);
+ switch (SCARG(uap, mode) & S_IFMT) {
+ case S_IFCHR:
+ case S_IFBLK:
+ error = suser(p);
+ break;
+ default:
+ error = suser_xxx(0, p, PRISON_ROOT);
+ break;
+ }
if (error)
return (error);
NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
@@ -2977,7 +2993,7 @@ revoke(p, uap)
if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
goto out;
if (p->p_ucred->cr_uid != vattr.va_uid &&
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
VOP_REVOKE(vp, REVOKEALL);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 43c0bccc1547..dd464d71e493 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
- * $Id: vfs_syscalls.c,v 1.121 1999/03/23 14:26:40 phk Exp $
+ * $Id: vfs_syscalls.c,v 1.122 1999/04/27 11:16:25 phk Exp $
*/
/* For 4.3 integer FS ID compatibility */
@@ -132,7 +132,7 @@ mount(p, uap)
/*
* Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
*/
- if (suser_xxx(p->p_ucred, (u_short *)NULL))
+ if (suser_xxx(p->p_ucred, 0, 0))
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
/*
* Get vnode to be covered
@@ -562,6 +562,12 @@ sync(p, uap)
return (0);
}
+/* XXX PRISON: could be per prison flag */
+static int prison_quotas;
+#if 0
+SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
+#endif
+
/*
* Change filesystem quotas.
*/
@@ -588,6 +594,8 @@ quotactl(p, uap)
int error;
struct nameidata nd;
+ if (p->p_prison && !prison_quotas)
+ return (EPERM);
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
@@ -631,7 +639,7 @@ statfs(p, uap)
if (error)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- if (suser_xxx(p->p_ucred, (u_short *)NULL)) {
+ if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
@@ -671,7 +679,7 @@ fstatfs(p, uap)
if (error)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- if (suser_xxx(p->p_ucred, (u_short *)NULL)) {
+ if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
@@ -886,7 +894,7 @@ chroot(p, uap)
int error;
struct nameidata nd;
- error = suser(p);
+ error = suser_xxx(0, p, PRISON_ROOT);
if (error)
return (error);
if (chroot_allow_open_directories == 0 ||
@@ -1076,7 +1084,15 @@ mknod(p, uap)
int whiteout = 0;
struct nameidata nd;
- error = suser(p);
+ switch (SCARG(uap, mode) & S_IFMT) {
+ case S_IFCHR:
+ case S_IFBLK:
+ error = suser(p);
+ break;
+ default:
+ error = suser_xxx(0, p, PRISON_ROOT);
+ break;
+ }
if (error)
return (error);
NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
@@ -2977,7 +2993,7 @@ revoke(p, uap)
if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
goto out;
if (p->p_ucred->cr_uid != vattr.va_uid &&
- (error = suser(p)))
+ (error = suser_xxx(0, p, PRISON_ROOT)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
VOP_REVOKE(vp, REVOKEALL);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 802c43718934..0300ba5adfe0 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
- * $Id: vfs_vnops.c,v 1.66 1999/04/21 05:56:45 alc Exp $
+ * $Id: vfs_vnops.c,v 1.67 1999/04/27 11:16:27 phk Exp $
*/
#include <sys/param.h>
@@ -422,7 +422,7 @@ vn_stat(vp, sb, p)
sb->st_ctimespec = vap->va_ctime;
sb->st_blksize = vap->va_blocksize;
sb->st_flags = vap->va_flags;
- if (suser_xxx(p->p_ucred, (u_short *)NULL))
+ if (suser_xxx(p->p_ucred, 0, 0))
sb->st_gen = 0;
else
sb->st_gen = vap->va_gen;
diff --git a/sys/miscfs/devfs/devfs_vnops.c b/sys/miscfs/devfs/devfs_vnops.c
index 64387e6bd29f..b924ef5de4fc 100644
--- a/sys/miscfs/devfs/devfs_vnops.c
+++ b/sys/miscfs/devfs/devfs_vnops.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: devfs_vnops.c,v 1.70 1999/02/25 16:06:51 bde Exp $
+ * $Id: devfs_vnops.c,v 1.71 1999/04/27 11:16:31 phk Exp $
*/
@@ -381,7 +381,7 @@ found:
* but only use suser_xxx prives as a last resort
* (Use of super powers is recorded in ap->a_p->p_acflag)
*/
- if( suser_xxx(cred, &ap->a_p->p_acflag) == 0) /* XXX what if no proc? */
+ if( suser_xxx(cred, ap->a_p, 0) == 0) /* XXX what if no proc? */
return 0;
return (EACCES);
}
@@ -519,7 +519,7 @@ DBPRINT(("setattr\n"));
#endif
if (((vap->va_vaflags & VA_UTIMES_NULL) == 0) &&
(cred->cr_uid != file_node->uid) &&
- suser_xxx(cred, &p->p_acflag))
+ suser_xxx(cred, p, 0))
return (EPERM);
if(VOP_ACCESS(vp, VWRITE, cred, p))
return (EACCES);
@@ -534,7 +534,7 @@ DBPRINT(("setattr\n"));
*/
if (vap->va_mode != (u_short)VNOVAL) {
if ((cred->cr_uid != file_node->uid)
- && suser_xxx(cred, &p->p_acflag))
+ && suser_xxx(cred, p, 0))
return (EPERM);
/* set drwxwxrwx stuff */
file_node->mode &= ~07777;
@@ -545,7 +545,7 @@ DBPRINT(("setattr\n"));
* Change the owner.. must be root to do this.
*/
if (vap->va_uid != (uid_t)VNOVAL) {
- if (suser_xxx(cred, &p->p_acflag))
+ if (suser_xxx(cred, p, 0))
return (EPERM);
file_node->uid = vap->va_uid;
}
@@ -568,7 +568,7 @@ DBPRINT(("setattr\n"));
* we can't do it with normal privs,
* do we have an ace up our sleeve?
*/
- if( suser_xxx(cred, &p->p_acflag))
+ if( suser_xxx(cred, p, 0))
return (EPERM);
cando:
file_node->gid = vap->va_gid;
@@ -580,7 +580,7 @@ cando:
* flags should be handled some day
*/
if (vap->va_flags != VNOVAL) {
- if (error = suser_xxx(cred, &p->p_acflag))
+ if (error = suser_xxx(cred, p, 0))
return error;
if (cred->cr_uid == 0)
;
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h
index 180a47f5ad8b..d9b333bda765 100644
--- a/sys/miscfs/procfs/procfs.h
+++ b/sys/miscfs/procfs/procfs.h
@@ -37,7 +37,7 @@
* @(#)procfs.h 8.9 (Berkeley) 5/14/95
*
* From:
- * $Id: procfs.h,v 1.21 1999/01/05 03:53:06 peter Exp $
+ * $Id: procfs.h,v 1.22 1999/04/27 11:16:35 phk Exp $
*/
/*
@@ -92,7 +92,8 @@ struct pfsnode {
* Evaluates to 1 if access is allowed.
*/
#define CHECKIO(p1, p2) \
- ((((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
+ (PRISON_CHECK(p1, p2) && \
+ (((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \
((p2)->p_flag & P_SUGID) == 0) || (suser((p1)) == 0))
diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c
index 3176a6440064..ba1abe42be04 100644
--- a/sys/miscfs/procfs/procfs_status.c
+++ b/sys/miscfs/procfs/procfs_status.c
@@ -37,12 +37,13 @@
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*
* From:
- * $Id: procfs_status.c,v 1.11 1998/07/11 07:45:45 bde Exp $
+ * $Id: procfs_status.c,v 1.12 1999/01/05 03:53:06 peter Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/jail.h>
#include <sys/vnode.h>
#include <sys/tty.h>
#include <sys/resourcevar.h>
@@ -134,6 +135,11 @@ procfs_dostatus(curp, p, pfs, uio)
for (i = 0; i < cr->cr_ngroups; i++)
ps += sprintf(ps, ",%lu", (u_long)cr->cr_groups[i]);
+
+ if (p->p_prison)
+ ps += sprintf(ps, " %s", p->p_prison->pr_host);
+ else
+ ps += sprintf(ps, " -");
ps += sprintf(ps, "\n");
xlen = ps - psbuf;
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index ffab3e8a02fa..4f0b8fefb107 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -36,7 +36,7 @@
*
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
*
- * $Id: procfs_vnops.c,v 1.64 1999/01/27 22:42:07 dillon Exp $
+ * $Id: procfs_vnops.c,v 1.65 1999/04/27 11:16:39 phk Exp $
*/
/*
@@ -134,6 +134,8 @@ procfs_open(ap)
p2 = PFIND(pfs->pfs_pid);
if (p2 == NULL)
return (ENOENT);
+ if (!PRISON_CHECK(ap->a_p, p2))
+ return (ENOENT);
switch (pfs->pfs_type) {
case Pmem:
@@ -835,6 +837,8 @@ procfs_readdir(ap)
p = PFIND(pfs->pfs_pid);
if (p == NULL)
break;
+ if (!PRISON_CHECK(curproc, p))
+ break;
for (pt = &proc_targets[i];
uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
@@ -893,7 +897,14 @@ procfs_readdir(ap)
default:
while (pcnt < i) {
+ p = p->p_list.le_next;
+ if (!p)
+ goto done;
+ if (!PRISON_CHECK(curproc, p))
+ continue;
pcnt++;
+ }
+ while (!PRISON_CHECK(curproc, p)) {
p = p->p_list.le_next;
if (!p)
goto done;
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
index 00f576b9fc33..108aab0ffad8 100644
--- a/sys/msdosfs/msdosfs_vnops.c
+++ b/sys/msdosfs/msdosfs_vnops.c
@@ -1,4 +1,4 @@
-/* $Id: msdosfs_vnops.c,v 1.81 1999/01/27 22:42:09 dillon Exp $ */
+/* $Id: msdosfs_vnops.c,v 1.82 1999/04/27 11:16:51 phk Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */
/*-
@@ -431,7 +431,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return (error);
/*
* We are very inconsistent about handling unsupported
@@ -472,7 +472,7 @@ msdosfs_setattr(ap)
gid = pmp->pm_gid;
if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid ||
(gid != pmp->pm_gid && !groupmember(gid, cred))) &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return error;
if (uid != pmp->pm_uid || gid != pmp->pm_gid)
return EINVAL;
@@ -504,7 +504,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)) &&
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
return (error);
@@ -527,7 +527,7 @@ msdosfs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, &ap->a_p->p_acflag)))
+ (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
return (error);
if (vp->v_type != VDIR) {
/* We ignore the read and execute bits. */
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 0c37a7a02172..5b6dd2f2f641 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -37,7 +37,7 @@
*
* @(#)bpf.c 8.2 (Berkeley) 3/28/94
*
- * $Id: bpf.c,v 1.47 1999/01/27 22:42:13 dillon Exp $
+ * $Id: bpf.c,v 1.48 1999/04/28 01:18:13 msmith Exp $
*/
#include "bpfilter.h"
@@ -346,6 +346,9 @@ bpfopen(dev, flags, fmt, p)
{
register struct bpf_d *d;
+ if (p->p_prison)
+ return (EPERM);
+
if (minor(dev) >= NBPFILTER)
return (ENXIO);
/*
@@ -1014,12 +1017,12 @@ bpfpoll(dev, events, p)
d = &bpf_dtab[minor(dev)];
s = splimp();
- if (events & (POLLIN | POLLRDNORM))
+ if (events & (POLLIN | POLLRDNORM)) {
if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(p, &d->bd_sel);
-
+ }
splx(s);
return (revents);
}
diff --git a/sys/net/if.c b/sys/net/if.c
index bb36fa4b976d..e91445e945ac 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if.c 8.3 (Berkeley) 1/4/94
- * $Id: if.c,v 1.68 1999/04/26 09:02:40 peter Exp $
+ * $Id: if.c,v 1.69 1999/04/27 11:16:56 phk Exp $
*/
#include "opt_compat.h"
@@ -857,7 +857,7 @@ ifconf(cmd, data)
ifrp = ifc->ifc_req;
for (; space > sizeof (ifr) && ifp; ifp = ifp->if_link.tqe_next) {
char workbuf[64];
- int ifnlen;
+ int ifnlen, addrs;
ifnlen = snprintf(workbuf, sizeof(workbuf),
"%s%d", ifp->if_name, ifp->if_unit);
@@ -867,17 +867,14 @@ ifconf(cmd, data)
strcpy(ifr.ifr_name, workbuf);
}
- if ((ifa = ifp->if_addrhead.tqh_first) == 0) {
- bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
- error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
- sizeof (ifr));
- if (error)
- break;
- space -= sizeof (ifr), ifrp++;
- } else
- for ( ; space > sizeof (ifr) && ifa;
- ifa = ifa->ifa_link.tqe_next) {
+ addrs = 0;
+ ifa = ifp->if_addrhead.tqh_first;
+ for ( ; space > sizeof (ifr) && ifa;
+ ifa = ifa->ifa_link.tqe_next) {
register struct sockaddr *sa = ifa->ifa_addr;
+ if (curproc->p_prison && prison_if(curproc, sa))
+ continue;
+ addrs++;
#ifdef COMPAT_43
if (cmd == OSIOCGIFCONF) {
struct osockaddr *osa =
@@ -910,6 +907,14 @@ ifconf(cmd, data)
break;
space -= sizeof (ifr);
}
+ if (!addrs) {
+ bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
+ error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
+ sizeof (ifr));
+ if (error)
+ break;
+ space -= sizeof (ifr), ifrp++;
+ }
}
ifc->ifc_len -= space;
return (error);
diff --git a/sys/net/if.h b/sys/net/if.h
index e4f0046a99ef..4ca06612d1df 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if.h 8.1 (Berkeley) 6/10/93
- * $Id: if.h,v 1.49 1998/03/21 13:36:20 peter Exp $
+ * $Id: if.h,v 1.50 1999/02/19 13:41:35 phk Exp $
*/
#ifndef _NET_IF_H_
@@ -221,6 +221,7 @@ MALLOC_DECLARE(M_IFMADDR);
/* XXX - this should go away soon */
#ifdef KERNEL
+int prison_if __P((struct proc *p, struct sockaddr *sa));
#include <net/if_var.h>
#endif
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index bf5da6e18d4d..a57b518b2785 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)rtsock.c 8.5 (Berkeley) 11/2/94
- * $Id: rtsock.c,v 1.37 1997/10/31 08:53:13 davidg Exp $
+ * $Id: rtsock.c,v 1.38 1999/01/27 22:42:14 dillon Exp $
*/
@@ -911,6 +911,8 @@ sysctl_iflist(af, w)
while ((ifa = ifa->ifa_link.tqe_next) != 0) {
if (af && af != ifa->ifa_addr->sa_family)
continue;
+ if (curproc->p_prison && prison_if(curproc, ifa->ifa_addr))
+ continue;
ifaaddr = ifa->ifa_addr;
netmask = ifa->ifa_netmask;
brdaddr = ifa->ifa_dstaddr;
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 1542e247165b..0fe16f4c72d4 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in.h 8.3 (Berkeley) 1/3/94
- * $Id: in.h,v 1.38 1998/12/14 18:09:13 luigi Exp $
+ * $Id: in.h,v 1.39 1999/04/20 13:32:04 peter Exp $
*/
#ifndef _NETINET_IN_H_
@@ -433,6 +433,9 @@ int in_cksum __P((struct mbuf *, int));
int in_localaddr __P((struct in_addr));
char *inet_ntoa __P((struct in_addr)); /* in libkern */
+int prison_ip __P((struct proc *p, int flag, u_int32_t *ip));
+void prison_remote_ip __P((struct proc *p, int flag, u_int32_t *ip));
+
#endif /* KERNEL */
#endif
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 7788c9b13d14..2f13bf173fca 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in_pcb.c 8.4 (Berkeley) 5/24/95
- * $Id: in_pcb.c,v 1.47 1999/01/27 22:42:24 dillon Exp $
+ * $Id: in_pcb.c,v 1.48 1999/04/27 11:17:31 phk Exp $
*/
#include <sys/param.h>
@@ -42,6 +42,7 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/proc.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -154,7 +155,7 @@ in_pcbbind(inp, nam, p)
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
u_short lport = 0;
int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
- int error;
+ int error, prison = 0;
if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */
return (EADDRNOTAVAIL);
@@ -174,6 +175,8 @@ in_pcbbind(inp, nam, p)
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
#endif
+ if (prison_ip(p, 0, &sin->sin_addr.s_addr))
+ return(EINVAL);
lport = sin->sin_port;
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
/*
@@ -195,12 +198,15 @@ in_pcbbind(inp, nam, p)
/* GROSS */
if (ntohs(lport) < IPPORT_RESERVED && p &&
- suser(p))
+ suser_xxx(0, p, PRISON_ROOT))
return (EACCES);
+ if (p && p->p_prison)
+ prison = 1;
if (so->so_uid &&
!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
t = in_pcblookup_local(inp->inp_pcbinfo,
- sin->sin_addr, lport, INPLOOKUP_WILDCARD);
+ sin->sin_addr, lport,
+ prison ? 0 : INPLOOKUP_WILDCARD);
if (t &&
(ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
@@ -210,7 +216,7 @@ in_pcbbind(inp, nam, p)
return (EADDRINUSE);
}
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
- lport, wild);
+ lport, prison ? 0 : wild);
if (t && (reuseport & t->inp_socket->so_options) == 0)
return (EADDRINUSE);
}
@@ -220,6 +226,8 @@ in_pcbbind(inp, nam, p)
ushort first, last;
int count;
+ if (prison_ip(p, 0, &inp->inp_laddr.s_addr ))
+ return (EINVAL);
inp->inp_flags |= INP_ANONPORT;
if (inp->inp_flags & INP_HIGHPORT) {
@@ -227,7 +235,7 @@ in_pcbbind(inp, nam, p)
last = ipport_hilastauto;
lastport = &pcbinfo->lasthi;
} else if (inp->inp_flags & INP_LOWPORT) {
- if (p && (error = suser(p)))
+ if (p && (error = suser_xxx(0, p, PRISON_ROOT)))
return error;
first = ipport_lowfirstauto; /* 1023 */
last = ipport_lowlastauto; /* 600 */
@@ -895,3 +903,13 @@ in_pcbremlists(inp)
LIST_REMOVE(inp, inp_list);
inp->inp_pcbinfo->ipi_count--;
}
+
+int
+prison_xinpcb(struct proc *p, struct inpcb *inp)
+{
+ if (!p->p_prison)
+ return (0);
+ if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip)
+ return (0);
+ return (1);
+}
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index aa2d0bec301f..33d8d7a73dcf 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in_pcb.h 8.1 (Berkeley) 6/10/93
- * $Id: in_pcb.h,v 1.25 1998/03/28 10:18:22 bde Exp $
+ * $Id: in_pcb.h,v 1.26 1998/05/15 20:11:33 wollman Exp $
*/
#ifndef _NETINET_IN_PCB_H_
@@ -168,6 +168,7 @@ void in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
void in_pcbrehash __P((struct inpcb *));
int in_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
int in_setsockaddr __P((struct socket *so, struct sockaddr **nam));
+int prison_xinpcb __P((struct proc *p, struct inpcb *inp));
#endif /* KERNEL */
#endif /* !_NETINET_IN_PCB_H_ */
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index b9355da79509..ed0acd4944c9 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
- * $Id: tcp_subr.c,v 1.51 1999/02/04 03:02:56 msmith Exp $
+ * $Id: tcp_subr.c,v 1.52 1999/02/04 03:27:43 msmith Exp $
*/
#include "opt_compat.h"
@@ -541,7 +541,7 @@ tcp_pcblist SYSCTL_HANDLER_ARGS
s = splnet();
for (inp = tcbinfo.listhead->lh_first, i = 0; inp && i < n;
inp = inp->inp_list.le_next) {
- if (inp->inp_gencnt <= gencnt)
+ if (inp->inp_gencnt <= gencnt && !prison_xinpcb(req->p, inp))
inp_list[i++] = inp;
}
splx(s);
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index b9355da79509..ed0acd4944c9 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
- * $Id: tcp_subr.c,v 1.51 1999/02/04 03:02:56 msmith Exp $
+ * $Id: tcp_subr.c,v 1.52 1999/02/04 03:27:43 msmith Exp $
*/
#include "opt_compat.h"
@@ -541,7 +541,7 @@ tcp_pcblist SYSCTL_HANDLER_ARGS
s = splnet();
for (inp = tcbinfo.listhead->lh_first, i = 0; inp && i < n;
inp = inp->inp_list.le_next) {
- if (inp->inp_gencnt <= gencnt)
+ if (inp->inp_gencnt <= gencnt && !prison_xinpcb(req->p, inp))
inp_list[i++] = inp;
}
splx(s);
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 5d231c996b68..02a281f1182c 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
- * $Id: tcp_usrreq.c,v 1.40 1999/01/20 17:31:59 fenner Exp $
+ * $Id: tcp_usrreq.c,v 1.41 1999/04/24 18:25:35 ache Exp $
*/
#include "opt_tcpdebug.h"
@@ -239,6 +239,8 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
goto out;
}
+ prison_remote_ip(p, 0, &sinp->sin_addr.s_addr);
+
if ((error = tcp_connect(tp, nam, p)) != 0)
goto out;
error = tcp_output(tp);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 3462c70908d3..7fc09d2cdaac 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
- * $Id: udp_usrreq.c,v 1.48 1998/08/24 07:47:39 dfr Exp $
+ * $Id: udp_usrreq.c,v 1.49 1998/12/03 20:23:21 dillon Exp $
*/
#include <sys/param.h>
@@ -410,7 +410,7 @@ udp_pcblist SYSCTL_HANDLER_ARGS
s = splnet();
for (inp = udbinfo.listhead->lh_first, i = 0; inp && i < n;
inp = inp->inp_list.le_next) {
- if (inp->inp_gencnt <= gencnt)
+ if (inp->inp_gencnt <= gencnt && !prison_xinpcb(req->p, inp))
inp_list[i++] = inp;
}
splx(s);
@@ -462,6 +462,7 @@ udp_output(inp, m, addr, control, p)
register struct udpiphdr *ui;
register int len = m->m_pkthdr.len;
struct in_addr laddr;
+ struct sockaddr_in *sin;
int s = 0, error = 0;
if (control)
@@ -473,6 +474,8 @@ udp_output(inp, m, addr, control, p)
}
if (addr) {
+ sin = (struct sockaddr_in *)addr;
+ prison_remote_ip(p, 0, &sin->sin_addr.s_addr);
laddr = inp->inp_laddr;
if (inp->inp_faddr.s_addr != INADDR_ANY) {
error = EISCONN;
@@ -614,6 +617,7 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
{
struct inpcb *inp;
int s, error;
+ struct sockaddr_in *sin;
inp = sotoinpcb(so);
if (inp == 0)
@@ -621,6 +625,8 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
if (inp->inp_faddr.s_addr != INADDR_ANY)
return EISCONN;
s = splnet();
+ sin = (struct sockaddr_in *)nam;
+ prison_remote_ip(p, 0, &sin->sin_addr.s_addr);
error = in_pcbconnect(inp, nam, p);
splx(s);
if (error == 0)
diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c
index d60f2652e014..63e8e39732ad 100644
--- a/sys/nfs/nfs_serv.c
+++ b/sys/nfs/nfs_serv.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
- * $Id: nfs_serv.c,v 1.73 1999/02/16 10:49:53 dfr Exp $
+ * $Id: nfs_serv.c,v 1.74 1999/04/27 11:17:49 phk Exp $
*/
/*
@@ -1445,7 +1445,7 @@ nfsrv_create(nfsd, slp, procp, mrq)
if (vap->va_type == VCHR && rdev == 0xffffffff)
vap->va_type = VFIFO;
if (vap->va_type != VFIFO &&
- (error = suser_xxx(cred, (u_short *)0))) {
+ (error = suser_xxx(cred, 0, 0))) {
vrele(nd.ni_startdir);
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
@@ -1642,7 +1642,7 @@ nfsrv_mknod(nfsd, slp, procp, mrq)
if (!error)
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
} else {
- if (vtyp != VFIFO && (error = suser_xxx(cred, (u_short *)0))) {
+ if (vtyp != VFIFO && (error = suser_xxx(cred, 0, 0))) {
vrele(nd.ni_startdir);
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index d60f2652e014..63e8e39732ad 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
- * $Id: nfs_serv.c,v 1.73 1999/02/16 10:49:53 dfr Exp $
+ * $Id: nfs_serv.c,v 1.74 1999/04/27 11:17:49 phk Exp $
*/
/*
@@ -1445,7 +1445,7 @@ nfsrv_create(nfsd, slp, procp, mrq)
if (vap->va_type == VCHR && rdev == 0xffffffff)
vap->va_type = VFIFO;
if (vap->va_type != VFIFO &&
- (error = suser_xxx(cred, (u_short *)0))) {
+ (error = suser_xxx(cred, 0, 0))) {
vrele(nd.ni_startdir);
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
@@ -1642,7 +1642,7 @@ nfsrv_mknod(nfsd, slp, procp, mrq)
if (!error)
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
} else {
- if (vtyp != VFIFO && (error = suser_xxx(cred, (u_short *)0))) {
+ if (vtyp != VFIFO && (error = suser_xxx(cred, 0, 0))) {
vrele(nd.ni_startdir);
zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
new file mode 100644
index 000000000000..aea9bf586e38
--- /dev/null
+++ b/sys/sys/jail.h
@@ -0,0 +1,41 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: loran.c,v 1.15 1999/04/11 03:06:06 eivind Exp $
+ *
+ */
+
+#ifndef _SYS_JAIL_H_
+#define _SYS_JAIL_H_
+
+struct jail {
+ char *path;
+ char *hostname;
+ u_int32_t ip_number;
+};
+
+#ifdef KERNEL
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_PRISON);
+#endif
+
+/*
+ * This structure describes a prison. It is pointed to by all struct
+ * proc's of the inmates. pr_ref keeps track of them and is used to
+ * delete the struture when the last inmate is dead.
+ */
+
+struct prison {
+ int pr_ref;
+ char pr_host[MAXHOSTNAMELEN];
+ u_int32_t pr_ip;
+};
+
+#endif /* !KERNEL */
+#endif /* !_SYS_JAIL_H_ */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 12b809b7520f..9030584513d4 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.15 (Berkeley) 5/19/95
- * $Id: proc.h,v 1.79 1999/04/27 11:18:32 phk Exp $
+ * $Id: proc.h,v 1.80 1999/04/28 01:04:33 luoqi Exp $
*/
#ifndef _SYS_PROC_H_
@@ -107,6 +107,9 @@ struct pasleep {
* which might be addressable only on a processor on which the process
* is running.
*/
+
+struct jail;
+
struct proc {
TAILQ_ENTRY(proc) p_procq; /* run/sleep queue. */
LIST_ENTRY(proc) p_list; /* List of all processes. */
@@ -206,6 +209,7 @@ struct proc {
struct sysentvec *p_sysent; /* System call dispatch information. */
struct rtprio p_rtprio; /* Realtime priority. */
+ struct prison *p_prison;
/* End area that is copied on creation. */
#define p_endcopy p_addr
struct user *p_addr; /* Kernel virtual addr of u-area (PROC ONLY). */
@@ -268,6 +272,8 @@ struct proc {
#define P_NOCLDWAIT 0x400000 /* No zombies if child dies */
#define P_DEADLKTREAT 0x800000 /* lock aquisition - deadlock treatment */
+#define P_JAILED 0x1000000 /* Process is in jail */
+
/*
* MOVE TO ucred.h?
*
@@ -292,6 +298,14 @@ MALLOC_DECLARE(M_SUBPROC);
MALLOC_DECLARE(M_ZOMBIE);
#endif
+/* flags for suser_xxx() */
+#define PRISON_ROOT 1
+
+/* Handy macro to determine of p1 can mangle p2 */
+
+#define PRISON_CHECK(p1, p2) \
+ ((!(p1)->p_prison) || (p1)->p_prison == (p2)->p_prison)
+
/*
* We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t,
* as it is used to represent "no process group".
@@ -376,6 +390,7 @@ void setrunnable __P((struct proc *));
void setrunqueue __P((struct proc *));
void sleepinit __P((void));
int suser __P((struct proc *));
+int suser_xxx __P((struct ucred *cred, struct proc *proc, int flag));
void remrq __P((struct proc *));
void cpu_switch __P((struct proc *));
void unsleep __P((struct proc *));
diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h
index e7feea16d933..cba0b9d2864c 100644
--- a/sys/sys/syscall-hide.h
+++ b/sys/sys/syscall-hide.h
@@ -2,7 +2,7 @@
* System call hiders.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+ * created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
*/
HIDE_POSIX(fork)
@@ -251,3 +251,4 @@ HIDE_POSIX(sched_rr_get_interval)
HIDE_BSD(utrace)
HIDE_BSD(sendfile)
HIDE_BSD(kldsym)
+HIDE_BSD(jail)
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index f20a43d80ae0..79441f1d6d18 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -2,7 +2,7 @@
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+ * created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
*/
#define SYS_syscall 0
@@ -257,4 +257,5 @@
#define SYS_utrace 335
#define SYS_sendfile 336
#define SYS_kldsym 337
-#define SYS_MAXSYSCALL 338
+#define SYS_jail 338
+#define SYS_MAXSYSCALL 339
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index 732435c49c36..832bb160ed94 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -1,6 +1,6 @@
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
-# created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+# created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
MIASM = \
syscall.o \
exit.o \
@@ -212,4 +212,5 @@ MIASM = \
sched_rr_get_interval.o \
utrace.o \
sendfile.o \
- kldsym.o
+ kldsym.o \
+ jail.o
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 003222b93508..0f949d87487a 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)sysctl.h 8.1 (Berkeley) 6/2/93
- * $Id: sysctl.h,v 1.71 1999/02/16 10:49:55 dfr Exp $
+ * $Id: sysctl.h,v 1.72 1999/02/28 17:38:28 dt Exp $
*/
#ifndef _SYS_SYSCTL_H_
@@ -79,6 +79,7 @@ struct ctlname {
#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */
#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
+#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
/*
* USE THIS instead of a hardwired number from the categories below
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 7c18bd18ba87..43666d8cee64 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -2,7 +2,7 @@
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.57 1999/04/04 21:41:16 dt Exp
+ * created from Id: syscalls.master,v 1.58 1999/04/28 11:28:49 phk Exp
*/
#ifndef _SYS_SYSPROTO_H_
@@ -907,6 +907,9 @@ struct kldsym_args {
int cmd; char cmd_[PAD_(int)];
void * data; char data_[PAD_(void *)];
};
+struct jail_args {
+ struct jail * jail; char jail_[PAD_(struct jail *)];
+};
int nosys __P((struct proc *, struct nosys_args *));
void exit __P((struct proc *, struct rexit_args *)) __dead2;
int fork __P((struct proc *, struct fork_args *));
@@ -1116,6 +1119,7 @@ int sched_rr_get_interval __P((struct proc *, struct sched_rr_get_interval_args
int utrace __P((struct proc *, struct utrace_args *));
int sendfile __P((struct proc *, struct sendfile_args *));
int kldsym __P((struct proc *, struct kldsym_args *));
+int jail __P((struct proc *, struct jail_args *));
#ifdef COMPAT_43
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index d95b0d871bd7..f65dbe05f0c9 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ucred.h 8.4 (Berkeley) 1/9/95
- * $Id: ucred.h,v 1.10 1999/01/31 10:05:59 bde Exp $
+ * $Id: ucred.h,v 1.11 1999/04/27 11:18:38 phk Exp $
*/
#ifndef _SYS_UCRED_H_
@@ -41,7 +41,7 @@
* Credentials.
*
* Please do not inspect cr_uid directly to determine superuserness.
- * Only the suser_xxx() function should be used for this.
+ * Only the suser()/suser_xxx() function should be used for this.
*/
struct ucred {
u_short cr_ref; /* reference count */
@@ -60,7 +60,6 @@ struct ucred *crcopy __P((struct ucred *cr));
struct ucred *crdup __P((struct ucred *cr));
void crfree __P((struct ucred *cr));
struct ucred *crget __P((void));
-int suser_xxx __P((struct ucred *cred, u_short *acflag));
int groupmember __P((gid_t gid, struct ucred *cred));
#endif /* KERNEL */
diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h
index 14191537f059..7c3881267ef8 100644
--- a/sys/sys/unpcb.h
+++ b/sys/sys/unpcb.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)unpcb.h 8.1 (Berkeley) 6/2/93
- * $Id: unpcb.h,v 1.6 1997/08/16 19:16:16 wollman Exp $
+ * $Id: unpcb.h,v 1.7 1998/05/15 20:11:40 wollman Exp $
*/
#ifndef _SYS_UNPCB_H_
@@ -71,6 +71,7 @@ struct unpcb {
LIST_ENTRY(unpcb) unp_link; /* glue on list of all PCBs */
struct socket *unp_socket; /* pointer back to socket */
struct vnode *unp_vnode; /* if associated with file */
+ struct vnode *unp_rvnode; /* root vp for creating process */
ino_t unp_ino; /* fake inode number */
struct unpcb *unp_conn; /* control block of connected socket */
struct unp_head unp_refs; /* referencing socket linked list */
diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c
index d9333b2af13a..55eb12db35ef 100644
--- a/sys/ufs/ufs/ufs_vfsops.c
+++ b/sys/ufs/ufs/ufs_vfsops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vfsops.c 8.8 (Berkeley) 5/20/95
- * $Id: ufs_vfsops.c,v 1.13 1999/01/28 00:57:56 dillon Exp $
+ * $Id: ufs_vfsops.c,v 1.14 1999/04/27 11:18:43 phk Exp $
*/
#include "opt_quota.h"
@@ -115,7 +115,7 @@ ufs_quotactl(mp, cmds, uid, arg, p)
break;
/* fall through */
default:
- if ((error = suser(p)) != 0)
+ if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0)
return (error);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index f2a085956c3c..411f2fefd4b0 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
- * $Id: ufs_vnops.c,v 1.111 1999/03/02 05:31:47 imp Exp $
+ * $Id: ufs_vnops.c,v 1.112 1999/04/27 11:18:44 phk Exp $
*/
#include "opt_quota.h"
@@ -448,7 +448,7 @@ ufs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != ip->i_uid &&
- (error = suser_xxx(cred, &p->p_acflag)))
+ (error = suser_xxx(cred, p, PRISON_ROOT)))
return (error);
if (cred->cr_uid == 0) {
if ((ip->i_flags
@@ -504,7 +504,7 @@ ufs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
if (cred->cr_uid != ip->i_uid &&
- (error = suser_xxx(cred, &p->p_acflag)) &&
+ (error = suser_xxx(cred, p, PRISON_ROOT)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, p))))
return (error);
@@ -546,7 +546,7 @@ ufs_chmod(vp, mode, cred, p)
int error;
if (cred->cr_uid != ip->i_uid) {
- error = suser_xxx(cred, &p->p_acflag);
+ error = suser_xxx(cred, p, PRISON_ROOT);
if (error)
return (error);
}
@@ -594,7 +594,7 @@ ufs_chown(vp, uid, gid, cred, p)
*/
if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
(gid != ip->i_gid && !groupmember((gid_t)gid, cred))) &&
- (error = suser_xxx(cred, &p->p_acflag)))
+ (error = suser_xxx(cred, p, PRISON_ROOT)))
return (error);
ogid = ip->i_gid;
ouid = ip->i_uid;
@@ -2166,7 +2166,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
if (DOINGSOFTDEP(tvp))
softdep_increase_linkcnt(ip);
if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
- suser_xxx(cnp->cn_cred, NULL))
+ suser_xxx(cnp->cn_cred, 0, 0))
ip->i_mode &= ~ISGID;
if (cnp->cn_flags & ISWHITEOUT)
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 4cd11baab111..576a238b5cd6 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -1,5 +1,5 @@
# From: @(#)Makefile 5.20 (Berkeley) 6/12/93
-# $Id: Makefile,v 1.151 1999/04/07 04:12:02 msmith Exp $
+# $Id: Makefile,v 1.152 1999/04/28 08:00:50 obrien Exp $
# XXX MISSING: mkproto
SUBDIR= IPXrouted \
@@ -31,6 +31,7 @@ SUBDIR= IPXrouted \
ipresend \
ipsend \
iptest \
+ jail \
kbdcontrol \
kbdmap \
kernbb \
diff --git a/usr.sbin/jail/Makefile b/usr.sbin/jail/Makefile
new file mode 100644
index 000000000000..f90553dfa090
--- /dev/null
+++ b/usr.sbin/jail/Makefile
@@ -0,0 +1,4 @@
+PROG= jail
+MAN8= jail.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
new file mode 100644
index 000000000000..e1108fabce6a
--- /dev/null
+++ b/usr.sbin/jail/jail.8
@@ -0,0 +1,32 @@
+.Dd April 28, 1999
+.Dt JAIL 8
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm jail
+.Nd imprison process and decendants.
+.Sh SYNOPSIS
+.Nm jail
+.Ar path
+.Ar hostname
+.Ar ip-number
+.Sh DESCRIPTION
+The
+.Nm
+command imprisons a process and all future decendants.
+.Pp
+Please see the
+.Xr jail 2
+Manual page for further details.
+.Sh SEE ALSO
+.Xr chroot 2 ,
+.Xr jail 2
+.Sh HISTORY
+The
+.Fn jail
+function call appeared in
+.Fx 4.0 .
+.Pp
+The jail feature was written by Poul-Henning Kamp for
+R&D Associates
+.Dq Li http://www.rndassociates.com/
+who contributed it to FreeBSD.
diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c
new file mode 100644
index 000000000000..938c50b7b937
--- /dev/null
+++ b/usr.sbin/jail/jail.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/jail.h>
+#include <netinet/in.h>
+
+int
+main(int argc, char **argv)
+{
+ struct jail j;
+ int i;
+ struct in_addr in;
+
+ if (argc < 5)
+ errx(1, "Usage: %s path hostname ip command ...\n", argv[0]);
+ i = chdir(argv[1]);
+ if (i)
+ err(1, "chdir %s", argv[1]);
+ j.path = argv[1];
+ j.hostname = argv[2];
+ i = inet_aton(argv[3], &in);
+ if (!i)
+ errx(1, "Couldn't make sense if ip number\n");
+ j.ip_number = in.s_addr;
+ i = jail(&j);
+ if (i)
+ err(1, "Imprisonment failed");
+ i = execv(argv[4], argv + 4);
+ if (i)
+ err(1, "execv(%s)", argv[4]);
+ exit (0);
+}