svn commit: r322982 - head/sys/fs/msdosfs

Konstantin Belousov kib at FreeBSD.org
Mon Aug 28 20:52:33 UTC 2017


Author: kib
Date: Mon Aug 28 20:52:32 2017
New Revision: 322982
URL: https://svnweb.freebsd.org/changeset/base/322982

Log:
  Verify that the BPB media descriptor and FAT ID match.
  
  FAT specification requires that for valid FAT, FAT cluster 0 has a
  specific value derived from the BPB media descriptor.  The lowest
  (little-endian) byte must be equal to bpb.bpbMedia, other bits in the
  cluster number must be all 1's.  Implement the check to reduce the
  chance of the randomly corrupted FAT to pass the mount attempt.
  
  Submitted by:	Siva Mahadevan <smahadevan at freebsdfoundation.org>
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D12124

Modified:
  head/sys/fs/msdosfs/msdosfs_fat.c

Modified: head/sys/fs/msdosfs/msdosfs_fat.c
==============================================================================
--- head/sys/fs/msdosfs/msdosfs_fat.c	Mon Aug 28 20:00:21 2017	(r322981)
+++ head/sys/fs/msdosfs/msdosfs_fat.c	Mon Aug 28 20:52:32 2017	(r322982)
@@ -908,19 +908,17 @@ fillinusemap(struct msdosfsmount *pmp)
 	 * zero.  These represent free clusters.
 	 */
 	pmp->pm_freeclustercount = 0;
-	for (cn = CLUST_FIRST; cn <= pmp->pm_maxcluster; cn++) {
+	for (cn = 0; cn <= pmp->pm_maxcluster; cn++) {
 		byteoffset = FATOFS(pmp, cn);
 		bo = byteoffset % pmp->pm_fatblocksize;
-		if (!bo || !bp) {
+		if (bo == 0) {
 			/* Read new FAT block */
-			if (bp)
+			if (bp != NULL)
 				brelse(bp);
 			fatblock(pmp, byteoffset, &bn, &bsize, NULL);
 			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
-			if (error) {
-				brelse(bp);
+			if (error != 0)
 				return (error);
-			}
 		}
 		if (FAT32(pmp))
 			readcn = getulong(&bp->b_data[bo]);
@@ -930,7 +928,19 @@ fillinusemap(struct msdosfsmount *pmp)
 			readcn >>= 4;
 		readcn &= pmp->pm_fatmask;
 
-		if (readcn == CLUST_FREE)
+		/*
+		 * Check if the FAT ID matches the BPB's media descriptor and
+		 * all other bits are set to 1.
+		 */
+		if (cn == 0 && readcn != ((pmp->pm_fatmask & 0xffffff00) |
+		    pmp->pm_bpb.bpbMedia)) {
+#ifdef MSDOSFS_DEBUG
+			printf("mountmsdosfs(): Media descriptor in BPB"
+			    "does not match FAT ID\n");
+#endif
+			brelse(bp);
+			return (EINVAL);
+		} else if (readcn == CLUST_FREE)
 			usemap_free(pmp, cn);
 	}
 	if (bp != NULL)


More information about the svn-src-all mailing list