Skip to content

Commit 1c07cd5

Browse files
authored
Merge pull request #709 from RalfJung/macos-rand
implement SecRandomCopyBytes for macOS RNG
2 parents 298bd1f + b731436 commit 1c07cd5

File tree

4 files changed

+35
-36
lines changed

4 files changed

+35
-36
lines changed

src/fn_call.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -298,19 +298,14 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
298298
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
299299
match this.read_scalar(args[0])?.to_usize(this)? {
300300
id if id == sys_getrandom => {
301-
let ptr = this.read_scalar(args[1])?.to_ptr()?;
301+
let ptr = this.read_scalar(args[1])?.not_undef()?;
302302
let len = this.read_scalar(args[2])?.to_usize(this)?;
303303

304304
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
305305
// neither of which have any effect on our current PRNG
306306
let _flags = this.read_scalar(args[3])?.to_i32()?;
307307

308-
if len > 0 {
309-
let data = gen_random(this, len as usize)?;
310-
this.memory_mut().get_mut(ptr.alloc_id)?
311-
.write_bytes(tcx, ptr, &data)?;
312-
}
313-
308+
gen_random(this, len as usize, ptr)?;
314309
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
315310
}
316311
id => {
@@ -712,6 +707,12 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
712707
"_NSGetArgv" => {
713708
this.write_scalar(Scalar::Ptr(this.machine.argv.unwrap()), dest)?;
714709
},
710+
"SecRandomCopyBytes" => {
711+
let len = this.read_scalar(args[1])?.to_usize(this)?;
712+
let ptr = this.read_scalar(args[2])?.not_undef()?;
713+
gen_random(this, len as usize, ptr)?;
714+
this.write_null(dest)?;
715+
}
715716

716717
// Windows API stubs.
717718
// HANDLE = isize
@@ -866,15 +867,9 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
866867
}
867868
// The actual name of 'RtlGenRandom'
868869
"SystemFunction036" => {
869-
let ptr = this.read_scalar(args[0])?.to_ptr()?;
870+
let ptr = this.read_scalar(args[0])?.not_undef()?;
870871
let len = this.read_scalar(args[1])?.to_u32()?;
871-
872-
if len > 0 {
873-
let data = gen_random(this, len as usize)?;
874-
this.memory_mut().get_mut(ptr.alloc_id)?
875-
.write_bytes(tcx, ptr, &data)?;
876-
}
877-
872+
gen_random(this, len as usize, ptr)?;
878873
this.write_scalar(Scalar::from_bool(true), dest)?;
879874
}
880875

@@ -915,21 +910,30 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
915910
fn gen_random<'a, 'mir, 'tcx>(
916911
this: &mut MiriEvalContext<'a, 'mir, 'tcx>,
917912
len: usize,
918-
) -> Result<Vec<u8>, EvalError<'tcx>> {
913+
dest: Scalar<Tag>,
914+
) -> EvalResult<'tcx> {
915+
if len == 0 {
916+
// Nothing to do
917+
return Ok(());
918+
}
919+
let ptr = dest.to_ptr()?;
919920

920-
match &mut this.machine.rng {
921+
let data = match &mut this.machine.rng {
921922
Some(rng) => {
922923
let mut data = vec![0; len];
923924
rng.fill_bytes(&mut data);
924-
Ok(data)
925+
data
925926
}
926927
None => {
927-
err!(Unimplemented(
928+
return err!(Unimplemented(
928929
"miri does not support gathering system entropy in deterministic mode!
929930
Use '-Zmiri-seed=<seed>' to enable random number generation.
930931
WARNING: Miri does *not* generate cryptographically secure entropy -
931932
do not use Miri to run any program that needs secure random number generation".to_owned(),
932-
))
933+
));
933934
}
934-
}
935+
};
936+
let tcx = &{this.tcx.tcx};
937+
this.memory_mut().get_mut(ptr.alloc_id)?
938+
.write_bytes(tcx, ptr, &data)
935939
}

test-cargo-miri/run-test.py

+3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ def test_cargo_miri_test():
6161
"test.stdout.ref2", "test.stderr.ref"
6262
)
6363

64+
os.chdir(os.path.dirname(os.path.realpath(__file__)))
65+
6466
test_cargo_miri_run()
6567
test_cargo_miri_test()
68+
6669
print("TEST SUCCESSFUL!")
6770
sys.exit(0)

test-cargo-miri/tests/test.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#![allow(unused_imports)] // FIXME for macOS
2-
3-
extern crate rand;
4-
51
use rand::{SeedableRng, FromEntropy, Rng, rngs::SmallRng};
62

73
#[test]
@@ -21,17 +17,13 @@ fn fixed_rng() {
2117

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

31-
// Also try per-thread RNG.
32-
let mut rng = rand::thread_rng();
33-
let _val = rng.gen::<i32>();
34-
}
24+
// Also try per-thread RNG.
25+
let mut rng = rand::thread_rng();
26+
let _val = rng.gen::<i32>();
3527
}
3628

3729
// A test that won't work on miri

travis.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ echo
2424
# Test
2525
function run_tests {
2626
cargo test --release --all-features
27-
(cd test-cargo-miri && ./run-test.py)
27+
test-cargo-miri/run-test.py
2828
}
2929

3030
echo "Test host architecture"

0 commit comments

Comments
 (0)