The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=9cd3860c10b6afaaaeb118dafc166ab168bc9083
commit 9cd3860c10b6afaaaeb118dafc166ab168bc9083 Author: Rick Macklem <rmack...@freebsd.org> AuthorDate: 2025-08-15 19:11:08 +0000 Commit: Rick Macklem <rmack...@freebsd.org> CommitDate: 2025-08-15 19:11:08 +0000 nfsd: Fix slow leaks of NAMEI buffers Commit 5b5b7e2ca2fa changed namei()s behaviour such that it does not free the NAMEI buffer unless returning an error. The nfsd was not fixed for this. Fortunately, the only leak would be one NAMEI buffer each time mountd(8) reloads the exports. (There were also leaks in the pNFS server configuration, but almost no one uses it.) This patch fixes the leaks by adding NDFREE_PNBUF() macros in the appropriate places. MFC after: 2 weeks Discussed with: kib Fixes: 5b5b7e2ca2fa ("vfs: always retain path buffer after lookup") --- sys/fs/nfsserver/nfs_nfsdport.c | 1 + sys/fs/nfsserver/nfs_nfsdstate.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 496cac263fa0..b2966934f9b7 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3751,6 +3751,7 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p) NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, nfsexargp->fspec); if ((error = namei(&nd)) != 0) goto out; + NDFREE_PNBUF(&nd); error = nfsvno_getfh(nd.ni_vp, &fh, p); vrele(nd.ni_vp); if (!error) { diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 36e3ce7b7142..111b0f26d0b5 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -7731,6 +7731,7 @@ nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p, NFSD_DEBUG(4, "lookup=%d\n", error); if (error != 0) return (error); + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VDIR) { vput(nd.ni_vp); NFSD_DEBUG(4, "dspath not dir\n"); @@ -7767,6 +7768,7 @@ nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p, NFSD_DEBUG(4, "dsdirpath=%s lookup=%d\n", dsdirpath, error); if (error != 0) break; + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VDIR) { vput(nd.ni_vp); error = ENOTDIR; @@ -7795,6 +7797,7 @@ nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p, NFSD_DEBUG(4, "mds lookup=%d\n", error); if (error != 0) goto out; + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VDIR) { vput(nd.ni_vp); error = ENOTDIR; @@ -8654,6 +8657,7 @@ nfsrv_mdscopymr(char *mdspathp, char *dspathp, char *curdspathp, char *buf, NFSD_DEBUG(4, "lookup=%d\n", error); if (error != 0) return (error); + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VREG) { vput(nd.ni_vp); NFSD_DEBUG(4, "mdspath not reg\n"); @@ -8675,6 +8679,7 @@ nfsrv_mdscopymr(char *mdspathp, char *dspathp, char *curdspathp, char *buf, vput(vp); return (error); } + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VDIR) { vput(nd.ni_vp); vput(vp); @@ -8717,6 +8722,7 @@ nfsrv_mdscopymr(char *mdspathp, char *dspathp, char *curdspathp, char *buf, vput(curvp); return (error); } + NDFREE_PNBUF(&nd); if (nd.ni_vp->v_type != VDIR || nd.ni_vp == curvp) { vput(nd.ni_vp); vput(vp);