From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
"Lai, Yi" <yi1.lai@linux.intel.com>,
Tycho Andersen <tycho@tycho.pizza>,
Andrei Vagin <avagin@google.com>,
Pavel Tikhomirov <snorcht@gmail.com>
Subject: [PATCH 3/4] use uniform permission checks for all mount propagation changes
Date: Sat, 16 Aug 2025 00:35:24 +0100 [thread overview]
Message-ID: <20250815233524.GC2117906@ZenIV> (raw)
In-Reply-To: <20250815233316.GS222315@ZenIV>
do_change_type() and do_set_group() are operating on different
aspects of the same thing - propagation graph. The latter
asks for mounts involved to be mounted in namespace(s) the caller
has CAP_SYS_ADMIN for. The former is a mess - originally it
didn't even check that mount *is* mounted. That got fixed,
but the resulting check turns out to be too strict for userland -
in effect, we check that mount is in our namespace, having already
checked that we have CAP_SYS_ADMIN there.
What we really need (in both cases) is
* we only touch mounts that are mounted. Hard requirement,
data corruption if that's get violated.
* we don't allow to mess with a namespace unless you already
have enough permissions to do so (i.e. CAP_SYS_ADMIN in its userns).
That's an equivalent of what do_set_group() does; let's extract that
into a helper (may_change_propagation()) and use it in both
do_set_group() and do_change_type().
Fixes: 12f147ddd6de "do_change_type(): refuse to operate on unmounted/not ours mounts"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/namespace.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 1c97f93d1865..88db58061919 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2859,6 +2859,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
return attach_recursive_mnt(mnt, p, mp);
}
+static int may_change_propagation(const struct mount *m)
+{
+ struct mnt_namespace *ns = m->mnt_ns;
+
+ // it must be mounted in some namespace
+ if (IS_ERR_OR_NULL(ns)) // is_mounted()
+ return -EINVAL;
+ // and the caller must be admin in userns of that namespace
+ if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
+ return -EPERM;
+ return 0;
+}
+
/*
* Sanity check the flags to change_mnt_propagation.
*/
@@ -2895,10 +2908,10 @@ static int do_change_type(struct path *path, int ms_flags)
return -EINVAL;
namespace_lock();
- if (!check_mnt(mnt)) {
- err = -EINVAL;
+ err = may_change_propagation(mnt);
+ if (err)
goto out_unlock;
- }
+
if (type == MS_SHARED) {
err = invent_group_ids(mnt, recurse);
if (err)
@@ -3344,18 +3357,11 @@ static int do_set_group(struct path *from_path, struct path *to_path)
namespace_lock();
- err = -EINVAL;
- /* To and From must be mounted */
- if (!is_mounted(&from->mnt))
- goto out;
- if (!is_mounted(&to->mnt))
- goto out;
-
- err = -EPERM;
- /* We should be allowed to modify mount namespaces of both mounts */
- if (!ns_capable(from->mnt_ns->user_ns, CAP_SYS_ADMIN))
+ err = may_change_propagation(from);
+ if (err)
goto out;
- if (!ns_capable(to->mnt_ns->user_ns, CAP_SYS_ADMIN))
+ err = may_change_propagation(to);
+ if (err)
goto out;
err = -EINVAL;
--
2.47.2
next prev parent reply other threads:[~2025-08-15 23:35 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-15 23:33 [PATCHES][RFC][CFT] mount fixes Al Viro
2025-08-15 23:34 ` [PATCH 1/4] fix the softlockups in attach_recursive_mnt() Al Viro
2025-08-19 10:18 ` Christian Brauner
2025-08-15 23:34 ` [PATCH 2/4] propagate_umount(): only surviving overmounts should be remounted Al Viro
2025-08-19 10:19 ` Christian Brauner
2025-08-15 23:35 ` Al Viro [this message]
2025-08-16 18:28 ` [PATCH 3/4] use uniform permission checks for all mount propagation changes Andrei Vagin
2025-08-19 4:44 ` Pavel Tikhomirov
2025-08-19 10:20 ` Christian Brauner
2025-08-15 23:36 ` [PATCH 4/4] change_mnt_propagation(): calculate propagation source only if we'll need it Al Viro
2025-08-19 10:20 ` Christian Brauner
2025-08-16 15:58 ` [PATCHES][RFC][CFT] mount fixes Al Viro
2025-08-19 16:12 ` [git pull] " Al Viro
2025-08-19 17:31 ` Linus Torvalds
2025-08-19 17:33 ` pr-tracker-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250815233524.GC2117906@ZenIV \
--to=viro@zeniv.linux.org.uk \
--cc=avagin@google.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=snorcht@gmail.com \
--cc=torvalds@linux-foundation.org \
--cc=tycho@tycho.pizza \
--cc=yi1.lai@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.