Re: [PATCH] ceph: fix refcount leak in ceph_readdir()
From: Viacheslav Dubeyko
Date: Tue Jun 30 2026 - 11:45:58 EST
On Thu, 2026-06-11 at 22:40 +0800, WenTao Liang wrote:
> The ceph_readdir() function allocates a ceph_mds_request via
> ceph_mdsc_create_request() and stores it in dfi->last_readdir. In
> the directory entry processing loop, if the entry's offset is less
> than ctx->pos or if the inode pointer is unexpectedly NULL, the
> function returns -EIO without releasing the reference held by
> dfi->last_readdir, causing a refcount leak.
>
> Fix this by adding ceph_mdsc_put_request(dfi->last_readdir) before
> returning on these error paths. Also set dfi->last_readdir to NULL
> for safety, matching the cleanup done at the normal exit.
>
> Cc: stable@xxxxxxxxxxxxxxx
> Fixes: af9ffa6df7e3 ("ceph: add support to readdir for encrypted
> names")
> Signed-off-by: WenTao Liang <vulab@xxxxxxxxxxx>
> ---
> fs/ceph/dir.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> index 27ce9e55e947..ef9e92e362d3 100644
> --- a/fs/ceph/dir.c
> +++ b/fs/ceph/dir.c
> @@ -546,11 +546,16 @@ static int ceph_readdir(struct file *file,
> struct dir_context *ctx)
> pr_warn_client(cl,
> "%p %llx.%llx rde->offset 0x%llx
> ctx->pos 0x%llx\n",
> inode, ceph_vinop(inode), rde-
> >offset, ctx->pos);
> + ceph_mdsc_put_request(dfi->last_readdir);
> + dfi->last_readdir = NULL;
> return -EIO;
> }
>
> - if (WARN_ON_ONCE(!rde->inode.in))
> + if (WARN_ON_ONCE(!rde->inode.in)) {
> + ceph_mdsc_put_request(dfi->last_readdir);
> + dfi->last_readdir = NULL;
> return -EIO;
> + }
>
> ctx->pos = rde->offset;
> doutc(cl, "%p %llx.%llx (%d/%d) -> %llx '%.*s'
> %p\n", inode,
Makes sense to me.
Reviewed-by: Viacheslav Dubeyko <slava@xxxxxxxxxxx>
Thanks,
Slava.