Skip to content

Commit

Permalink
Check BPB-reported sizes more thoroughly, improve error messages.
Browse files Browse the repository at this point in the history
Fixes #1
Thanks to 5225225 <5225225@mailbox.org> for the report!
  • Loading branch information
ColinFinck committed Jan 26, 2022
1 parent 0783cbd commit d3fcffd
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
19 changes: 16 additions & 3 deletions src/boot_sector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl BiosParameterBlock {
const MAXIMUM_CLUSTER_SIZE: u32 = 2097152;

let cluster_size = self.sectors_per_cluster as u32 * self.sector_size as u32;
if cluster_size > MAXIMUM_CLUSTER_SIZE {
if cluster_size > MAXIMUM_CLUSTER_SIZE || !cluster_size.is_power_of_two() {
return Err(NtfsError::UnsupportedClusterSize {
expected: MAXIMUM_CLUSTER_SIZE,
actual: cluster_size,
Expand Down Expand Up @@ -104,8 +104,21 @@ impl BiosParameterBlock {
}
}

pub(crate) fn sector_size(&self) -> u16 {
self.sector_size
pub(crate) fn sector_size(&self) -> Result<u16> {
// NTFS-3G supports more sector sizes, but I haven't got Windows to accept an NTFS partition
// with a sector size other than 512 bytes.
// This restriction is arbitrary and can be lifted once you show me a Windows NTFS partition
// with a different sector size.
const SUPPORTED_SECTOR_SIZE: u16 = 512;

if self.sector_size != SUPPORTED_SECTOR_SIZE {
return Err(NtfsError::UnsupportedSectorSize {
expected: SUPPORTED_SECTOR_SIZE,
actual: self.sector_size,
});
}

Ok(self.sector_size)
}

pub(crate) fn serial_number(&self) -> u64 {
Expand Down
14 changes: 9 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub enum NtfsError {
expected: u8,
actual: u8,
},
/// The cluster count {cluster_count} is too big
/// The NTFS Data Run cluster count {cluster_count} is too big to be multiplied by the cluster size
InvalidClusterCount { cluster_count: u64 },
/// The NTFS File Record at byte position {position:#010x} indicates an allocated size of {expected} bytes, but the record only has a size of {actual} bytes
InvalidFileAllocatedSize {
Expand Down Expand Up @@ -147,12 +147,14 @@ pub enum NtfsError {
},
/// I/O error: {0:?}
Io(binread::io::Error),
/// The Logical Cluster Number (LCN) {lcn} is too big to be processed
/// The Logical Cluster Number (LCN) {lcn} is too big to be multiplied by the cluster size
LcnTooBig { lcn: Lcn },
/// The index root at byte position {position:#010x} is a large index, but no matching index allocation attribute was provided
MissingIndexAllocation { position: u64 },
/// The NTFS file at byte position {position:#010x} is not a directory.
/// The NTFS file at byte position {position:#010x} is not a directory
NotADirectory { position: u64 },
/// The total sector count is too big to be multiplied by the sector size
TotalSectorsTooBig { total_sectors: u64 },
/// The NTFS Attribute at byte position {position:#010x} should not belong to an Attribute List, but it does
UnexpectedAttributeListAttribute { position: u64 },
/// The NTFS Attribute at byte position {position:#010x} should be resident, but it is non-resident
Expand All @@ -165,6 +167,8 @@ pub enum NtfsError {
UnsupportedClusterSize { expected: u32, actual: u32 },
/// The namespace of the NTFS file name starting at byte position {position:#010x} is {actual}, which is not supported
UnsupportedFileNamespace { position: u64, actual: u8 },
/// The sector size is {actual} bytes, but the only supported one is {expected}
UnsupportedSectorSize { expected: u16, actual: u16 },
/// The Update Sequence Array (USA) of the record at byte position {position:#010x} has entries for {array_count} sectors of {sector_size} bytes, but the record is only {record_size} bytes long
UpdateSequenceArrayExceedsRecordSize {
position: u64,
Expand All @@ -184,9 +188,9 @@ pub enum NtfsError {
expected: Vcn,
actual: Vcn,
},
/// The index allocation at byte position {position:#010x} references a Virtual Cluster Number (VCN) {vcn}, but this VCN exceeds the boundaries of the filesystem.
/// The index allocation at byte position {position:#010x} references a Virtual Cluster Number (VCN) {vcn}, but this VCN exceeds the boundaries of the filesystem
VcnOutOfBoundsInIndexAllocation { position: u64, vcn: Vcn },
/// The Virtual Cluster Number (VCN) {vcn} is too big to be processed
/// The Virtual Cluster Number (VCN) {vcn} is too big to be multiplied by the cluster size
VcnTooBig { vcn: Vcn },
}

Expand Down
7 changes: 5 additions & 2 deletions src/ntfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ impl Ntfs {

let bpb = boot_sector.bpb();
let cluster_size = bpb.cluster_size()?;
let sector_size = bpb.sector_size();
let size = bpb.total_sectors() * sector_size as u64;
let sector_size = bpb.sector_size()?;
let total_sectors = bpb.total_sectors();
let size = total_sectors
.checked_mul(sector_size as u64)
.ok_or(NtfsError::TotalSectorsTooBig { total_sectors })?;
let mft_position = 0;
let file_record_size = bpb.file_record_size()?;
let serial_number = bpb.serial_number();
Expand Down

0 comments on commit d3fcffd

Please sign in to comment.