DragonFlyBSD Kernel Audit
DF-2995 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/nfs/nfs_serv.c
+++ b/sys/vfs/nfs/nfs_serv.c
@@ -1303,14 +1303,18 @@ nfsrv_writegather(struct nfsrv_descript
 		}
 	    }
 	    if (len > NFS_MAXDATA || len < 0  || i < len) {
 nfsmout:
 		m_freem(info.mrep);
 		info.mrep = NULL;
-		error = EIO;
-		nfsm_writereply(&info, nfsd, slp, error, 2 * NFSX_UNSIGNED);
-		if (info.v3) {
-		    nfsm_srvwcc_data(&info, nfsd, forat_ret, &aft_ret, &va);
+		/*
+		 * DF-2995: when we got here through NEGREPLYOUT()'s -2 path
+		 * nfsm_reply() already built a reply into info.mreq — do not
+		 * build (and leak) a second one.
+		 */
+		if (info.mreq == NULL) {
+			error = EIO;
+			nfsm_writereply(&info, nfsd, slp, error, 2 * NFSX_UNSIGNED);
+			if (info.v3) {
+			    nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat,
+					     aftat_ret, &va);
+			}
 		}
 		nfsd->nd_mreq = info.mreq;
 		nfsd->nd_mrep = NULL;
 		nfsd->nd_time = 0;
 	    }