From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

This adds the check of count of clusters.  And if it's too big, fat driver
can't handle it.  So doesn't recognize this as fatfs.



 fs/fat/inode.c           |   21 +++++++++++++++------
 include/linux/msdos_fs.h |   13 +++++++++----
 2 files changed, 24 insertions(+), 10 deletions(-)

diff -puN fs/fat/inode.c~fat-07-cluster-count-check fs/fat/inode.c
--- 25/fs/fat/inode.c~fat-07-cluster-count-check	2003-12-21 22:18:06.000000000 -0800
+++ 25-akpm/fs/fat/inode.c	2003-12-21 22:18:06.000000000 -0800
@@ -765,8 +765,8 @@ int fat_fill_super(struct super_block *s
 	struct buffer_head *bh;
 	struct fat_boot_sector *b;
 	struct msdos_sb_info *sbi;
-	int logical_sector_size, fat_clusters, debug, cp, first;
-	unsigned int total_sectors, rootdir_sectors;
+	u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
+	int logical_sector_size, debug, cp, first;
 	unsigned int media;
 	long error;
 	char buf[50];
@@ -946,15 +946,24 @@ int fat_fill_super(struct super_block *s
 	total_sectors = CF_LE_W(get_unaligned((unsigned short *)&b->sectors));
 	if (total_sectors == 0)
 		total_sectors = CF_LE_L(b->total_sect);
-	sbi->clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
+
+	total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
 
 	if (sbi->fat_bits != 32)
-		sbi->fat_bits = (sbi->clusters > MSDOS_FAT12) ? 16 : 12;
+		sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
 
 	/* check that FAT table does not overflow */
 	fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
-	if (sbi->clusters > fat_clusters - 2)
-		sbi->clusters = fat_clusters - 2;
+	total_clusters = min(total_clusters, fat_clusters - 2);
+	if (total_clusters > MAX_FAT(sb)) {
+		if (!silent)
+			printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
+			       total_clusters);
+		brelse(bh);
+		goto out_invalid;
+	}
+
+	sbi->clusters = total_clusters;
 
 	brelse(bh);
 
diff -puN include/linux/msdos_fs.h~fat-07-cluster-count-check include/linux/msdos_fs.h
--- 25/include/linux/msdos_fs.h~fat-07-cluster-count-check	2003-12-21 22:18:06.000000000 -0800
+++ 25-akpm/include/linux/msdos_fs.h	2003-12-21 22:18:06.000000000 -0800
@@ -55,24 +55,29 @@
 #define MSDOS_DOT    ".          " /* ".", padded to MSDOS_NAME chars */
 #define MSDOS_DOTDOT "..         " /* "..", padded to MSDOS_NAME chars */
 
-#define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */
-
 /* media of boot sector */
 #define FAT_VALID_MEDIA(x)	((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
 #define FAT_FIRST_ENT(s, x)	((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
 	MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
 
+/* maximum number of clusters */
+#define MAX_FAT12 0xFF4
+#define MAX_FAT16 0xFFF4
+#define MAX_FAT32 0x0FFFFFF6
+#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
+	MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
+
 /* bad cluster mark */
 #define BAD_FAT12 0xFF7
 #define BAD_FAT16 0xFFF7
-#define BAD_FAT32 0xFFFFFF7
+#define BAD_FAT32 0x0FFFFFF7
 #define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \
 	MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12)
 
 /* standard EOF */
 #define EOF_FAT12 0xFFF
 #define EOF_FAT16 0xFFFF
-#define EOF_FAT32 0xFFFFFFF
+#define EOF_FAT32 0x0FFFFFFF
 #define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
 	MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12)
 

_