]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
umount: restrict non-root users to mountpoint paths only
authorKarel Zak <kzak@redhat.com>
Mon, 1 Jun 2026 13:22:53 +0000 (15:22 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 9 Jun 2026 08:40:39 +0000 (10:40 +0200)
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>
libmount/src/context_umount.c
sys-utils/umount.8.adoc
sys-utils/umount.c

index c59e1d30396e3b75c3d947b168baf2fe1c7b7ab9..78a01d61f2c74d1628fb56d4c35ec0099d6d78d4 100644 (file)
@@ -99,7 +99,8 @@ static int __mountinfo_find_umount_fs(struct libmnt_context *cxt,
 
 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")
@@ -128,7 +129,8 @@ try_loopdev:
                }
        }
 
-       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
                 */
index e91211957ca88a0dff3b19708f3ebc183910e91b..15ae358559dc51cfc5ef66c797abe9eb854c90b7 100644 (file)
@@ -121,6 +121,8 @@ include::man-common/help-version.adoc[]
 
 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).
index 5e213c20043c9faa797239160852193f9d6cefad..8198d574d91abdca7559af03b6168a6f46bb6029 100644 (file)
@@ -646,11 +646,21 @@ int main(int argc, char **argv)
                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);