Skip to content

Commit 260db79

Browse files
author
Ian Kent
committed
use uniform permission checks for all mount propagation changes
JIRA: https://issues.redhat.com/browse/RHEL-107304 Upstream status: Linus CVE: CVE-2025-38498 Conflicts: There is a fuzz 1 for hunk #1 in fs/namespace.c. This is due to the lack of upstream commit 86b1da9 ("attach_recursive_mnt(): get rid of flags entirely"), and some earlier changes, which depends on a number of other patches that add function getname_maybe_null() among other changes. But the patches do to resolve the CVE and are well defined and without dependencies. Note that hunk #3 has been dropped from the upstream patch becuase it patched function do_set_group() which belongs to functionality (also described in the description of the upstream patch) not present in RHEL-9 and deemed no relevant to the CVE we are resolving. commit cffd044 Author: Al Viro <[email protected]> Date: Thu Aug 14 01:44:31 2025 -0400 use uniform permission checks for all mount propagation changes 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 * only touch mounts that are mounted. That's a must-have constraint - data corruption happens if it get violated. * 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: 12f147d "do_change_type(): refuse to operate on unmounted/not ours mounts" Acked-by: Andrei Vagin <[email protected]> Reviewed-by: Pavel Tikhomirov <[email protected]> Tested-by: Pavel Tikhomirov <[email protected]> Reviewed-by: Christian Brauner <[email protected]> Signed-off-by: Al Viro <[email protected]> Signed-off-by: Ian Kent <[email protected]>
1 parent b897333 commit 260db79

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

fs/namespace.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
22942294
return attach_recursive_mnt(mnt, p, mp, false);
22952295
}
22962296

2297+
static int may_change_propagation(const struct mount *m)
2298+
{
2299+
struct mnt_namespace *ns = m->mnt_ns;
2300+
2301+
// it must be mounted in some namespace
2302+
if (IS_ERR_OR_NULL(ns)) // is_mounted()
2303+
return -EINVAL;
2304+
// and the caller must be admin in userns of that namespace
2305+
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
2306+
return -EPERM;
2307+
return 0;
2308+
}
2309+
22972310
/*
22982311
* Sanity check the flags to change_mnt_propagation.
22992312
*/
@@ -2330,10 +2343,10 @@ static int do_change_type(struct path *path, int ms_flags)
23302343
return -EINVAL;
23312344

23322345
namespace_lock();
2333-
if (!check_mnt(mnt)) {
2334-
err = -EINVAL;
2346+
err = may_change_propagation(mnt);
2347+
if (err)
23352348
goto out_unlock;
2336-
}
2349+
23372350
if (type == MS_SHARED) {
23382351
err = invent_group_ids(mnt, recurse);
23392352
if (err)

0 commit comments

Comments
 (0)