Merge pull request #709 from RalfJung/macos-rand
implement SecRandomCopyBytes for macOS RNG
This commit is contained in:
commit
1c07cd53e9
4 changed files with 35 additions and 36 deletions
|
|
@ -298,19 +298,14 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
|
|||
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
|
||||
match this.read_scalar(args[0])?.to_usize(this)? {
|
||||
id if id == sys_getrandom => {
|
||||
let ptr = this.read_scalar(args[1])?.to_ptr()?;
|
||||
let ptr = this.read_scalar(args[1])?.not_undef()?;
|
||||
let len = this.read_scalar(args[2])?.to_usize(this)?;
|
||||
|
||||
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
|
||||
// neither of which have any effect on our current PRNG
|
||||
let _flags = this.read_scalar(args[3])?.to_i32()?;
|
||||
|
||||
if len > 0 {
|
||||
let data = gen_random(this, len as usize)?;
|
||||
this.memory_mut().get_mut(ptr.alloc_id)?
|
||||
.write_bytes(tcx, ptr, &data)?;
|
||||
}
|
||||
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
|
||||
}
|
||||
id => {
|
||||
|
|
@ -712,6 +707,12 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
|
|||
"_NSGetArgv" => {
|
||||
this.write_scalar(Scalar::Ptr(this.machine.argv.unwrap()), dest)?;
|
||||
},
|
||||
"SecRandomCopyBytes" => {
|
||||
let len = this.read_scalar(args[1])?.to_usize(this)?;
|
||||
let ptr = this.read_scalar(args[2])?.not_undef()?;
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Windows API stubs.
|
||||
// HANDLE = isize
|
||||
|
|
@ -866,15 +867,9 @@ 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 ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let len = this.read_scalar(args[1])?.to_u32()?;
|
||||
|
||||
if len > 0 {
|
||||
let data = gen_random(this, len as usize)?;
|
||||
this.memory_mut().get_mut(ptr.alloc_id)?
|
||||
.write_bytes(tcx, ptr, &data)?;
|
||||
}
|
||||
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.write_scalar(Scalar::from_bool(true), dest)?;
|
||||
}
|
||||
|
||||
|
|
@ -915,21 +910,30 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
|
|||
fn gen_random<'a, 'mir, 'tcx>(
|
||||
this: &mut MiriEvalContext<'a, 'mir, 'tcx>,
|
||||
len: usize,
|
||||
) -> Result<Vec<u8>, EvalError<'tcx>> {
|
||||
dest: Scalar<Tag>,
|
||||
) -> EvalResult<'tcx> {
|
||||
if len == 0 {
|
||||
// Nothing to do
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = dest.to_ptr()?;
|
||||
|
||||
match &mut this.machine.rng {
|
||||
let data = match &mut this.machine.rng {
|
||||
Some(rng) => {
|
||||
let mut data = vec![0; len];
|
||||
rng.fill_bytes(&mut data);
|
||||
Ok(data)
|
||||
data
|
||||
}
|
||||
None => {
|
||||
err!(Unimplemented(
|
||||
return err!(Unimplemented(
|
||||
"miri does not support gathering system entropy in deterministic mode!
|
||||
Use '-Zmiri-seed=<seed>' to enable random number generation.
|
||||
WARNING: Miri does *not* generate cryptographically secure entropy -
|
||||
do not use Miri to run any program that needs secure random number generation".to_owned(),
|
||||
))
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
let tcx = &{this.tcx.tcx};
|
||||
this.memory_mut().get_mut(ptr.alloc_id)?
|
||||
.write_bytes(tcx, ptr, &data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,10 @@ def test_cargo_miri_test():
|
|||
"test.stdout.ref2", "test.stderr.ref"
|
||||
)
|
||||
|
||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
test_cargo_miri_run()
|
||||
test_cargo_miri_test()
|
||||
|
||||
print("TEST SUCCESSFUL!")
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
#![allow(unused_imports)] // FIXME for macOS
|
||||
|
||||
extern crate rand;
|
||||
|
||||
use rand::{SeedableRng, FromEntropy, Rng, rngs::SmallRng};
|
||||
|
||||
#[test]
|
||||
|
|
@ -21,17 +17,13 @@ fn fixed_rng() {
|
|||
|
||||
#[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>();
|
||||
// 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>();
|
||||
}
|
||||
// Also try per-thread RNG.
|
||||
let mut rng = rand::thread_rng();
|
||||
let _val = rng.gen::<i32>();
|
||||
}
|
||||
|
||||
// A test that won't work on miri
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ echo
|
|||
# Test
|
||||
function run_tests {
|
||||
cargo test --release --all-features
|
||||
(cd test-cargo-miri && ./run-test.py)
|
||||
test-cargo-miri/run-test.py
|
||||
}
|
||||
|
||||
echo "Test host architecture"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue