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.