From: Karel Zak Date: Mon, 1 Jun 2026 13:22:53 +0000 (+0200) Subject: umount: restrict non-root users to mountpoint paths only X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77fe5f39cabfb2f21caf2c2edeeeb0ff4607bbce;p=thirdparty%2Futil-linux.git umount: restrict non-root users to mountpoint paths only 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 --- diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c index c59e1d303..78a01d61f 100644 --- a/libmount/src/context_umount.c +++ b/libmount/src/context_umount.c @@ -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 */ diff --git a/sys-utils/umount.8.adoc b/sys-utils/umount.8.adoc index e91211957..15ae35855 100644 --- a/sys-utils/umount.8.adoc +++ b/sys-utils/umount.8.adoc @@ -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). diff --git a/sys-utils/umount.c b/sys-utils/umount.c index 5e213c200..8198d574d 100644 --- a/sys-utils/umount.c +++ b/sys-utils/umount.c @@ -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);