--- vfs_mount.c.orig Thu Dec 11 14:01:58 2003 +++ vfs_mount.c Mon Jan 26 23:36:35 2004 @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD: src/sys/kern/vfs_mou #include #include #include +#include #include #include #include @@ -678,6 +679,9 @@ vfs_domount( if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) return (ENAMETOOLONG); + /* mount(2) is not permitted inside of jail. */ + if (jailed(td->td_ucred)) + return (EPERM); if (usermount == 0) { error = suser(td); if (error) @@ -724,8 +728,17 @@ vfs_domount( /* * Only root, or the user that did the original mount is * permitted to update it. + * Remember that root may work with provileges while + * file system was mounted and now root may be an + * unprivileged user, so force suser(9) check for + * file systems mounted by user with uid UID_ROOT. + * XXX: Even if file system was mounted by unprivileged + * root and user mounts are permitted, it can't be + * updated by unprivileged root since information + * about root provileges isn't stored anywhere. */ - if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { + if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid || + mp->mnt_cred->cr_uid == UID_ROOT) { error = suser(td); if (error) { vput(vp); @@ -1014,6 +1027,15 @@ unmount(td, uap) char *pathbuf; int error, id0, id1; + /* unmount(2) is not permitted inside of jail. */ + if (jailed(td->td_ucred)) + return (EPERM); + if (usermount == 0) { + error = suser(td); + if (error) + return (error); + } + pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL); if (error) { @@ -1054,8 +1076,17 @@ unmount(td, uap) /* * Only root, or the user that did the original mount is * permitted to unmount this filesystem. + * Remember that root may work with provileges while + * file system was mounted and now root may be an + * unprivileged user, so force suser(9) check for + * file systems mounted by user with uid UID_ROOT. + * XXX: Even if file system was mounted by unprivileged + * root and user mounts are permitted, it can't be + * unmounted by unprivileged root since information + * about root provileges isn't stored anywhere. */ - if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { + if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid || + mp->mnt_cred->cr_uid == UID_ROOT) { error = suser(td); if (error) return (error);