⬢ DragonFlyBSD Kernel Audit
DF-3091 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/msdosfs/msdosfs_fat.c
+++ b/sys/vfs/msdosfs/msdosfs_fat.c
@@ -184,7 +184,8 @@
 		/*
 		 * Stop with all reserved clusters, not just with EOF.
 		 */
-		if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
+		if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD ||
+		    cn > pmp->pm_maxcluster)
 			goto hiteof;
 		byteoffset = FATOFS(pmp, cn);
 		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
@@ -223,6 +224,9 @@
 			cn |= ~pmp->pm_fatmask;
 	}
 
+	if (cn > pmp->pm_maxcluster)
+		goto hiteof;
+
 	if (!MSDOSFSEOF(pmp, cn)) {
 		if (bp)
 			brelse(bp);
--- a/sys/vfs/msdosfs/msdosfs_vnops.c
+++ b/sys/vfs/msdosfs/msdosfs_vnops.c
@@ -728,6 +728,18 @@
 				break;
 			}
 		}
+		/*
+		 * The buffer may be B_CACHE from a failed read of an
+		 * unmappable cluster; never accept data into a block we
+		 * cannot map back to the device, or the delayed-write
+		 * flush would fail forever and wedge sync/umount.
+		 */
+		if (bp->b_bio2.bio_offset == NOOFFSET) {
+			brelse(bp);
+			if (!error)
+				error = EIO;
+			break;
+		}
 
 		/*
 		 * Should these vnode_pager_* functions be done on dir