Skip to content

Commit

Permalink
Merge pull request #692 from RalfJung/rand
Browse files Browse the repository at this point in the history
Fix 0-sized getrandom and thread_rng()
  • Loading branch information
RalfJung authored Apr 17, 2019
2 parents f6fef3b + a50512f commit ff88062
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 20 deletions.
23 changes: 16 additions & 7 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
// neither of which have any effect on our current PRNG
let _flags = this.read_scalar(args[3])?.to_i32()?;

let data = gen_random(this, len as usize)?;
this.memory_mut().get_mut(ptr.alloc_id)?
.write_bytes(tcx, ptr, &data)?;
if len > 0 {
let data = gen_random(this, len as usize)?;
this.memory_mut().get_mut(ptr.alloc_id)?
.write_bytes(tcx, ptr, &data)?;
}

this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
}
Expand Down Expand Up @@ -622,6 +624,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
this.write_null(dest)?;
}

// We don't support fork so we don't have to do anything for atfork.
"pthread_atfork" => {
this.write_null(dest)?;
}

"mmap" => {
// This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.
let addr = this.read_scalar(args[0])?.not_undef()?;
Expand Down Expand Up @@ -767,11 +774,13 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
// The actual name of 'RtlGenRandom'
"SystemFunction036" => {
let ptr = this.read_scalar(args[0])?.to_ptr()?;
let len = this.read_scalar(args[1])?.to_usize(this)?;
let len = this.read_scalar(args[1])?.to_u32()?;

let data = gen_random(this, len as usize)?;
this.memory_mut().get_mut(ptr.alloc_id)?
.write_bytes(tcx, ptr, &data)?;
if len > 0 {
let data = gen_random(this, len as usize)?;
this.memory_mut().get_mut(ptr.alloc_id)?
.write_bytes(tcx, ptr, &data)?;
}

this.write_scalar(Scalar::from_bool(true), dest)?;
}
Expand Down
2 changes: 1 addition & 1 deletion test-cargo-miri/run-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_cargo_miri_run():
)

def test_cargo_miri_test():
test("cargo miri test", ["cargo", "miri", "test", "-q"], "test.stdout.ref", "test.stderr.ref")
test("cargo miri test", ["cargo", "miri", "test", "-q", "--", "-Zmiri-seed=feed"], "test.stdout.ref", "test.stderr.ref")
test("cargo miri test (with filter)",
["cargo", "miri", "test", "-q", "--", "--", "impl"],
"test.stdout.ref2", "test.stderr.ref"
Expand Down
7 changes: 4 additions & 3 deletions test-cargo-miri/test.stdout.ref
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ test test::rng ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out


running 2 tests
test rng ... ok
running 3 tests
test entropy_rng ... ok
test fixed_rng ... ok
test simple ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

2 changes: 1 addition & 1 deletion test-cargo-miri/test.stdout.ref2
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
running 1 test
test simple ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out

21 changes: 19 additions & 2 deletions test-cargo-miri/tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![allow(unused_imports)] // FIXME for macOS

extern crate rand;

use rand::{Rng, SeedableRng};
use rand::{SeedableRng, FromEntropy, Rng, rngs::SmallRng};

#[test]
fn simple() {
Expand All @@ -10,13 +12,28 @@ fn simple() {
// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn rng() {
fn fixed_rng() {
let mut rng = rand::rngs::StdRng::seed_from_u64(0xdeadcafe);
let x: u32 = rng.gen();
let y: u32 = rng.gen();
assert_ne!(x, y);
}

#[test]
fn entropy_rng() {
#[cfg(not(target_os="macos"))] // FIXME entropy does not work on macOS
// (Not disabling the entire test as that would change the output.)
{
// Use this opportunity to test querying the RNG (needs an external crate, hence tested here and not in the compiletest suite)
let mut rng = SmallRng::from_entropy();
let _val = rng.gen::<i32>();

// Also try per-thread RNG.
let mut rng = rand::thread_rng();
let _val = rng.gen::<i32>();
}
}

// A test that won't work on miri
#[cfg(not(miri))]
#[test]
Expand Down
4 changes: 2 additions & 2 deletions tests/compile-fail/getrandom.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore-macos
// ignore-windows
// ignore-macos: Uses Linux-only APIs
// ignore-windows: Uses Linux-only APIs

#![feature(rustc_private)]
extern crate libc;
Expand Down
9 changes: 5 additions & 4 deletions tests/run-pass/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ fn test_map<S: BuildHasher>(mut map: HashMap<i32, i32, S>) {
}

fn main() {
// TODO: Implement random number generation on OS X
if cfg!(not(target_os = "macos")) {
let map_normal: HashMap<i32, i32> = HashMap::new();
test_map(map_normal);
let map: HashMap<i32, i32> = HashMap::default();
test_map(map);
} else {
let map : HashMap<i32, i32, BuildHasherDefault<collections::hash_map::DefaultHasher>> = Default::default();
// TODO: Implement random number generation on OS X.
// Until then, use a deterministic map.
let map : HashMap<i32, i32, BuildHasherDefault<collections::hash_map::DefaultHasher>> = HashMap::default();
test_map(map);
}
}

0 comments on commit ff88062

Please sign in to comment.