Commit 2d5acefc authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] FAT: Add count of clusters check in fat_fill_super() (7/10)

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.
parent d97a5110
...@@ -765,8 +765,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -765,8 +765,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
struct buffer_head *bh; struct buffer_head *bh;
struct fat_boot_sector *b; struct fat_boot_sector *b;
struct msdos_sb_info *sbi; struct msdos_sb_info *sbi;
int logical_sector_size, fat_clusters, debug, cp, first; u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
unsigned int total_sectors, rootdir_sectors; int logical_sector_size, debug, cp, first;
unsigned int media; unsigned int media;
long error; long error;
char buf[50]; char buf[50];
...@@ -946,15 +946,24 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -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)); total_sectors = CF_LE_W(get_unaligned((unsigned short *)&b->sectors));
if (total_sectors == 0) if (total_sectors == 0)
total_sectors = CF_LE_L(b->total_sect); 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) 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 */ /* check that FAT table does not overflow */
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
if (sbi->clusters > fat_clusters - 2) total_clusters = min(total_clusters, fat_clusters - 2);
sbi->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); brelse(bh);
......
...@@ -55,24 +55,29 @@ ...@@ -55,24 +55,29 @@
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ #define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT ".. " /* "..", 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 */ /* media of boot sector */
#define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0) #define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \ #define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x)) 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 */ /* bad cluster mark */
#define BAD_FAT12 0xFF7 #define BAD_FAT12 0xFF7
#define BAD_FAT16 0xFFF7 #define BAD_FAT16 0xFFF7
#define BAD_FAT32 0xFFFFFF7 #define BAD_FAT32 0x0FFFFFF7
#define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \ #define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \
MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12) MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12)
/* standard EOF */ /* standard EOF */
#define EOF_FAT12 0xFFF #define EOF_FAT12 0xFFF
#define EOF_FAT16 0xFFFF #define EOF_FAT16 0xFFFF
#define EOF_FAT32 0xFFFFFFF #define EOF_FAT32 0x0FFFFFFF
#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \ #define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12) MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment