mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-24 22:36:05 +00:00
fs: fat: add bootsector validity check
The performed checks are similar to the checks performed by the Linux kernel in the function fat_read_bpb() in the file fs/fat/inode.c. Signed-off-by: Christian Taedcke <christian.taedcke@weidmueller.com>
This commit is contained in:
parent
33daef49b0
commit
c489937a6f
1 changed files with 53 additions and 0 deletions
53
fs/fat/fat.c
53
fs/fat/fat.c
|
@ -25,6 +25,7 @@
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/log2.h>
|
||||||
|
|
||||||
/* maximum number of clusters for FAT12 */
|
/* maximum number of clusters for FAT12 */
|
||||||
#define MAX_FAT12 0xFF4
|
#define MAX_FAT12 0xFF4
|
||||||
|
@ -508,6 +509,52 @@ static int determine_legacy_fat_bits(const boot_sector *bs)
|
||||||
return (total_clusters > MAX_FAT12) ? 16 : 12;
|
return (total_clusters > MAX_FAT12) ? 16 : 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines if the boot sector's media field is valid
|
||||||
|
*
|
||||||
|
* Based on fat_valid_media() from Linux kernel's include/linux/msdos_fs.h
|
||||||
|
*/
|
||||||
|
static int fat_valid_media(u8 media)
|
||||||
|
{
|
||||||
|
return media >= 0xf8 || media == 0xf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines if the given boot sector is valid
|
||||||
|
*
|
||||||
|
* Based on fat_read_bpb() from the Linux kernel's fs/fat/inode.c
|
||||||
|
*/
|
||||||
|
static int is_bootsector_valid(const boot_sector *bs)
|
||||||
|
{
|
||||||
|
u16 sector_size = get_unaligned_le16(bs->sector_size);
|
||||||
|
u16 dir_per_block = sector_size / sizeof(dir_entry);
|
||||||
|
|
||||||
|
if (!bs->reserved)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!bs->fats)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!fat_valid_media(bs->media))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!is_power_of_2(sector_size) ||
|
||||||
|
sector_size < 512 ||
|
||||||
|
sector_size > 4096)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!is_power_of_2(bs->cluster_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!bs->fat_length && !bs->fat32_length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (get_unaligned_le16(bs->dir_entries) & (dir_per_block - 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read boot sector and volume info from a FAT filesystem
|
* Read boot sector and volume info from a FAT filesystem
|
||||||
*/
|
*/
|
||||||
|
@ -542,6 +589,12 @@ read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)
|
||||||
bs->heads = FAT2CPU16(bs->heads);
|
bs->heads = FAT2CPU16(bs->heads);
|
||||||
bs->total_sect = FAT2CPU32(bs->total_sect);
|
bs->total_sect = FAT2CPU32(bs->total_sect);
|
||||||
|
|
||||||
|
if (!is_bootsector_valid(bs)) {
|
||||||
|
debug("Error: bootsector is invalid\n");
|
||||||
|
ret = -1;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
/* FAT32 entries */
|
/* FAT32 entries */
|
||||||
if (!bs->fat_length && bs->fat32_length) {
|
if (!bs->fat_length && bs->fat32_length) {
|
||||||
/* Assume FAT32 */
|
/* Assume FAT32 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue