[PATCH 4/6] nfsd: fix dentry ref leak on V4ROOT export filehandle lookup

From: Jeff Layton

Date: Sun May 31 2026 - 08:12:05 EST


nfsd_set_fh_dentry() leaks the dentry reference from
exportfs_decode_fh_raw() when the NFS3_FHSIZE or NFS_FHSIZE
switch cases detect NFSEXP_V4ROOT and goto out. The out: label
calls exp_put() but never dput(dentry), and fhp->fh_dentry was
never assigned so fh_put() cannot compensate.

A crafted NFSv3 filehandle targeting a V4ROOT export's fsid
triggers the leak on every request.

Fixes: 6e171106dce7 ("nfsd: move V4ROOT version check to nfsd_set_fh_dentry()")
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
fs/nfsd/nfsfh.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 429ca5c6ec08..b36915401758 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -344,15 +344,19 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net,
if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC)
fhp->fh_no_wcc = true;
fhp->fh_64bit_cookies = true;
- if (exp->ex_flags & NFSEXP_V4ROOT)
+ if (exp->ex_flags & NFSEXP_V4ROOT) {
+ dput(dentry);
goto out;
+ }
break;
case NFS_FHSIZE:
fhp->fh_no_wcc = true;
if (EX_WGATHER(exp))
fhp->fh_use_wgather = true;
- if (exp->ex_flags & NFSEXP_V4ROOT)
+ if (exp->ex_flags & NFSEXP_V4ROOT) {
+ dput(dentry);
goto out;
+ }
}

fhp->fh_dentry = dentry;

--
2.54.0