Non-root users should only specify mountpoints when calling umount.
Device names, tags (LABEL=, UUID=, etc.) and loop device resolution
are disabled for unprivileged users to avoid processing untrusted
input through tag resolution code paths before permission checks.
In umount.c, reject tag arguments and disable swapmatch for
restricted users. In libmount, skip source and loopdev swapmatch
lookups for restricted contexts as defense in depth.
Signed-off-by: Karel Zak <kzak@redhat.com>
try_loopdev:
fs = mnt_table_find_target(mountinfo, tgt, MNT_ITER_BACKWARD);
- if (!fs && mnt_context_is_swapmatch(cxt)) {
+ if (!fs && mnt_context_is_swapmatch(cxt)
+ && !mnt_context_is_restricted(cxt)) {
/*
* Maybe the option is source rather than target (sometimes
* people use e.g. "umount /dev/sda1")
}
}
- if (!fs && !loopdev && mnt_context_is_swapmatch(cxt)) {
+ if (!fs && !loopdev && mnt_context_is_swapmatch(cxt)
+ && !mnt_context_is_restricted(cxt)) {
/*
* Maybe the option is /path/file.img, try to convert to /dev/loopN
*/
Normally, only the superuser can umount filesystems. However, when _fstab_ contains the *user* option on a line, anybody can umount the corresponding filesystem. For more details see *mount*(8) man page.
+Non-root users must specify the filesystem by mountpoint path only. Device names, tags (LABEL=, UUID=, etc.) and loop device resolution are not supported for unprivileged users.
+
Since version 2.34 the *umount* command can be used to perform umount operation also for fuse filesystems if kernel mount table contains user's ID. In this case _fstab_ *user=* mount option is not required.
Since version 2.35 *umount* command does not exit when user permissions are inadequate by internal *libmount* security rules. It drops suid permissions and continue as regular unprivileged user. This can be used to support use-cases where root permissions are not necessary (e.g., fuse filesystems, user namespaces, etc).
while (argc--)
rc += umount_recursive(cxt, *argv++);
} else {
+ if (mnt_context_is_restricted(cxt)) {
+ int i;
+ for (i = 0; i < argc; i++) {
+ if (mnt_tag_is_valid(argv[i]))
+ errx(MNT_EX_USAGE,
+ _("%s: tags are not allowed for non-root users"),
+ argv[i]);
+ }
+ mnt_context_disable_swapmatch(cxt, 1);
+ }
+
while (argc--) {
char *path = *argv;
- if (mnt_context_is_restricted(cxt)
- && !mnt_tag_is_valid(path))
+ if (mnt_context_is_restricted(cxt))
path = sanitize_path(path);
rc += umount_one(cxt, path);