Skip to content

Commit 2284215

Browse files
committed
clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns
jira KERNEL-386 cve CVE-2025-38499 Rebuild_History Non-Buildable kernel-6.12.0-124.21.1.el10_1 Rebuild_CHGLOG: - CVE-2025-38499 kernel: clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns (Abhi Das) [RHEL-129282] {CVE-2025-38499} Rebuild_FUZZ: 87.43% commit-author Al Viro <viro@zeniv.linux.org.uk> commit c28f922 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-6.12.0-124.21.1.el10_1/c28f922c.failed What we want is to verify there is that clone won't expose something hidden by a mount we wouldn't be able to undo. "Wouldn't be able to undo" may be a result of MNT_LOCKED on a child, but it may also come from lacking admin rights in the userns of the namespace mount belongs to. clone_private_mnt() checks the former, but not the latter. There's a number of rather confusing CAP_SYS_ADMIN checks in various userns during the mount, especially with the new mount API; they serve different purposes and in case of clone_private_mnt() they usually, but not always end up covering the missing check mentioned above. Reviewed-by: Christian Brauner <brauner@kernel.org> Reported-by: "Orlando, Noah" <Noah.Orlando@deshaw.com> Fixes: 427215d ("ovl: prevent private clone if bind mount is not allowed") Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> (cherry picked from commit c28f922) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/namespace.c
1 parent 48c4b75 commit 2284215

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns
2+
3+
jira KERNEL-386
4+
cve CVE-2025-38499
5+
Rebuild_History Non-Buildable kernel-6.12.0-124.21.1.el10_1
6+
Rebuild_CHGLOG: - CVE-2025-38499 kernel: clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns (Abhi Das) [RHEL-129282] {CVE-2025-38499}
7+
Rebuild_FUZZ: 87.43%
8+
commit-author Al Viro <viro@zeniv.linux.org.uk>
9+
commit c28f922c9dcee0e4876a2c095939d77fe7e15116
10+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
11+
Will be included in final tarball splat. Ref for failed cherry-pick at:
12+
ciq/ciq_backports/kernel-6.12.0-124.21.1.el10_1/c28f922c.failed
13+
14+
What we want is to verify there is that clone won't expose something
15+
hidden by a mount we wouldn't be able to undo. "Wouldn't be able to undo"
16+
may be a result of MNT_LOCKED on a child, but it may also come from
17+
lacking admin rights in the userns of the namespace mount belongs to.
18+
19+
clone_private_mnt() checks the former, but not the latter.
20+
21+
There's a number of rather confusing CAP_SYS_ADMIN checks in various
22+
userns during the mount, especially with the new mount API; they serve
23+
different purposes and in case of clone_private_mnt() they usually,
24+
but not always end up covering the missing check mentioned above.
25+
26+
Reviewed-by: Christian Brauner <brauner@kernel.org>
27+
Reported-by: "Orlando, Noah" <Noah.Orlando@deshaw.com>
28+
Fixes: 427215d85e8d ("ovl: prevent private clone if bind mount is not allowed")
29+
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
30+
(cherry picked from commit c28f922c9dcee0e4876a2c095939d77fe7e15116)
31+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
32+
33+
# Conflicts:
34+
# fs/namespace.c
35+
diff --cc fs/namespace.c
36+
index da767032a0a1,1c54c16c7bab..000000000000
37+
--- a/fs/namespace.c
38+
+++ b/fs/namespace.c
39+
@@@ -2254,21 -2488,37 +2254,33 @@@ struct vfsmount *clone_private_mount(co
40+
struct mount *old_mnt = real_mount(path->mnt);
41+
struct mount *new_mnt;
42+
43+
- guard(rwsem_read)(&namespace_sem);
44+
-
45+
+ down_read(&namespace_sem);
46+
if (IS_MNT_UNBINDABLE(old_mnt))
47+
- return ERR_PTR(-EINVAL);
48+
+ goto invalid;
49+
50+
- /*
51+
- * Make sure the source mount is acceptable.
52+
- * Anything mounted in our mount namespace is allowed.
53+
- * Otherwise, it must be the root of an anonymous mount
54+
- * namespace, and we need to make sure no namespace
55+
- * loops get created.
56+
- */
57+
- if (!check_mnt(old_mnt)) {
58+
- if (!is_mounted(&old_mnt->mnt) ||
59+
- !is_anon_ns(old_mnt->mnt_ns) ||
60+
- mnt_has_parent(old_mnt))
61+
- return ERR_PTR(-EINVAL);
62+
+ if (!check_mnt(old_mnt))
63+
+ goto invalid;
64+
65+
++<<<<<<< HEAD
66+
+ if (has_locked_children(old_mnt, path->dentry))
67+
+ goto invalid;
68+
++=======
69+
+ if (!check_for_nsfs_mounts(old_mnt))
70+
+ return ERR_PTR(-EINVAL);
71+
+ }
72+
+
73+
+ if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN))
74+
+ return ERR_PTR(-EPERM);
75+
+
76+
+ if (__has_locked_children(old_mnt, path->dentry))
77+
+ return ERR_PTR(-EINVAL);
78+
++>>>>>>> c28f922c9dce (clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the right userns)
79+
80+
new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
81+
+ up_read(&namespace_sem);
82+
+
83+
if (IS_ERR(new_mnt))
84+
- return ERR_PTR(-EINVAL);
85+
+ return ERR_CAST(new_mnt);
86+
87+
/* Longterm mount to be removed by kern_unmount*() */
88+
new_mnt->mnt_ns = MNT_NS_INTERNAL;
89+
* Unmerged path fs/namespace.c

0 commit comments

Comments
 (0)