--- //depot/vendor/freebsd_6/src/sys/kern/kern_jail.c 2005/11/12 20:31:23 +++ //depot/yahoo/ybsd_6/src/sys/kern/kern_jail.c 2008/07/30 14:54:10 @@ -66,11 +74,16 @@ &jail_allow_raw_sockets, 0, "Prison root can create raw sockets"); +int jail_allow_mount = 0; +SYSCTL_INT(_security_jail, OID_AUTO, allow_mount, CTLFLAG_RW, + &jail_allow_mount, 0, + "Prison root can mount filesystems"); + int jail_chflags_allowed = 0; SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, &jail_chflags_allowed, 0, "Processes in jail can alter system file flags"); /* allprison, lastprid, and prisoncount are protected by allprison_mtx. */ struct prisonlist allprison; struct mtx allprison_mtx; @@ -454,6 +633,8 @@ pr = cred->cr_prison; if (pr->pr_root->v_mount == mp) return (0); + if (mp->mnt_cred->cr_prison == pr) + return (0); if (jail_enforce_statfs == 2) return (ENOENT); /* @@ -508,6 +689,12 @@ */ if (strcmp(pr->pr_path, "/") == 0) return; + /* + * If this filesystem was mounted inside the jail, just leave the + * existing path alone. + */ + if (mp->mnt_cred->cr_prison == pr) + return; len = strlen(pr->pr_path); strlcpy(jpath, sp->f_mntonname + len, sizeof(jpath)); /* --- //depot/vendor/freebsd_6/src/sys/kern/vfs_mount.c 2007/05/10 03:28:43 +++ //depot/yahoo/ybsd_6/src/sys/kern/vfs_mount.c 2008/07/30 14:54:10 @@ -812,13 +813,14 @@ * variables will fit in our mp buffers, including the * terminating NUL. */ if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) return (ENAMETOOLONG); - if (jailed(td->td_ucred)) + if (jailed(td->td_ucred) && !jail_allow_mount) return (EPERM); if (usermount == 0) { - if ((error = suser(td)) != 0) + if ((error = suser_cred(td->td_ucred, jail_allow_mount ? + SUSER_ALLOWJAIL : 0)) != 0) return (error); } @@ -916,7 +918,8 @@ return (error); } if (va.va_uid != td->td_ucred->cr_uid) { - if ((error = suser(td)) != 0) { + if ((error = suser_cred(td->td_ucred, jail_allow_mount ? + SUSER_ALLOWJAIL : 0)) != 0) { vput(vp); return (error); } @@ -1077,10 +1080,11 @@ char *pathbuf; int error, id0, id1; - if (jailed(td->td_ucred)) + if (jailed(td->td_ucred) && !jail_allow_mount) return (EPERM); if (usermount == 0) { - if ((error = suser(td)) != 0) + if ((error = suser_cred(td->td_ucred, jail_allow_mount ? + SUSER_ALLOWJAIL : 0)) != 0) return (error); } --- //depot/vendor/freebsd_6/src/sys/kern/vfs_subr.c 2007/05/24 10:29:03 +++ //depot/yahoo/ybsd_6/src/sys/kern/vfs_subr.c 2007/11/25 21:00:25 @@ -417,7 +433,8 @@ if ((mp->mnt_flag & MNT_USER) == 0 || mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { - if ((error = suser(td)) != 0) + if ((error = suser_cred(td->td_ucred, jail_allow_mount ? + SUSER_ALLOWJAIL : 0)) != 0) return (error); } return (0); --- //depot/vendor/freebsd_6/src/sys/sys/jail.h 2005/06/09 12:29:15 +++ //depot/yahoo/ybsd_6/src/sys/sys/jail.h 2008/07/30 14:54:10 @@ -87,7 +107,8 @@ extern int jail_sysvipc_allowed; extern int jail_getfsstat_jailrootonly; extern int jail_allow_raw_sockets; +extern int jail_allow_mount; extern int jail_chflags_allowed; LIST_HEAD(prisonlist, prison); extern struct prisonlist allprison;