From 98ec30589ae05c9885fa970f991d965921f750a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Tue, 10 Oct 2017 23:19:44 +0200 Subject: [PATCH] Add some sanity checks and fix possible issues with partial read when not using read_exact. --- src/fs.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/fs.rs b/src/fs.rs index 2d1abd0..d47dfcf 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -147,9 +147,23 @@ impl <'a> FileSystem<'a> { bpb.sectors_per_fat_16 = rdr.read_u16::()?; bpb.sectors_per_track = rdr.read_u16::()?; bpb.heads = rdr.read_u16::()?; - bpb.hidden_sectors = rdr.read_u32::()?; // hidden_sector_count + bpb.hidden_sectors = rdr.read_u32::()?; bpb.total_sectors_32 = rdr.read_u32::()?; + // sanity checks + if bpb.bytes_per_sector < 512 { + return Err(Error::new(ErrorKind::Other, "invalid bytes_per_sector value in BPB")); + } + if bpb.sectors_per_cluster < 1 { + return Err(Error::new(ErrorKind::Other, "invalid sectors_per_cluster value in BPB")); + } + if bpb.reserved_sectors < 1 { + return Err(Error::new(ErrorKind::Other, "invalid reserved_sectors value in BPB")); + } + if bpb.fats == 0 { + return Err(Error::new(ErrorKind::Other, "invalid fats value in BPB")); + } + if bpb.sectors_per_fat_16 == 0 { bpb.sectors_per_fat_32 = rdr.read_u32::()?; bpb.extended_flags = rdr.read_u16::()?; @@ -157,20 +171,20 @@ impl <'a> FileSystem<'a> { bpb.root_dir_first_cluster = rdr.read_u32::()?; bpb.fs_info_sector = rdr.read_u16::()?; bpb.backup_boot_sector = rdr.read_u16::()?; - rdr.read(&mut bpb.reserved_0)?; + rdr.read_exact(&mut bpb.reserved_0)?; bpb.drive_num = rdr.read_u8()?; bpb.reserved_1 = rdr.read_u8()?; bpb.ext_sig = rdr.read_u8()?; // 0x29 bpb.volume_id = rdr.read_u32::()?; - rdr.read(&mut bpb.volume_label)?; - rdr.read(&mut bpb.fs_type_label)?; + rdr.read_exact(&mut bpb.volume_label)?; + rdr.read_exact(&mut bpb.fs_type_label)?; } else { bpb.drive_num = rdr.read_u8()?; bpb.reserved_1 = rdr.read_u8()?; bpb.ext_sig = rdr.read_u8()?; // 0x29 bpb.volume_id = rdr.read_u32::()?; - rdr.read(&mut bpb.volume_label)?; - rdr.read(&mut bpb.fs_type_label)?; + rdr.read_exact(&mut bpb.volume_label)?; + rdr.read_exact(&mut bpb.fs_type_label)?; } Ok(bpb) } @@ -187,8 +201,8 @@ impl <'a> FileSystem<'a> { fn read_boot_record(rdr: &mut Read) -> io::Result { let mut boot: BootRecord = Default::default(); - rdr.read(&mut boot.bootjmp)?; - rdr.read(&mut boot.oem_name)?; + rdr.read_exact(&mut boot.bootjmp)?; + rdr.read_exact(&mut boot.oem_name)?; boot.bpb = Self::read_bpb(rdr)?; if boot.bpb.sectors_per_fat_16 == 0 { @@ -196,7 +210,7 @@ impl <'a> FileSystem<'a> { } else { rdr.read_exact(&mut boot.boot_code[0..448])?; } - rdr.read(&mut boot.boot_sig)?; + rdr.read_exact(&mut boot.boot_sig)?; Ok(boot) }