CEPH filesystem development
 help / color / mirror / Atom feed
* [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