(c) 2004 Pawel Jakub Dawidek Patch against FreeBSD 5.2-CURRENT, kern.osreldate: 502101. diff -upr /usr/src/sbin/mount/mount.c src/sbin/mount/mount.c --- /usr/src/sbin/mount/mount.c Sat Jan 31 09:19:22 2004 +++ src/sbin/mount/mount.c Mon Feb 2 16:32:17 2004 @@ -522,7 +522,11 @@ prmount(sfp) (void)printf(", %s", o->o_name); flags &= ~o->o_opt; } - if (sfp->f_owner) { + /* + * Inform when file system is mounted by an unprivileged user + * or privileged non-root user. + */ + if ((flags & MNT_USER) != 0 || sfp->owner != 0) { (void)printf(", mounted by "); if ((pw = getpwuid(sfp->f_owner)) != NULL) (void)printf("%s", pw->pw_name); diff -upr /usr/src/sys/kern/vfs_mount.c src/sys/kern/vfs_mount.c --- /usr/src/sys/kern/vfs_mount.c Mon Dec 1 00:30:09 2003 +++ src/sys/kern/vfs_mount.c Sat Jan 31 10:13:03 2004 @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD: src/sys/kern/vfs_mou #include #include #include +#include #include #include #include @@ -678,6 +679,10 @@ 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) @@ -692,10 +697,11 @@ vfs_domount( return (error); } /* - * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users. + * Silently enforce MNT_NOSUID, MNT_NODEV and MNT_USER + * for non-root users. */ if (suser(td)) - fsflags |= MNT_NOSUID | MNT_NODEV; + fsflags |= MNT_NOSUID | MNT_NODEV | MNT_USER; /* * Get vnode to be covered */ @@ -725,9 +731,15 @@ vfs_domount( * Only root, or the user that did the original mount is * permitted to update it. */ - if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { - error = suser(td); - if (error) { + if ((mp->mnt_flag & MNT_USER) != 0) { + if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { + if ((error = suser(td)) != 0) { + vput(vp); + return (error); + } + } + } else { + if ((error = suser(td)) != 0) { vput(vp); return (error); } @@ -1014,6 +1026,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) { + if ((error = suser(td)) != 0) + return (error); + } + pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL); if (error) { @@ -1055,9 +1076,13 @@ unmount(td, uap) * Only root, or the user that did the original mount is * permitted to unmount this filesystem. */ - if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { - error = suser(td); - if (error) + if ((mp->mnt_flag & MNT_USER) != 0) { + if (mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { + if ((error = suser(td)) != 0) + return (error); + } + } else { + if ((error = suser(td)) != 0) return (error); } diff -upr /usr/src/sys/sys/mount.h src/sys/sys/mount.h --- /usr/src/sys/sys/mount.h Sat Jan 31 10:09:49 2004 +++ src/sys/sys/mount.h Sat Jan 31 10:10:06 2004 @@ -244,7 +244,7 @@ struct mount { MNT_NOATIME | \ MNT_NOSYMFOLLOW | MNT_IGNORE | MNT_JAILDEVFS | \ MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \ - MNT_ACLS) + MNT_ACLS | MNT_USER) /* * External filesystem command modifier flags.