1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

volume_id: make FAT32 recognition more robust

FAT32 volumes should never have a cluster count, that fits
into a 16 bit value, but mkdosfs can create such volumes.
No sane formatter or Windows will ever do this, but the
Linux kernel as Windows can read/write it.

Thanks to Ted Ts'o <tytso@mit.edu> for convincing me.

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
Kay Sievers 2005-10-23 19:15:07 +02:00
parent 1305b47167
commit 04b222b4b0

View File

@ -138,7 +138,8 @@ int volume_id_probe_vfat(struct volume_id *id, uint64_t off)
uint32_t root_cluster;
uint32_t dir_size;
uint32_t cluster_count;
uint32_t fat_length;
uint16_t fat_length;
uint32_t fat32_length;
uint64_t root_start;
uint32_t start_data_sect;
uint16_t root_dir_entries;
@ -222,11 +223,18 @@ valid:
dbg("sect_count 0x%x", sect_count);
fat_length = le16_to_cpu(vs->fat_length);
if (fat_length == 0)
fat_length = le32_to_cpu(vs->type.fat32.fat32_length);
dbg("fat_length 0x%x", fat_length);
fat32_length = le32_to_cpu(vs->type.fat32.fat32_length);
dbg("fat32_length 0x%x", fat32_length);
if (fat_length)
fat_size = fat_length * vs->fats;
else if (fat32_length)
fat_size = fat32_length * vs->fats;
else
return -1;
dbg("fat_size 0x%x", fat_size);
fat_size = fat_length * vs->fats;
dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
(sector_size-1)) / sector_size;
dbg("dir_size 0x%x", dir_size);
@ -235,14 +243,17 @@ valid:
cluster_count /= vs->sectors_per_cluster;
dbg("cluster_count 0x%x", cluster_count);
if (cluster_count < FAT12_MAX) {
strcpy(id->type_version, "FAT12");
} else if (cluster_count < FAT16_MAX) {
strcpy(id->type_version, "FAT16");
} else {
strcpy(id->type_version, "FAT32");
/* must be FAT32 */
if (!fat_length && fat32_length)
goto fat32;
/* cluster_count tells us the format */
if (cluster_count < FAT12_MAX)
strcpy(id->type_version, "FAT12");
else if (cluster_count < FAT16_MAX)
strcpy(id->type_version, "FAT16");
else
goto fat32;
}
/* the label may be an attribute in the root directory */
root_start = (reserved + fat_size) * sector_size;
@ -274,6 +285,8 @@ valid:
goto found;
fat32:
strcpy(id->type_version, "FAT32");
/* FAT32 root dir is a cluster chain like any other directory */
buf_size = vs->sectors_per_cluster * sector_size;
root_cluster = le32_to_cpu(vs->type.fat32.root_cluster);