⬢ DragonFlyBSD Kernel Audit
DF-3099 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hpfs/hpfs_alsubr.c
+++ b/sys/vfs/hpfs/hpfs_alsubr.c
@@ -67,6 +67,7 @@
 	alleaf_t *alp;
 	alnode_t *anp;
 	int error, i;
+	int run;
 
 	dprintf(("hpfs_hpbmap(0x%x, 0x%x): ",hp->h_no, bn));
 
@@ -125,10 +126,14 @@
 
 				if (runp != NULL) {
 					if (alp->al_len)
-						*runp = alp->al_off - 1 +
+						run = alp->al_off - 1 +
 							alp->al_len - bn;
 					else
-						*runp = 3; /* XXX */
+						run = 3; /* XXX */
+					if (run < 0 ||
+					    run > MAXBSIZE / DEV_BSIZE - 1)
+						run = MAXBSIZE / DEV_BSIZE - 1;
+					*runp = run;
 
 					dprintf((" 0x%x cont", *runp));
 				}
--- a/sys/vfs/hpfs/hpfs_vnops.c
+++ b/sys/vfs/hpfs/hpfs_vnops.c
@@ -394,6 +394,10 @@
 		towrite = szmin(off + uio->uio_resid,
 				min(64*1024, (runl+1)*DEV_BSIZE));
 		xfersz = roundup2(towrite, DEV_BSIZE);
+
+		if (towrite == 0)	/* no forward progress possible */
+			return (EINVAL);
+
 		dprintf(("hpfs_write: bn: 0x%x (0x%x) towrite: 0x%x (0x%x)\n",
 			bn, runl, towrite, xfersz));