]> git.hungrycats.org Git - linux/commitdiff
[PATCH] FAT: Add count of clusters check in fat_fill_super() (7/10)
authorAndrew Morton <akpm@osdl.org>
Tue, 30 Dec 2003 07:45:48 +0000 (23:45 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 30 Dec 2003 07:45:48 +0000 (23:45 -0800)
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
include/linux/msdos_fs.h

index c67e488178722e23cf34273d1724889900017ff6..4e5d0c08517b232d5f92a95740078085574b455b 100644 (file)
@@ -765,8 +765,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
        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 *sb, void *data, int silent,
        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);
 
index 8c969199ee026241b80c9988f6a81acacfad5a9b..f5c6209bc8f11e05269b79dd25eaa39cdcda741f 100644 (file)
 #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)