Skip to content

Commit baa78f9

Browse files
author
Ian Kent
committed
use uniform permission checks for all mount propagation changes
JIRA: https://issues.redhat.com/browse/RHEL-107307 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") which depends on a number of other patches that add function getname_maybe_null() among other changes. But what these two patches do to resolve the CVE is well defined and without further dependencies. In particular this patch is an additional patch to the original patch to resolve the CVE and is needed to prevent regressions that would very likely be seen in our products in the same way as were seen and reported upstream. commit cffd044 Author: Al Viro <viro@zeniv.linux.org.uk> 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 <avagin@gmail.com> Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Tested-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Ian Kent <ikent@redhat.com>
1 parent 08937af commit baa78f9

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

fs/namespace.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,6 +2673,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
26732673
return attach_recursive_mnt(mnt, p, mp, 0);
26742674
}
26752675

2676+
static int may_change_propagation(const struct mount *m)
2677+
{
2678+
struct mnt_namespace *ns = m->mnt_ns;
2679+
2680+
// it must be mounted in some namespace
2681+
if (IS_ERR_OR_NULL(ns)) // is_mounted()
2682+
return -EINVAL;
2683+
// and the caller must be admin in userns of that namespace
2684+
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
2685+
return -EPERM;
2686+
return 0;
2687+
}
2688+
26762689
/*
26772690
* Sanity check the flags to change_mnt_propagation.
26782691
*/
@@ -2709,10 +2722,10 @@ static int do_change_type(struct path *path, int ms_flags)
27092722
return -EINVAL;
27102723

27112724
namespace_lock();
2712-
if (!check_mnt(mnt)) {
2713-
err = -EINVAL;
2725+
err = may_change_propagation(mnt);
2726+
if (err)
27142727
goto out_unlock;
2715-
}
2728+
27162729
if (type == MS_SHARED) {
27172730
err = invent_group_ids(mnt, recurse);
27182731
if (err)
@@ -3106,18 +3119,11 @@ static int do_set_group(struct path *from_path, struct path *to_path)
31063119

31073120
namespace_lock();
31083121

3109-
err = -EINVAL;
3110-
/* To and From must be mounted */
3111-
if (!is_mounted(&from->mnt))
3112-
goto out;
3113-
if (!is_mounted(&to->mnt))
3114-
goto out;
3115-
3116-
err = -EPERM;
3117-
/* We should be allowed to modify mount namespaces of both mounts */
3118-
if (!ns_capable(from->mnt_ns->user_ns, CAP_SYS_ADMIN))
3122+
err = may_change_propagation(from);
3123+
if (err)
31193124
goto out;
3120-
if (!ns_capable(to->mnt_ns->user_ns, CAP_SYS_ADMIN))
3125+
err = may_change_propagation(to);
3126+
if (err)
31213127
goto out;
31223128

31233129
err = -EINVAL;

0 commit comments

Comments
 (0)