Skip to content

Commit

Permalink
use the UB-free version with proper alignment in Miri
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Apr 20, 2019
1 parent 1f6e599 commit f1d0419
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions rand_core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
// As an optimization we try to write directly into the output buffer.
// This is only enabled for little-endian platforms where unaligned writes
// are known to be safe and fast.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
// FIXME: This is UB. We disable it in Miri to paper over that, but really
// we should stop creating unaligned references.
#[cfg(all(not(miri), any(target_arch = "x86", target_arch = "x86_64")))]
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut filled = 0;

Expand All @@ -232,6 +234,7 @@ where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
let end_direct = dest.len() - len_remainder;

while filled < end_direct {
// This reference is not aligned. Even just creating it is UB.
let dest_u32: &mut R::Results = unsafe {
&mut *(dest[filled..].as_mut_ptr() as
*mut <R as BlockRngCore>::Results)
Expand All @@ -251,7 +254,7 @@ where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
}
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
#[cfg(not(all(not(miri), any(target_arch = "x86", target_arch = "x86_64"))))]
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut read_len = 0;
while read_len < dest.len() {
Expand Down Expand Up @@ -419,7 +422,9 @@ where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>
// As an optimization we try to write directly into the output buffer.
// This is only enabled for little-endian platforms where unaligned writes
// are known to be safe and fast.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
// FIXME: This is UB. We disable it in Miri to paper over that, but really
// we should stop creating unaligned references.
#[cfg(all(not(miri), any(target_arch = "x86", target_arch = "x86_64")))]
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut filled = 0;
self.half_used = false;
Expand All @@ -439,6 +444,7 @@ where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>
let end_direct = dest.len() - len_remainder;

while filled < end_direct {
// This reference is not aligned. Even just creating it is UB.
let dest_u64: &mut R::Results = unsafe {
::core::mem::transmute(dest[filled..].as_mut_ptr())
};
Expand All @@ -457,7 +463,7 @@ where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>
}
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
#[cfg(not(all(not(miri), any(target_arch = "x86", target_arch = "x86_64"))))]
fn fill_bytes(&mut self, dest: &mut [u8]) {
let mut read_len = 0;
self.half_used = false;
Expand Down

0 comments on commit f1d0419

Please sign in to comment.