? compile/DEBUG ? i386/conf/DEBUG Index: compat/linprocfs/linprocfs_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_misc.c,v retrieving revision 1.18 diff -u -r1.18 linprocfs_misc.c --- compat/linprocfs/linprocfs_misc.c 2001/01/23 22:13:07 1.18 +++ compat/linprocfs/linprocfs_misc.c 2001/02/05 03:54:32 @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include #include #include +#include #include #include Index: compat/linux/linux_mib.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_mib.c,v retrieving revision 1.8 diff -u -r1.8 linux_mib.c --- compat/linux/linux_mib.c 2000/12/05 06:44:22 1.8 +++ compat/linux/linux_mib.c 2001/02/05 03:54:32 @@ -117,10 +117,11 @@ register struct prison *pr; register struct linux_prison *lpr; - pr = p->p_prison; - if (pr == NULL) + if (!jailed(p->p_ucred)) return (NULL); + pr = p->p_ucred->cr_prison; + if (pr->pr_linux == NULL) { MALLOC(lpr, struct linux_prison *, sizeof *lpr, M_PRISON, M_WAITOK|M_ZERO); @@ -137,7 +138,7 @@ register struct prison *pr; register struct linux_prison *lpr; - pr = p->p_prison; + pr = p->p_ucred->cr_prison; if (pr != NULL && pr->pr_linux != NULL) { lpr = pr->pr_linux; if (lpr->pr_osname[0]) @@ -170,7 +171,7 @@ register struct prison *pr; register struct linux_prison *lpr; - pr = p->p_prison; + pr = p->p_ucred->cr_prison; if (pr != NULL && pr->pr_linux != NULL) { lpr = pr->pr_linux; if (lpr->pr_osrelease[0]) @@ -203,7 +204,7 @@ register struct prison *pr; register struct linux_prison *lpr; - pr = p->p_prison; + pr = p->p_ucred->cr_prison; if (pr != NULL && pr->pr_linux != NULL) { lpr = pr->pr_linux; if (lpr->pr_oss_version) Index: compat/svr4/svr4_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.23 diff -u -r1.23 svr4_misc.c --- compat/svr4/svr4_misc.c 2001/01/27 00:01:28 1.23 +++ compat/svr4/svr4_misc.c 2001/02/05 03:54:33 @@ -1299,15 +1299,6 @@ q->p_cred = NULL; } - /* - * Destroy empty prisons - */ - if (q->p_prison && !--q->p_prison->pr_ref) { - if (q->p_prison->pr_linux != NULL) - FREE(q->p_prison->pr_linux, M_PRISON); - FREE(q->p_prison, M_PRISON); - } - /* * Remove unused arguments */ Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.153 diff -u -r1.153 init_main.c --- kern/init_main.c 2001/01/24 10:40:56 1.153 +++ kern/init_main.c 2001/02/05 03:54:48 @@ -324,9 +324,7 @@ p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ p->p_ucred->cr_uidinfo = uifind(0); - - /* Don't jail it */ - p->p_prison = 0; + p->p_ucred->cr_prison = NULL; /* Don't jail it. */ /* Create procsig. */ p->p_procsig = &procsig0; Index: kern/kern_exit.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v retrieving revision 1.114 diff -u -r1.114 kern_exit.c --- kern/kern_exit.c 2001/01/24 00:33:44 1.114 +++ kern/kern_exit.c 2001/02/05 03:54:48 @@ -528,15 +528,6 @@ } /* - * Destroy empty prisons - */ - if (p->p_prison && !--p->p_prison->pr_ref) { - if (p->p_prison->pr_linux != NULL) - FREE(p->p_prison->pr_linux, M_PRISON); - FREE(p->p_prison, M_PRISON); - } - - /* * Remove unused arguments */ if (p->p_args && --p->p_args->ar_ref == 0) Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.96 diff -u -r1.96 kern_fork.c --- kern/kern_fork.c 2001/01/26 23:51:40 1.96 +++ kern/kern_fork.c 2001/02/05 03:54:49 @@ -392,11 +392,6 @@ crhold(p1->p_ucred); uihold(p1->p_cred->p_uidinfo); - if (p2->p_prison) { - p2->p_prison->pr_ref++; - p2->p_flag |= P_JAILED; - } - if (p2->p_args) p2->p_args->ar_ref++; Index: kern/kern_jail.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_jail.c,v retrieving revision 1.9 diff -u -r1.9 kern_jail.c --- kern/kern_jail.c 2000/12/08 21:50:32 1.9 +++ kern/kern_jail.c 2001/02/05 03:54:49 @@ -46,16 +46,17 @@ int jail(p, uap) - struct proc *p; - struct jail_args /* { - syscallarg(struct jail *) jail; - } */ *uap; + struct proc *p; + struct jail_args /* { + syscallarg(struct jail *) jail; + } */ *uap; { int error; struct prison *pr; struct jail j; struct chroot_args ca; + /* Implicitly fail if already in jail. */ error = suser(p); if (error) return (error); @@ -75,9 +76,9 @@ if (error) goto bail; - pr->pr_ref++; - p->p_prison = pr; - p->p_flag |= P_JAILED; + p->p_ucred = crcopy(p->p_ucred); + p->p_ucred->cr_prison = pr; + pr->pr_ref = 1; return (0); bail: @@ -85,12 +86,33 @@ return (error); } +void +prison_free(struct prison *pr) +{ + + pr->pr_ref--; + if (pr->pr_ref == 0) { + if (pr->pr_linux != NULL) + FREE(pr->pr_linux, M_PRISON); + FREE(pr, M_PRISON); + } + /* XXX */ +} + +void +prison_hold(struct prison *pr) +{ + + pr->pr_ref++; + /* XXX */ +} + int -prison_ip(struct proc *p, int flag, u_int32_t *ip) +prison_ip(struct ucred *cred, int flag, u_int32_t *ip) { u_int32_t tmp; - if (!p->p_prison) + if (!jailed(cred)) return (0); if (flag) tmp = *ip; @@ -98,22 +120,22 @@ tmp = ntohl(*ip); if (tmp == INADDR_ANY) { if (flag) - *ip = p->p_prison->pr_ip; + *ip = cred->cr_prison->pr_ip; else - *ip = htonl(p->p_prison->pr_ip); + *ip = htonl(cred->cr_prison->pr_ip); return (0); } - if (p->p_prison->pr_ip != tmp) + if (cred->cr_prison->pr_ip != tmp) return (1); return (0); } void -prison_remote_ip(struct proc *p, int flag, u_int32_t *ip) +prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip) { u_int32_t tmp; - if (!p || !p->p_prison) + if (!jailed(cred)) return; if (flag) tmp = *ip; @@ -121,16 +143,16 @@ tmp = ntohl(*ip); if (tmp == 0x7f000001) { if (flag) - *ip = p->p_prison->pr_ip; + *ip = cred->cr_prison->pr_ip; else - *ip = htonl(p->p_prison->pr_ip); + *ip = htonl(cred->cr_prison->pr_ip); return; } return; } int -prison_if(struct proc *p, struct sockaddr *sa) +prison_if(struct ucred *cred, struct sockaddr *sa) { struct sockaddr_in *sai = (struct sockaddr_in*) sa; int ok; @@ -139,9 +161,38 @@ ok = 1; else if (sai->sin_family != AF_INET) ok = 0; - else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) + else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) ok = 1; else ok = 0; return (ok); +} + +/* + * Return 0 if jails permit p1 to frob p2, otherwise ESRCH. + */ +int +prison_check(cred1, cred2) + struct ucred *cred1, *cred2; +{ + + if (jailed(cred1)) { + if (!jailed(cred2)) + return (ESRCH); + if (cred2->cr_prison != cred1->cr_prison) + return (ESRCH); + } + + return (0); +} + +/* + * Return 1 if the passed credential is in a jail, otherwise 0. + */ +int +jailed(cred) + struct ucred *cred; +{ + + return (cred->cr_prison != NULL); } Index: kern/kern_ktrace.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.48 diff -u -r1.48 kern_ktrace.c --- kern/kern_ktrace.c 2001/01/08 07:22:06 1.48 +++ kern/kern_ktrace.c 2001/02/05 03:54:50 @@ -48,6 +48,7 @@ #include #include #include +#include static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE"); @@ -519,6 +520,7 @@ * so, only root may further change it. * * XXX: These checks are stronger than for ptrace() + * XXX: This check should be p_can(... P_CAN_DEBUG ...); * * TODO: check groups. use caller effective gid. */ @@ -529,7 +531,7 @@ register struct pcred *caller = callp->p_cred; register struct pcred *target = targetp->p_cred; - if (!PRISON_CHECK(callp, targetp)) + if (prison_check(callp->p_ucred, targetp->p_ucred)) return (0); if ((caller->pc_ucred->cr_uid == target->p_ruid && target->p_ruid == target->p_svuid && Index: kern/kern_mib.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_mib.c,v retrieving revision 1.37 diff -u -r1.37 kern_mib.c --- kern/kern_mib.c 2000/07/04 11:25:22 1.37 +++ kern/kern_mib.c 2001/02/05 03:54:50 @@ -146,12 +146,12 @@ { int error; - if (req->p->p_prison) { + if (jailed(req->p->p_ucred)) { if (!jail_set_hostname_allowed && req->newptr) return(EPERM); error = sysctl_handle_string(oidp, - req->p->p_prison->pr_host, - sizeof req->p->p_prison->pr_host, req); + req->p->p_ucred->cr_prison->pr_host, + sizeof req->p->p_ucred->cr_prison->pr_host, req); } else error = sysctl_handle_string(oidp, hostname, sizeof hostname, req); Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.83 diff -u -r1.83 kern_proc.c --- kern/kern_proc.c 2001/01/24 12:49:50 1.83 +++ kern/kern_proc.c 2001/02/05 03:54:50 @@ -49,6 +49,7 @@ #include #include #include +#include static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header"); MALLOC_DEFINE(M_SESSION, "session", "session header"); @@ -481,6 +482,9 @@ kp->ki_xstat = p->p_xstat; kp->ki_acflag = p->p_acflag; kp->ki_flag = p->p_flag; + /* If jailed(p->p_ucred), emulate the old P_JAILED flag. */ + if (jailed(p->p_ucred)) + kp->ki_flag |= P_JAILED; kp->ki_lock = p->p_lock; PROC_UNLOCK(p); PROCTREE_LOCK(PT_SHARED); Index: kern/kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.71 diff -u -r1.71 kern_prot.c --- kern/kern_prot.c 2001/01/13 22:49:59 1.71 +++ kern/kern_prot.c 2001/02/05 03:54:51 @@ -56,6 +56,7 @@ #include #include #include +#include static MALLOC_DEFINE(M_CRED, "cred", "credentials"); @@ -941,15 +942,15 @@ */ int suser(p) - const struct proc *p; + struct proc *p; { return suser_xxx(0, p, 0); } int suser_xxx(cred, proc, flag) - const struct ucred *cred; - const struct proc *proc; + struct ucred *cred; + struct proc *proc; int flag; { if (!suser_permitted) @@ -962,20 +963,21 @@ cred = proc->p_ucred; if (cred->cr_uid != 0) return (EPERM); - if (proc && proc->p_prison && !(flag & PRISON_ROOT)) + if (jailed(cred) && !(flag & PRISON_ROOT)) return (EPERM); return (0); } static int -p_cansee(const struct proc *p1, const struct proc *p2, int *privused) +p_cansee(struct proc *p1, struct proc *p2, int *privused) { + int error; if (privused != NULL) *privused = 0; - if (!PRISON_CHECK(p1, p2)) - return (ESRCH); + if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + return (error); if (!ps_showallprocs && p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) { if (suser_xxx(NULL, p1, PRISON_ROOT) == 0) { @@ -990,8 +992,9 @@ } static int -p_cankill(const struct proc *p1, const struct proc *p2, int *privused) +p_cankill(struct proc *p1, struct proc *p2, int *privused) { + int error; if (privused != NULL) *privused = 0; @@ -999,8 +1002,8 @@ if (p1 == p2) return (0); - if (!PRISON_CHECK(p1, p2)) - return (ESRCH); + if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + return (error); if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) return (0); @@ -1033,8 +1036,9 @@ } static int -p_cansched(const struct proc *p1, const struct proc *p2, int *privused) +p_cansched(struct proc *p1, struct proc *p2, int *privused) { + int error; if (privused != NULL) *privused = 0; @@ -1042,8 +1046,8 @@ if (p1 == p2) return (0); - if (!PRISON_CHECK(p1, p2)) - return (ESRCH); + if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + return (error); if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) return (0); @@ -1076,9 +1080,9 @@ } static int -p_candebug(const struct proc *p1, const struct proc *p2, int *privused) +p_candebug(struct proc *p1, struct proc *p2, int *privused) { - int error; + int error; if (privused != NULL) *privused = 0; @@ -1087,8 +1091,8 @@ if (p1 == p2) return (0); - if (!PRISON_CHECK(p1, p2)) - return (ESRCH); + if ((error = prison_check(p1->p_ucred, p2->p_ucred))) + return (error); /* not owned by you, has done setuid (unless you're root) */ /* add a CAP_SYS_PTRACE here? */ @@ -1110,7 +1114,7 @@ } int -p_can(const struct proc *p1, const struct proc *p2, int operation, +p_can(struct proc *p1, struct proc *p2, int operation, int *privused) { @@ -1180,6 +1184,11 @@ */ if (cr->cr_uidinfo != NULL) uifree(cr->cr_uidinfo); + /* + * Free a prison, if any. + */ + if (jailed(cr)) + prison_free(cr->cr_prison); FREE((caddr_t)cr, M_CRED); } else { mtx_exit(&cr->cr_mtx, MTX_DEF); @@ -1219,6 +1228,8 @@ *newcr = *cr; mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); uihold(newcr->cr_uidinfo); + if (jailed(newcr)) + prison_hold(newcr->cr_prison); newcr->cr_ref = 1; return (newcr); } Index: kern/sysv_msg.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sysv_msg.c,v retrieving revision 1.29 diff -u -r1.29 sysv_msg.c --- kern/sysv_msg.c 2001/01/14 18:04:30 1.29 +++ kern/sysv_msg.c 2001/02/05 03:54:52 @@ -278,7 +278,7 @@ } */ *uap; { - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) @@ -334,7 +334,7 @@ printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); msqid = IPCID_TO_IX(msqid); @@ -473,7 +473,7 @@ printf("msgget(0x%x, 0%o)\n", key, msgflg); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); if (key != IPC_PRIVATE) { @@ -588,7 +588,7 @@ msgflg); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); msqid = IPCID_TO_IX(msqid); @@ -915,7 +915,7 @@ msgsz, msgtyp, msgflg); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); msqid = IPCID_TO_IX(msqid); Index: kern/sysv_sem.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sysv_sem.c,v retrieving revision 1.31 diff -u -r1.31 sysv_sem.c --- kern/sysv_sem.c 2001/01/14 18:04:30 1.31 +++ kern/sysv_sem.c 2001/02/05 03:54:53 @@ -255,7 +255,7 @@ } */ *uap; { - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) @@ -464,7 +464,7 @@ printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); semid = IPCID_TO_IX(semid); @@ -627,7 +627,7 @@ printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); if (key != IPC_PRIVATE) { @@ -748,7 +748,7 @@ printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops); #endif - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ Index: kern/sysv_shm.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sysv_shm.c,v retrieving revision 1.51 diff -u -r1.51 sysv_shm.c --- kern/sysv_shm.c 2001/01/14 18:04:30 1.51 +++ kern/sysv_shm.c 2001/02/05 03:54:53 @@ -229,7 +229,7 @@ struct shmmap_state *shmmap_s; int i; - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; @@ -266,7 +266,7 @@ vm_size_t size; int rv; - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; @@ -360,7 +360,7 @@ struct shmid_ds *shmseg; struct oshmid_ds outbuf; - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); shmseg = shm_find_segment_by_shmid(uap->shmid); @@ -411,7 +411,7 @@ struct shmid_ds inbuf; struct shmid_ds *shmseg; - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); shmseg = shm_find_segment_by_shmid(uap->shmid); @@ -590,7 +590,7 @@ { int segnum, mode, error; - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); mode = uap->shmflg & ACCESSPERMS; @@ -621,7 +621,7 @@ } */ *uap; { - if (!jail_sysvipc_allowed && p->p_prison != NULL) + if (!jail_sysvipc_allowed && jailed(p->p_ucred)) return (ENOSYS); if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) Index: kern/tty_pty.c =================================================================== RCS file: /home/ncvs/src/sys/kern/tty_pty.c,v retrieving revision 1.82 diff -u -r1.82 tty_pty.c --- kern/tty_pty.c 2000/12/08 21:50:37 1.82 +++ kern/tty_pty.c 2001/02/05 03:54:54 @@ -185,7 +185,7 @@ tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; } else if (tp->t_state & TS_XCLUDE && suser(p)) { return (EBUSY); - } else if (pti->pt_prison != p->p_prison) { + } else if (pti->pt_prison != p->p_ucred->cr_prison) { return (EBUSY); } if (tp->t_oproc) /* Ctrlr still around. */ @@ -346,7 +346,7 @@ (void)(*linesw[tp->t_line].l_modem)(tp, 1); tp->t_lflag &= ~EXTPROC; pti = dev->si_drv1; - pti->pt_prison = p->p_prison; + pti->pt_prison = p->p_ucred->cr_prison; pti->pt_flags = 0; pti->pt_send = 0; pti->pt_ucntl = 0; Index: kern/uipc_socket.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.87 diff -u -r1.87 uipc_socket.c --- kern/uipc_socket.c 2001/01/21 22:23:10 1.87 +++ kern/uipc_socket.c 2001/02/05 03:54:55 @@ -144,7 +144,7 @@ if (prp == 0 || prp->pr_usrreqs->pru_attach == 0) return (EPROTONOSUPPORT); - if (p->p_prison && jail_socket_unixiproute_only && + if (jailed(p->p_ucred) && jail_socket_unixiproute_only && prp->pr_domain->dom_family != PF_LOCAL && prp->pr_domain->dom_family != PF_INET && prp->pr_domain->dom_family != PF_ROUTE) { Index: kern/uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.62 diff -u -r1.62 uipc_usrreq.c --- kern/uipc_usrreq.c 2000/12/21 21:43:24 1.62 +++ kern/uipc_usrreq.c 2001/02/05 03:54:56 @@ -54,6 +54,7 @@ #include #include #include +#include #include @@ -725,7 +726,7 @@ static int prison_unpcb(struct proc *p, struct unpcb *unp) { - if (!p->p_prison) + if (!jailed(p->p_ucred)) return (0); if (p->p_fd->fd_rdir == unp->unp_rvnode) return (0); Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.175 diff -u -r1.175 vfs_syscalls.c --- kern/vfs_syscalls.c 2000/12/13 00:17:01 1.175 +++ kern/vfs_syscalls.c 2001/02/05 03:55:00 @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -601,7 +602,7 @@ int error; struct nameidata nd; - if (p->p_prison && !prison_quotas) + if (jailed(p->p_ucred) && !prison_quotas) return (EPERM); NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); if ((error = namei(&nd)) != 0) Index: miscfs/procfs/procfs_status.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_status.c,v retrieving revision 1.25 diff -u -r1.25 procfs_status.c --- miscfs/procfs/procfs_status.c 2001/01/24 11:17:35 1.25 +++ miscfs/procfs/procfs_status.c 2001/02/05 03:55:00 @@ -163,9 +163,9 @@ DOCHECK(); } - if (p->p_prison) + if (jailed(p->p_ucred)) ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - " %s", p->p_prison->pr_host); + " %s", p->p_ucred->cr_prison->pr_host); else ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " -"); DOCHECK(); Index: net/bpf.c =================================================================== RCS file: /home/ncvs/src/sys/net/bpf.c,v retrieving revision 1.75 diff -u -r1.75 bpf.c --- net/bpf.c 2001/01/29 13:26:14 1.75 +++ net/bpf.c 2001/02/05 03:55:10 @@ -354,9 +354,6 @@ { register struct bpf_d *d; - if (p->p_prison) - return (EPERM); - d = dev->si_drv1; /* * Each minor can be opened by only one process. If the requested Index: net/if.c =================================================================== RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.98 diff -u -r1.98 if.c --- net/if.c 2001/01/30 22:28:03 1.98 +++ net/if.c 2001/02/05 03:55:10 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -1084,7 +1085,8 @@ 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)) + if (jailed(curproc->p_ucred) && + prison_if(curproc->p_ucred, sa)) continue; addrs++; #ifdef COMPAT_43 Index: net/if.h =================================================================== RCS file: /home/ncvs/src/sys/net/if.h,v retrieving revision 1.59 diff -u -r1.59 if.h --- net/if.h 2000/03/27 19:14:17 1.59 +++ net/if.h 2001/02/05 03:55:11 @@ -265,8 +265,6 @@ #ifdef _KERNEL struct proc; -int prison_if __P((struct proc *p, struct sockaddr *sa)); - /* XXX - this should go away soon. */ #include #endif Index: net/rtsock.c =================================================================== RCS file: /home/ncvs/src/sys/net/rtsock.c,v retrieving revision 1.48 diff -u -r1.48 rtsock.c --- net/rtsock.c 2000/12/08 21:50:44 1.48 +++ net/rtsock.c 2001/02/05 03:55:11 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -915,7 +916,8 @@ 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)) + if (jailed(curproc->p_ucred) && + prison_if(curproc->p_ucred, ifa->ifa_addr)) continue; ifaaddr = ifa->ifa_addr; netmask = ifa->ifa_netmask; Index: netinet/in.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.h,v retrieving revision 1.51 diff -u -r1.51 in.h --- netinet/in.h 2001/01/12 07:47:53 1.51 +++ netinet/in.h 2001/02/05 03:55:13 @@ -485,9 +485,6 @@ char *inet_ntoa __P((struct in_addr)); /* in libkern */ char *inet_ntoa_r __P((struct in_addr ina, char *buf)); /* 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 #endif Index: netinet/in_pcb.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.73 diff -u -r1.73 in_pcb.c --- netinet/in_pcb.c 2001/01/23 07:27:56 1.73 +++ netinet/in_pcb.c 2001/02/05 03:55:14 @@ -198,8 +198,13 @@ if (sin->sin_family != AF_INET) return (EAFNOSUPPORT); #endif + /* + * XXX: The following jail() related code uses the process + * credential rather than the socket credential. It should + * probably use the socket credential. + */ if (sin->sin_addr.s_addr != INADDR_ANY) - if (prison_ip(p, 0, &sin->sin_addr.s_addr)) + if (prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr)) return(EINVAL); lport = sin->sin_port; if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { @@ -219,12 +224,17 @@ } if (lport) { struct inpcb *t; - + /* + * XXX: Some of the access checks below use + * the calling process. Others use the cached + * socket credential. The direct cr_uid checks + * below should use suser_xxx(). + */ /* GROSS */ if (ntohs(lport) < IPPORT_RESERVED && p && suser_xxx(0, p, PRISON_ROOT)) return (EACCES); - if (p && p->p_prison) + if (p && jailed(p->p_ucred)) prison = 1; if (so->so_cred->cr_uid != 0 && !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { @@ -273,8 +283,16 @@ ushort first, last; int count; + /* + * XXX: The following jail() related code uses the process + * credential rather than the socket credential. It should + * probably use the socket credential. + * XXX: Original jail() code dereferences (p) below in + * prison_ip(). Is that OK, or should there be a check for + * NULL (p). + */ if (inp->inp_laddr.s_addr != INADDR_ANY) - if (prison_ip(p, 0, &inp->inp_laddr.s_addr )) + if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr )) return (EINVAL); inp->inp_flags |= INP_ANONPORT; @@ -345,7 +363,12 @@ } } inp->inp_lport = lport; - if (prison_ip(p, 0, &inp->inp_laddr.s_addr)) + /* + * XXX: The following jail() related code uses the process + * credential rather than the socket credential. It should + * probably use the socket credential. + */ + if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr)) return(EINVAL); if (in_pcbinshash(inp) != 0) { inp->inp_laddr.s_addr = INADDR_ANY; @@ -493,11 +516,13 @@ struct sockaddr_in *ifaddr; struct sockaddr_in *sin = (struct sockaddr_in *)nam; struct sockaddr_in sa; + struct ucred *cred; int error; - if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) { + cred = inp->inp_socket->so_cred; + if (inp->inp_laddr.s_addr == INADDR_ANY && jailed(cred)) { bzero(&sa, sizeof (sa)); - sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip); + sa.sin_addr.s_addr = htonl(cred->cr_prison->pr_ip); sa.sin_len=sizeof (sa); sa.sin_family = AF_INET; error = in_pcbbind(inp, (struct sockaddr *)&sa, p); @@ -1072,9 +1097,9 @@ int prison_xinpcb(struct proc *p, struct inpcb *inp) { - if (!p->p_prison) + if (!jailed(p->p_ucred)) return (0); - if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip) + if (ntohl(inp->inp_laddr.s_addr) == p->p_ucred->cr_prison->pr_ip) return (0); return (1); } Index: netinet/tcp_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.53 diff -u -r1.53 tcp_usrreq.c --- netinet/tcp_usrreq.c 2001/02/02 18:48:25 1.53 +++ netinet/tcp_usrreq.c 2001/02/05 03:55:14 @@ -49,6 +49,8 @@ #include #include #include +#include +#include #include #include @@ -328,7 +330,8 @@ goto out; } - prison_remote_ip(p, 0, &sinp->sin_addr.s_addr); + if (p && jailed(p->p_ucred)) + prison_remote_ip(p->p_ucred, 0, &sinp->sin_addr.s_addr); if ((error = tcp_connect(tp, nam, p)) != 0) goto out; Index: netinet/udp_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.80 diff -u -r1.80 udp_usrreq.c --- netinet/udp_usrreq.c 2000/12/24 10:57:21 1.80 +++ netinet/udp_usrreq.c 2001/02/05 03:55:15 @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -656,7 +657,13 @@ if (addr) { sin = (struct sockaddr_in *)addr; - prison_remote_ip(p, 0, &sin->sin_addr.s_addr); + /* + * XXX: The following jail() related code uses the process + * credential rather than the socket credential. It should + * probably use the socket credential. + */ + if (p && jailed(p->p_ucred)) + prison_remote_ip(p->p_ucred, 0, &sin->sin_addr.s_addr); laddr = inp->inp_laddr; if (inp->inp_faddr.s_addr != INADDR_ANY) { error = EISCONN; @@ -829,7 +836,13 @@ return EISCONN; s = splnet(); sin = (struct sockaddr_in *)nam; - prison_remote_ip(p, 0, &sin->sin_addr.s_addr); + /* + * XXX: The following jail() related code uses the process + * credential rather than the socket credential. It should + * probably use the socket credential. + */ + if (p && jailed(p->p_ucred)) + prison_remote_ip(p->p_ucred, 0, &sin->sin_addr.s_addr); error = in_pcbconnect(inp, nam, p); splx(s); if (error == 0) Index: sys/capability.h =================================================================== RCS file: /home/ncvs/src/sys/sys/capability.h,v retrieving revision 1.4 diff -u -r1.4 capability.h --- sys/capability.h 2000/10/13 17:12:58 1.4 +++ sys/capability.h 2001/02/05 03:55:16 @@ -167,7 +167,7 @@ struct proc; struct ucred; struct vnode; -int cap_check(const struct ucred *, const struct proc *, cap_value_t, int); +int cap_check(struct ucred *, struct proc *, cap_value_t, int); int cap_change_on_inherit(struct cap *cap_p); int cap_inherit(struct vnode *vp, struct proc *p); void cap_init_proc0(struct cap *); Index: sys/jail.h =================================================================== RCS file: /home/ncvs/src/sys/sys/jail.h,v retrieving revision 1.10 diff -u -r1.10 jail.h --- sys/jail.h 2000/10/31 01:34:00 1.10 +++ sys/jail.h 2001/02/05 03:55:16 @@ -32,7 +32,7 @@ /* * 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 + * ucreds's of the inmates. pr_ref keeps track of them and is used to * delete the struture when the last inmate is dead. */ @@ -49,6 +49,19 @@ extern int jail_set_hostname_allowed; extern int jail_socket_unixiproute_only; extern int jail_sysvipc_allowed; + +/* + * Kernel support functions for jail(). + */ +struct ucred; +struct sockaddr; +int jailed __P((struct ucred *cred)); +int prison_check __P((struct ucred *cred1, struct ucred *cred2)); +void prison_free __P((struct prison *pr)); +void prison_hold __P((struct prison *pr)); +int prison_if __P((struct ucred *cred, struct sockaddr *sa)); +int prison_ip __P((struct ucred *cred, int flag, u_int32_t *ip)); +void prison_remote_ip __P((struct ucred *cred, int flags, u_int32_t *ip)); #endif /* !_KERNEL */ #endif /* !_SYS_JAIL_H_ */ Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.145 diff -u -r1.145 proc.h --- sys/proc.h 2001/01/31 04:29:52 1.145 +++ sys/proc.h 2001/02/05 03:55:17 @@ -258,7 +258,6 @@ struct pgrp *p_pgrp; /* (e?/c?) Pointer to process group. */ struct sysentvec *p_sysent; /* (b) System call dispatch information. */ struct rtprio p_rtprio; /* (j) Realtime priority. */ - struct prison *p_prison; /* (b?) jail(4). */ struct pargs *p_args; /* (b?) Process arguments. */ /* End area that is copied on creation. */ @@ -391,10 +390,6 @@ : 0); } -/* Handy macro to determine if p1 can mangle p2. */ -#define PRISON_CHECK(p1, p2) \ - ((p1)->p_prison == NULL || (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". @@ -520,7 +515,7 @@ int inferior __P((struct proc *p)); int leavepgrp __P((struct proc *p)); void mi_switch __P((void)); -int p_can __P((const struct proc *p1, const struct proc *p2, int operation, +int p_can __P((struct proc *p1, struct proc *p2, int operation, int *privused)); int p_trespass __P((struct proc *p1, struct proc *p2)); void procinit __P((void)); Index: sys/systm.h =================================================================== RCS file: /home/ncvs/src/sys/sys/systm.h,v retrieving revision 1.133 diff -u -r1.133 systm.h --- sys/systm.h 2001/01/19 10:46:58 1.133 +++ sys/systm.h 2001/02/05 03:55:17 @@ -163,9 +163,8 @@ /* flags for suser_xxx() */ #define PRISON_ROOT 1 -int suser __P((const struct proc *)); -int suser_xxx __P((const struct ucred *cred, const struct proc *proc, - int flag)); +int suser __P((struct proc *)); +int suser_xxx __P((struct ucred *cred, struct proc *proc, int flag)); char *getenv __P((char *name)); int getenv_int __P((char *name, int *data)); Index: sys/ucred.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ucred.h,v retrieving revision 1.19 diff -u -r1.19 ucred.h --- sys/ucred.h 2000/11/30 19:09:47 1.19 +++ sys/ucred.h 2001/02/05 03:55:17 @@ -51,6 +51,7 @@ short cr_ngroups; /* number of groups */ gid_t cr_groups[NGROUPS]; /* groups */ struct uidinfo *cr_uidinfo; /* per uid resource consumption */ + struct prison *cr_prison; /* jail(4) */ struct mtx cr_mtx; /* protect refcount */ }; #define cr_gid cr_groups[0]