DF-2993 / fix.diff
--- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -3009,6 +3009,13 @@ nfsrv_readdir(struct nfsrv_descript *nf if (!error && toff && verf && verf != at.va_filerev) error = NFSERR_BAD_COOKIE; #endif + /* + * DF-2993: a count of 0 from the wire makes siz/fullsiz 0 + * which turns the degenerate-case retry loop below into an + * infinite loop (no eof reply is possible because that path + * requires uio_resid > 0). + */ + if (siz <= 0) + error = NFSERR_TOOSMALL; } if (!error) error = nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 0); @@ -3302,6 +3309,13 @@ nfsrv_readdirplus(struct nfsrv_descript if (!error && toff && verf && verf != at.va_filerev) error = NFSERR_BAD_COOKIE; #endif + /* + * DF-2993: a dircount of 0 from the wire makes siz/fullsiz 0 which + * turns the degenerate-case retry loop below into an infinite loop. + */ + if (siz <= 0) + error = NFSERR_TOOSMALL; if (!error) { error = nfsrv_access(mp, vp, VEXEC, cred, rdonly, td, 0); } |