View Issue Details

IDProjectCategoryView StatusLast Update
0000668AlmaLinux-10Generalpublic2026-09-09 13:15
Reportervaclove Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
Status newResolutionopen 
Summary0000668: OOM on kernel 6.12.0-211.x: CephFS clients with path-restricted MDS caps leak unreclaimable slab (CVE-2024-56563,CVE-2025-21737)
DescriptionAlmaLinux 10 kernels 6.12.0-211.38.1 and 6.12.0-211.49.1 (and 6.12.0-211.50.1, per its
changelog) leak kernel memory on every file open/setattr/rename on a CephFS mount when the
client key carries an MDS cap of the form `allow rw path=/something` and the mount is that
subpath. Two upstream bugs in fs/ceph/mds_client.c, both introduced by 596afb0b8933
("ceph: add ceph_mds_check_access() helper", v6.10), both still present in the el10 source:

* CVE-2024-56563 — ceph_mds_check_access() calls get_current_cred() and never put_cred().
  Fixed upstream in c5cf420303256dcd6ff175643e9e9558543c2047 (v6.13, stable v6.12.4).
* CVE-2025-21737 — ceph_mds_auth_match() kmallocs the "<mountpath>/<path>" string for the
  cap comparison and frees it only on the two mismatch branches; the match path leaks it.
  Fixed upstream in 3b7d93db450e9d8ead80d75e2a303248f1528c35 (v6.13.3, stable v6.12.14).

Red Hat lists these as "Fix deferred" and "Affected" for RHEL 10 respectively, so they will
not arrive via a rebase. RHEL 9's 5.14 kernel predates the code and is unaffected. Debian 13
(6.12.85) carries both. AlmaLinux 6.12.0-211.50.1 backported the neighbouring
ceph_mdsc_build_path leak (CVE-2026-43419) but not these two.

Observed in production: three Dovecot IMAP backends (8 GB RAM, CephFS mount :/mail, key with
`mds allow rw path=/mail`) grow SUnreclaim by 130-300 MB/day — cred, kmalloc-64/96/128 and
kmalloc-cg-32 — until the OOM killer loops. One host logged 161 OOM kills in a day, killing
dovecot workers, node_exporter and zabbix_agent2, while `free` showed userspace nearly empty.
Only a reboot recovers the memory, so each host needs rebooting every 6-8 weeks. Any
AlmaLinux 10 CephFS client with a path-restricted key is affected.
Steps To Reproduce1. AlmaLinux 10, kernel 6.12.0-211.49.1.el10_2.
2. CephX key with `mds allow rw path=/x`; mount that subpath: `mount -t ceph <mons>:/x /mnt -o name=<key>`.
3. Generate file opens under the mount, e.g. `for i in $(seq 100000); do cat /mnt/somefile >/dev/null; done`.
4. Watch `grep SUnreclaim /proc/meminfo` and `slabtop -s c`: cred and kmalloc-64/96/128 grow
   linearly with the number of opens and never shrink.
Additional InformationBoth fixes are a few lines. Applied against the current CentOS Stream 10 fs/ceph/mds_client.c:

* The CVE-2025-21737 patch from linux-6.12.y applies with a line offset only.
* The CVE-2024-56563 patch needs `-C1` or a trivial context fixup: el10 lacks the preceding
  upstream commit that passes the cred pointer into ceph_mds_auth_match(), so the context line
  differs. The fix itself is two put_cred() calls and does not depend on that commit.

Patches attached, taken from the linux-6.12.y stable branch.
TagsNo tags attached.
Attached Files
cve-2024-56563.patch (1,471 bytes)   
From e3d1c9e2b811f13bdbbb962c2b17a6091c28522c Mon Sep 17 00:00:00 2001
From: Max Kellermann <max.kellermann@ionos.com>
Date: Sat, 23 Nov 2024 08:21:21 +0100
Subject: ceph: fix cred leak in ceph_mds_check_access()

commit c5cf420303256dcd6ff175643e9e9558543c2047 upstream.

get_current_cred() increments the reference counter, but the
put_cred() call was missing.

Cc: stable@vger.kernel.org
Fixes: 596afb0b8933 ("ceph: add ceph_mds_check_access() helper")
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/ceph/mds_client.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index ca9b96ae0646e..cf92b75745e2a 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -5736,6 +5736,7 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
 
 		err = ceph_mds_auth_match(mdsc, s, cred, tpath);
 		if (err < 0) {
+			put_cred(cred);
 			return err;
 		} else if (err > 0) {
 			/* always follow the last auth caps' permision */
@@ -5751,6 +5752,8 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
 		}
 	}
 
