Re: [PATCH] ceph: fix use-after-dereference of NULL ci in __ceph_remove_cap()
From: Viacheslav Dubeyko
Date: Tue Jul 14 2026 - 13:46:47 EST
On Tue, 2026-07-14 at 14:20 +0800, Xiubo Li via B4 Relay wrote:
> From: Xiubo Li <xiubo.li@xxxxxxxxx>
>
> The NULL check for "ci" in __ceph_remove_cap() was dead code because
> ci was dereferenced via &ci->netfs.inode before the check, and
> cap->session was dereferenced via session->s_mdsc->fsc->client even
> earlier. On a double-remove, both cap->ci and cap->session are set
> to NULL by the first call, so the second call would crash before
> ever reaching the guard.
>
> Move ci, session, cl, and inode initializations after the NULL check
> so that the early-return actually works.
>
> Signed-off-by: Xiubo Li <xiubo.li@xxxxxxxxx>
> ---
> fs/ceph/caps.c | 17 ++++++++++-------
> 1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
> index f8d898ad091e..8568edf494b5 100644
> --- a/fs/ceph/caps.c
> +++ b/fs/ceph/caps.c
> @@ -1154,18 +1154,21 @@ int ceph_is_any_caps(struct inode *inode)
> */
> void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
> {
> - struct ceph_mds_session *session = cap->session;
> - struct ceph_client *cl = session->s_mdsc->fsc->client;
> - struct ceph_inode_info *ci = cap->ci;
> - struct inode *inode = &ci->netfs.inode;
> + struct ceph_mds_session *session;
> + struct ceph_client *cl;
> + struct ceph_inode_info *ci;
> + struct inode *inode;
> struct ceph_mds_client *mdsc;
> int removed = 0;
>
> /* 'ci' being NULL means the remove have already occurred */
> - if (!ci) {
> - doutc(cl, "inode is NULL\n");
> + ci = cap->ci;
> + if (!ci)
> return;
> - }
> +
> + session = cap->session;
> + cl = session->s_mdsc->fsc->client;
> + inode = &ci->netfs.inode;
>
> lockdep_assert_held(&ci->i_ceph_lock);
>
>
> ---
> base-commit: fc67edb66b3c9924c4e0bb366a92b32ea13c526a
> change-id: 20260714-ceph-fix-remove-cap-cf7d8a7a242a
>
> Best regards,
> --
> Xiubo Li <xiubo.li@xxxxxxxxx>
Makes sense.
Reviewed-by: Viacheslav Dubeyko <slava@xxxxxxxxxxx>
Thanks,
Slava.