--- 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