From: WenTao Liang Date: Thu, 11 Jun 2026 14:40:07 +0000 (+0800) Subject: ceph: fix refcount leak in ceph_readdir() X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c3e64079d8b9663e3998d0caac9aba915b6b93ae;p=thirdparty%2Fkernel%2Flinux.git ceph: fix refcount leak in ceph_readdir() 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@vger.kernel.org Fixes: af9ffa6df7e3 ("ceph: add support to readdir for encrypted names") Signed-off-by: WenTao Liang Reviewed-by: Viacheslav Dubeyko Reviewed-by: Alex Markuze Signed-off-by: Ilya Dryomov --- 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 @@ more: 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,