@@ -1583,6 +1583,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
struct msdos_sb_info *sbi;
u16 logical_sector_size;
u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
+ u64 device_sectors;
int debug;
long error;
char buf[50];
@@ -1738,6 +1739,15 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
if (total_sectors == 0)
total_sectors = bpb.fat_total_sect;
+ device_sectors = sb->s_bdev->bd_inode->i_size >>
+ (ffs(logical_sector_size) - 1);
+ if (device_sectors && total_sectors > device_sectors) {
+ fat_msg(sb, KERN_ERR, "total sectors %u "
+ "exceeds size of device (%llu sectors)",
+ total_sectors, device_sectors);
+ goto out_invalid;
+ }
+
total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
if (sbi->fat_bits != 32)
The original code did not check for size of device. A truncated device would mount, I/O failures would occur when "attempt to access beyond end of device", leading to data lost. Fix this by comparing total-sectors field in BPB with size of device. Signed-off-by: Zheng Lv <lv.zheng.2015@gmail.com> --- This patch remove the unwanted "else" block and eliminate use of division. fs/fat/inode.c | 10 ++++++++++ 1 file changed, 10 insertions(+)