DragonFlyBSD Kernel Audit
DF-2993 / fix.diff
← back to finding ↓ download raw
--- 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);
 	}