From: OGAWA Hirofumi 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) _