diff options
author | pjd <pjd@FreeBSD.org> | 2004-02-02 19:02:05 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2004-02-02 19:02:05 +0000 |
commit | bc4eae093630ca14e9231c249c2f41ae714b6edb (patch) | |
tree | bbfead6c4e14ae5b280b1a39f5235e314618746b /sys | |
parent | 9354393ea0bc54c02e6b91362112ae33101217eb (diff) | |
download | FreeBSD-src-bc4eae093630ca14e9231c249c2f41ae714b6edb.zip FreeBSD-src-bc4eae093630ca14e9231c249c2f41ae714b6edb.tar.gz |
Fix many issues related to mount/unmount:
1. Root from inside a jail was able to unmount any file system
(except /).
2. Unprivileged root was able to unmount file systems mounted by
privileged root (execpt /).
3. User from inside a jail was able to mount file system when
sysctl vfs.usermount was set to 1.
4. User was able to mount file system when vfs.usermount was set to 1
(that's ok) and unmount it even if vfs.usermount was equal to 0
(that's not correct).
Possibility from point 1 was reported by: Dariusz Kowalski <darek@76.pl>
Only a part of this fix will be MFC'ed (if approved).
PR: kern/60149
Reviewed by: rwatson
Approved by: scottl (mentor)
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_mount.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index c1bf0b9..544e983 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/conf.h> #include <sys/cons.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/linker.h> #include <sys/mac.h> @@ -678,6 +679,10 @@ vfs_domount( if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) return (ENAMETOOLONG); + /* mount(2) is not permitted inside the 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 unprivileged 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 the 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); } |