* [PATCH] ceph: lock mutex in ceph_mds_check_access()
@ 2026-08-24 16:47 Max Kellermann
2026-08-25 12:41 ` Alex Markuze
2026-08-27 9:23 ` [PATCH] " Xiubo Li
0 siblings, 2 replies; 3+ messages in thread
From: Max Kellermann @ 2026-08-24 16:47 UTC (permalink / raw)
To: idryomov, amarkuze, xiubo.li, ceph-devel, linux-kernel
Cc: Max Kellermann, stable
MDS session OPEN handling replaces mdsc->s_cap_auths under
mdsc->mutex, freeing the previous array and its strings.
ceph_mds_check_access() traverses this array without holding the
mutex. A concurrent session reopen can therefore free the array while
it is being inspected, resulting in a use-after-free like this:
Unable to handle kernel paging request at virtual address 003aaad64b2c8bb9
[...]
Internal error: Oops: 0000000096000004 [#1] SMP
Modules linked in:
CPU: 56 UID: 2953037534 PID: 1253231 Comm: php-cgi8.4 Not tainted 6.18.45-i2-ampere #1146 NONE
[..]
pc : ceph_mds_check_access+0xd4/0x550
lr : ceph_mds_check_access+0xc8/0x550
[...]
Call trace:
ceph_mds_check_access+0xd4/0x550 (P)
ceph_atomic_open+0x138/0xbe8
path_openat+0xa24/0xfa8
do_filp_open+0x94/0x158
do_sys_openat2+0x88/0xf8
Fixes: 596afb0b8933 ("ceph: add ceph_mds_check_access() helper")
Cc: stable@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
fs/ceph/mds_client.c | 4 ++++
fs/ceph/mds_client.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 3c692ad02c85..0348e8b848ff 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -6532,11 +6532,13 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
doutc(cl, "tpath '%s', mask %d, caller_uid %d, caller_gid %d\n",
tpath, mask, caller_uid, caller_gid);
+ mutex_lock(&mdsc->mutex);
for (i = 0; i < mdsc->s_cap_auths_num; i++) {
struct ceph_mds_cap_auth *s = &mdsc->s_cap_auths[i];
err = ceph_mds_auth_match(mdsc, s, cred, tpath);
if (err < 0) {
+ mutex_unlock(&mdsc->mutex);
put_cred(cred);
return err;
} else if (err > 0) {
@@ -6558,6 +6560,7 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
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) {
+ mutex_unlock(&mdsc->mutex);
doutc(cl, "access allowed\n");
return 0;
}
@@ -6572,6 +6575,7 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
!!(mask & MAY_READ), !!(mask & MAY_WRITE));
}
doutc(cl, "access denied\n");
+ mutex_unlock(&mdsc->mutex);
return -EACCES;
}
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 0ece4c9e3529..8774c7d7d18d 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -603,6 +603,7 @@ struct ceph_mds_client {
struct rw_semaphore pool_perm_rwsem;
struct rb_root pool_perm_tree;
+ /* protected by mutex */
u32 s_cap_auths_num;
struct ceph_mds_cap_auth *s_cap_auths;
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: ceph: lock mutex in ceph_mds_check_access()
2026-08-24 16:47 [PATCH] ceph: lock mutex in ceph_mds_check_access() Max Kellermann
@ 2026-08-25 12:41 ` Alex Markuze
2026-08-27 9:23 ` [PATCH] " Xiubo Li
1 sibling, 0 replies; 3+ messages in thread
From: Alex Markuze @ 2026-08-25 12:41 UTC (permalink / raw)
To: Max Kellermann; +Cc: ceph-devel
Hi Max,
Thanks for the patch.
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
--
Alex Markuze
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ceph: lock mutex in ceph_mds_check_access()
2026-08-24 16:47 [PATCH] ceph: lock mutex in ceph_mds_check_access() Max Kellermann
2026-08-25 12:41 ` Alex Markuze
@ 2026-08-27 9:23 ` Xiubo Li
1 sibling, 0 replies; 3+ messages in thread
From: Xiubo Li @ 2026-08-27 9:23 UTC (permalink / raw)
To: Max Kellermann; +Cc: idryomov, amarkuze, ceph-devel, linux-kernel, stable
LGTM.
Reviewed-by: Xiubo Li <xiubo.li@clyso.com>
On Mon, 24 Aug 2026 at 09:47, Max Kellermann <max.kellermann@ionos.com> wrote:
>
> MDS session OPEN handling replaces mdsc->s_cap_auths under
> mdsc->mutex, freeing the previous array and its strings.
>
> ceph_mds_check_access() traverses this array without holding the
> mutex. A concurrent session reopen can therefore free the array while
> it is being inspected, resulting in a use-after-free like this:
>
> Unable to handle kernel paging request at virtual address 003aaad64b2c8bb9
> [...]
> Internal error: Oops: 0000000096000004 [#1] SMP
> Modules linked in:
> CPU: 56 UID: 2953037534 PID: 1253231 Comm: php-cgi8.4 Not tainted 6.18.45-i2-ampere #1146 NONE
> [..]
> pc : ceph_mds_check_access+0xd4/0x550
> lr : ceph_mds_check_access+0xc8/0x550
> [...]
> Call trace:
> ceph_mds_check_access+0xd4/0x550 (P)
> ceph_atomic_open+0x138/0xbe8
> path_openat+0xa24/0xfa8
> do_filp_open+0x94/0x158
> do_sys_openat2+0x88/0xf8
>
> Fixes: 596afb0b8933 ("ceph: add ceph_mds_check_access() helper")
> Cc: stable@vger.kernel.org
> Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
> ---
> fs/ceph/mds_client.c | 4 ++++
> fs/ceph/mds_client.h | 1 +
> 2 files changed, 5 insertions(+)
>
> diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> index 3c692ad02c85..0348e8b848ff 100644
> --- a/fs/ceph/mds_client.c
> +++ b/fs/ceph/mds_client.c
> @@ -6532,11 +6532,13 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
> doutc(cl, "tpath '%s', mask %d, caller_uid %d, caller_gid %d\n",
> tpath, mask, caller_uid, caller_gid);
>
> + mutex_lock(&mdsc->mutex);
> for (i = 0; i < mdsc->s_cap_auths_num; i++) {
> struct ceph_mds_cap_auth *s = &mdsc->s_cap_auths[i];
>
> err = ceph_mds_auth_match(mdsc, s, cred, tpath);
> if (err < 0) {
> + mutex_unlock(&mdsc->mutex);
> put_cred(cred);
> return err;
> } else if (err > 0) {
> @@ -6558,6 +6560,7 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
> 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) {
> + mutex_unlock(&mdsc->mutex);
> doutc(cl, "access allowed\n");
> return 0;
> }
> @@ -6572,6 +6575,7 @@ int ceph_mds_check_access(struct ceph_mds_client *mdsc, char *tpath, int mask)
> !!(mask & MAY_READ), !!(mask & MAY_WRITE));
> }
> doutc(cl, "access denied\n");
> + mutex_unlock(&mdsc->mutex);
> return -EACCES;
> }
>
> diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
> index 0ece4c9e3529..8774c7d7d18d 100644
> --- a/fs/ceph/mds_client.h
> +++ b/fs/ceph/mds_client.h
> @@ -603,6 +603,7 @@ struct ceph_mds_client {
> struct rw_semaphore pool_perm_rwsem;
> struct rb_root pool_perm_tree;
>
> + /* protected by mutex */
> u32 s_cap_auths_num;
> struct ceph_mds_cap_auth *s_cap_auths;
>
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-27 9:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 16:47 [PATCH] ceph: lock mutex in ceph_mds_check_access() Max Kellermann
2026-08-25 12:41 ` Alex Markuze
2026-08-27 9:23 ` [PATCH] " Xiubo Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox