Skip to content

Commit

Permalink
Fix out-of-bounds access in Record::fixup()
Browse files Browse the repository at this point in the history
This change also optimizes the routine by performing the validation only once and not in every iteration.

Fixes #24
  • Loading branch information
ColinFinck committed Jan 24, 2023
1 parent acc7b7d commit 441ea7b
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/record.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021-2022 Colin Finck <colin@reactos.org>
// Copyright 2021-2023 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: MIT OR Apache-2.0

use core::mem;
Expand Down Expand Up @@ -40,6 +40,15 @@ impl Record {
let mut array_position = self.update_sequence_array_start() as usize;
let array_end =
self.update_sequence_offset() as usize + self.update_sequence_size() as usize;
let sectors_end = self.update_sequence_array_count() as usize * NTFS_BLOCK_SIZE;

if array_end > self.data.len() || sectors_end > self.data.len() {
return Err(NtfsError::UpdateSequenceArrayExceedsRecordSize {
position: self.position,
array_count: self.update_sequence_array_count(),
record_size: self.data.len(),
});
}

// The Update Sequence Number (USN) is written to the last 2 bytes of each sector.
let mut sector_position = NTFS_BLOCK_SIZE - mem::size_of::<u16>();
Expand All @@ -48,14 +57,6 @@ impl Record {
let array_position_end = array_position + mem::size_of::<u16>();
let sector_position_end = sector_position + mem::size_of::<u16>();

if sector_position_end > self.data.len() {
return Err(NtfsError::UpdateSequenceArrayExceedsRecordSize {
position: self.position,
array_count: self.update_sequence_array_count(),
record_size: self.data.len(),
});
}

// The array contains the actual 2 bytes that need to be at `sector_position` after the fixup.
let new_bytes: [u8; 2] = self.data[array_position..array_position_end]
.try_into()
Expand Down

0 comments on commit 441ea7b

Please sign in to comment.