+	put_cred(cred);
+
 	doutc(cl, "root_squash_perms %d, rw_perms_s %p\n", root_squash_perms,
 	      rw_perms_s);
 	if (root_squash_perms && rw_perms_s == NULL) {
-- 
cgit 1.3.1-korg

cve-2024-56563.patch (1,471 bytes)   
cve-2025-21737.patch (3,796 bytes)   
From 2b6086c5efe5c7bd6e0eb440d96c26ca0d20d9d7 Mon Sep 17 00:00:00 2001
From: Antoine Viallon <antoine@lesviallon.fr>
Date: Tue, 14 Jan 2025 23:45:14 +0100
Subject: ceph: fix memory leak in ceph_mds_auth_match()

commit 3b7d93db450e9d8ead80d75e2a303248f1528c35 upstream.

We now free the temporary target path substring allocation on every
possible branch, instead of omitting the default branch.  In some
cases, a memory leak occured, which could rapidly crash the system
(depending on how many file accesses were attempted).

This was detected in production because it caused a continuous memory
growth, eventually triggering kernel OOM and completely hard-locking
the kernel.

Relevant kmemleak stacktrace:

    unreferenced object 0xffff888131e69900 (size 128):
      comm "git", pid 66104, jiffies 4295435999
      hex dump (first 32 bytes):
        76 6f 6c 75 6d 65 73 2f 63 6f 6e 74 61 69 6e 65  volumes/containe
        72 73 2f 67 69 74 65 61 2f 67 69 74 65 61 2f 67  rs/gitea/gitea/g
      backtrace (crc 2f3bb450):
        [<ffffffffaa68fb49>] __kmalloc_noprof+0x359/0x510
        [<ffffffffc32bf1df>] ceph_mds_check_access+0x5bf/0x14e0 [ceph]
        [<ffffffffc3235722>] ceph_open+0x312/0xd80 [ceph]
        [<ffffffffaa7dd786>] do_dentry_open+0x456/0x1120
        [<ffffffffaa7e3729>] vfs_open+0x79/0x360
        [<ffffffffaa832875>] path_openat+0x1de5/0x4390
        [<ffffffffaa834fcc>] do_filp_open+0x19c/0x3c0
        [<ffffffffaa7e44a1>] do_sys_openat2+0x141/0x180
        [<ffffffffaa7e4945>] __x64_sys_open+0xe5/0x1a0
        [<ffffffffac2cc2f7>] do_syscall_64+0xb7/0x210
        [<ffffffffac400130>] entry_SYSCALL_64_after_hwframe+0x77/0x7f

It can be triggered by mouting a subdirectory of a CephFS filesystem,
and then trying to access files on this subdirectory with an auth token
using a path-scoped capability:

    $ ceph auth get client.services
    [client.services]
            key = REDACTED
            caps mds = "allow rw fsname=cephfs path=/volumes/"
            caps mon = "allow r fsname=cephfs"
            caps osd = "allow rw tag cephfs data=cephfs"

    $ cat /proc/self/mounts
    services@[REDACTED].cephfs=/volumes/containers /ceph/containers ceph rw,noatime,name=services,secret=<hidden>,ms_mode=prefer-crc,mount_timeout=300,acl,mon_addr=[REDACTED]:3300,recover_session=clean 0 0

    $ seq 1 1000000 | xargs -P32 --replace={} touch /ceph/containers/file-{} && \
    seq 1 1000000 | xargs -P32 --replace={} cat /ceph/containers/file-{}

[ idryomov: combine if statements, rename rc to path_matched and make
            it a bool, formatting ]

Cc: stable@vger.kernel.org
Fixes: 596afb0b8933 ("ceph: add ceph_mds_check_access() helper")
Signed-off-by: Antoine Viallon <antoine@lesviallon.fr>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/ceph/mds_client.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 785fe489ef4b8..ae37f0e24c996 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -5690,18 +5690,18 @@ static int ceph_mds_auth_match(struct ceph_mds_client *mdsc,
 			 *
 			 * All the other cases                       --> mismatch
 			 */
+			bool path_matched = true;
 			char *first = strstr(_tpath, auth->match.path);
-			if (first != _tpath) {
-				if (free_tpath)
-					kfree(_tpath);
-				return 0;
+			if (first != _tpath ||
+			    (tlen > len && _tpath[len] != '/')) {
+				path_matched = false;
 			}
 
-			if (tlen > len && _tpath[len] != '/') {
-				if (free_tpath)
-					kfree(_tpath);
+			if (free_tpath)
+				kfree(_tpath);
+
+			if (!path_matched)
 				return 0;
-			}
 		}
 	}
 
-- 
cgit 1.3.1-korg

cve-2025-21737.patch (3,796 bytes)   

Activities

Issue History

Date Modified Username Field Change
2026-09-09 13:15 vaclove New Issue
2026-09-09 13:15 vaclove File Added: cve-2024-56563.patch
2026-09-09 13:15 vaclove File Added: cve-2025-21737.patch