Skip to content

Commit c41f21b

Browse files
committed
Fix UB in Windows DirBuffIter (provenance and alignment)
1 parent 5c3490c commit c41f21b

File tree

1 file changed

+10
-7
lines changed
  • library/std/src/sys/windows

1 file changed

+10
-7
lines changed

library/std/src/sys/windows/fs.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -658,18 +658,18 @@ impl File {
658658

659659
/// A buffer for holding directory entries.
660660
struct DirBuff {
661-
buffer: Vec<u8>,
661+
buffer: Box<Align8<[u8; Self::BUFFER_SIZE]>>,
662662
}
663663
impl DirBuff {
664+
const BUFFER_SIZE: usize = 1024;
664665
fn new() -> Self {
665-
const BUFFER_SIZE: usize = 1024;
666-
Self { buffer: vec![0_u8; BUFFER_SIZE] }
666+
Self { buffer: Box::new(Align8([0u8; Self::BUFFER_SIZE])) }
667667
}
668668
fn capacity(&self) -> usize {
669-
self.buffer.len()
669+
self.buffer.0.len()
670670
}
671671
fn as_mut_ptr(&mut self) -> *mut u8 {
672-
self.buffer.as_mut_ptr().cast()
672+
self.buffer.0.as_mut_ptr().cast()
673673
}
674674
/// Returns a `DirBuffIter`.
675675
fn iter(&self) -> DirBuffIter<'_> {
@@ -678,7 +678,7 @@ impl DirBuff {
678678
}
679679
impl AsRef<[u8]> for DirBuff {
680680
fn as_ref(&self) -> &[u8] {
681-
&self.buffer
681+
&self.buffer.0
682682
}
683683
}
684684

@@ -706,9 +706,12 @@ impl<'a> Iterator for DirBuffIter<'a> {
706706
// used to get the file name slice.
707707
let (name, is_directory, next_entry) = unsafe {
708708
let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
709+
// Guaranteed to be aligned in documentation for
710+
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
711+
assert!(info.is_aligned());
709712
let next_entry = (*info).NextEntryOffset as usize;
710713
let name = crate::slice::from_raw_parts(
711-
(*info).FileName.as_ptr().cast::<u16>(),
714+
ptr::addr_of!((*info).FileName).cast::<u16>(),
712715
(*info).FileNameLength as usize / size_of::<u16>(),
713716
);
714717
let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;

0 commit comments

Comments
 (0)