feat: check more BPB fields when mounting fs

Fail mounting if:
* root_entries is zero (only on FAT12/FAT16)
* backup_boot_sector is outside of the reserved region (only on FAT32)
* fs_info_sector is outside of the reserved region (only on FAT32)
This commit is contained in:
Rafał Harabień 2018-12-12 22:21:12 +01:00
parent b4455a86a8
commit c372429951
2 changed files with 15 additions and 1 deletions

View File

@ -202,6 +202,13 @@ impl BiosParameterBlock {
)); ));
} }
if !is_fat32 && self.root_entries == 0 {
return Err(Error::new(
ErrorKind::Other,
"Empty root directory region defined in FAT12/FAT16 BPB",
));
}
if (u32::from(self.root_entries) * DIR_ENTRY_SIZE as u32) % u32::from(self.bytes_per_sector) != 0 { if (u32::from(self.root_entries) * DIR_ENTRY_SIZE as u32) % u32::from(self.bytes_per_sector) != 0 {
warn!("Root entries should fill sectors fully"); warn!("Root entries should fill sectors fully");
} }
@ -235,6 +242,14 @@ impl BiosParameterBlock {
return Err(Error::new(ErrorKind::Other, "Invalid BPB (total_sectors field value is too small)")); return Err(Error::new(ErrorKind::Other, "Invalid BPB (total_sectors field value is too small)"));
} }
if is_fat32 && self.backup_boot_sector() >= self.reserved_sectors() {
return Err(Error::new(ErrorKind::Other, "Invalid BPB (backup boot-sector not in a reserved region)"));
}
if is_fat32 && self.fs_info_sector() >= self.reserved_sectors() {
return Err(Error::new(ErrorKind::Other, "Invalid BPB (FSInfo sector not in a reserved region)"));
}
let total_clusters = self.total_clusters(); let total_clusters = self.total_clusters();
let fat_type = FatType::from_clusters(total_clusters); let fat_type = FatType::from_clusters(total_clusters);
if is_fat32 != (fat_type == FatType::Fat32) { if is_fat32 != (fat_type == FatType::Fat32) {

View File

@ -913,7 +913,6 @@ pub fn format_volume<T: ReadWriteSeek>(mut disk: T, options: FormatVolumeOptions
write_zeros_until_end_of_sector(&mut disk, bytes_per_sector)?; write_zeros_until_end_of_sector(&mut disk, bytes_per_sector)?;
// backup boot sector // backup boot sector
debug_assert!(boot.bpb.backup_boot_sector() < boot.bpb.reserved_sectors());
disk.seek(SeekFrom::Start(boot.bpb.bytes_from_sectors(boot.bpb.backup_boot_sector())))?; disk.seek(SeekFrom::Start(boot.bpb.bytes_from_sectors(boot.bpb.backup_boot_sector())))?;
boot.serialize(&mut disk)?; boot.serialize(&mut disk)?;
write_zeros_until_end_of_sector(&mut disk, bytes_per_sector)?; write_zeros_until_end_of_sector(&mut disk, bytes_per_sector)?;