Skip to content

Commit aaf5c5e

Browse files
committed
move randomness tests into a single file and share the getrandom implementation across unices
1 parent 352b210 commit aaf5c5e

File tree

7 files changed

+55
-88
lines changed

7 files changed

+55
-88
lines changed

src/tools/miri/ci/ci.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,12 @@ case $HOST_TARGET in
143143
# Partially supported targets (tier 2)
144144
VERY_BASIC="integer vec string btreemap" # common things we test on all of them (if they have std), requires no target-specific shims
145145
BASIC="$VERY_BASIC hello hashmap alloc align" # ensures we have the shims for stdout and basic data structures
146-
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
147-
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
148-
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic
149-
MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-misc
146+
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-misc libc-random libc-time fs env num_cpus
147+
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-misc libc-random libc-time fs env num_cpus
148+
MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-misc libc-random
150149
# TODO fix solaris stack guard
151150
# MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic pthread-sync
151+
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic
152152
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm
153153
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm
154154
MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std

src/tools/miri/src/shims/unix/foreign_items.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
2323
// well allow it in `dlsym`.
2424
"signal" => true,
2525
// needed at least on macOS to avoid file-based fallback in getrandom
26-
"getentropy" => true,
26+
"getentropy" | "getrandom" => true,
2727
// Give specific OSes a chance to allow their symbols.
2828
_ =>
2929
match target_os {
@@ -632,6 +632,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
632632
this.write_scalar(Scalar::from_i32(0), dest)?;
633633
}
634634
}
635+
"getrandom" => {
636+
// This function is non-standard but exists with the same signature and behavior on
637+
// Linux, FreeBSD and Solaris/Illumos.
638+
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris") {
639+
throw_unsup_format!(
640+
"`getentropy` is not supported on {}",
641+
this.tcx.sess.target.os
642+
);
643+
}
644+
let [ptr, len, flags] =
645+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
646+
let ptr = this.read_pointer(ptr)?;
647+
let len = this.read_target_usize(len)?;
648+
let _flags = this.read_scalar(flags)?.to_i32()?;
649+
// We ignore the flags, just always use the same PRNG / host RNG.
650+
this.gen_random(ptr, len)?;
651+
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
652+
}
635653

636654
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
637655
// These shims are enabled only when the caller is in the standard library.

src/tools/miri/src/shims/unix/freebsd/foreign_items.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2020
let this = self.eval_context_mut();
2121
match link_name.as_str() {
2222
// Threading
23-
"pthread_attr_get_np" if this.frame_in_std() => {
24-
let [_thread, _attr] =
25-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
26-
this.write_null(dest)?;
27-
}
2823
"pthread_set_name_np" => {
2924
let [thread, name] =
3025
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
@@ -75,27 +70,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7570
}
7671

7772
// Miscellaneous
78-
"getrandom" => {
79-
let [ptr, len, flags] =
80-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
81-
let ptr = this.read_pointer(ptr)?;
82-
let len = this.read_target_usize(len)?;
83-
let _flags = this.read_scalar(flags)?.to_i32()?;
84-
// flags on freebsd does not really matter
85-
// in practice, GRND_RANDOM does not particularly draw from /dev/random
86-
// since it is the same as to /dev/urandom.
87-
// GRND_INSECURE is only an alias of GRND_NONBLOCK, which
88-
// does not affect the RNG.
89-
// https://man.freebsd.org/cgi/man.cgi?query=getrandom&sektion=2&n=1
90-
this.gen_random(ptr, len)?;
91-
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
92-
}
9373
"__error" => {
9474
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
9575
let errno_place = this.last_error_place()?;
9676
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
9777
}
9878

79+
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
80+
// These shims are enabled only when the caller is in the standard library.
81+
"pthread_attr_get_np" if this.frame_in_std() => {
82+
let [_thread, _attr] =
83+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
84+
this.write_null(dest)?;
85+
}
86+
9987
_ => return Ok(EmulateItemResult::NotSupported),
10088
}
10189
Ok(EmulateItemResult::NeedsJumping)

src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use shims::unix::linux::mem::EvalContextExt as _;
1111
use shims::unix::linux::sync::futex;
1212

1313
pub fn is_dyn_sym(name: &str) -> bool {
14-
matches!(name, "getrandom" | "statx")
14+
matches!(name, "statx")
1515
}
1616

1717
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
@@ -140,11 +140,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
140140
}
141141

142142
// Miscellaneous
143-
"getrandom" => {
144-
let [ptr, len, flags] =
145-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
146-
getrandom(this, ptr, len, flags, dest)?;
147-
}
148143
"mmap64" => {
149144
let [addr, length, prot, flags, fd, offset] =
150145
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

src/tools/miri/tests/pass-dep/shims/libc-getentropy.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/tools/miri/tests/pass-dep/shims/libc-getrandom-without-isolation.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/tools/miri/tests/pass-dep/shims/libc-getrandom.rs renamed to src/tools/miri/tests/pass-dep/shims/libc-random.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
//@ignore-target-windows: no libc
2-
//@ignore-target-apple: no getrandom
3-
4-
use std::ptr;
2+
//@revisions: isolation no_isolation
3+
//@[no_isolation]compile-flags: -Zmiri-disable-isolation
54

65
fn main() {
6+
test_getentropy();
7+
#[cfg(not(target_os = "macos"))]
8+
test_getrandom();
9+
}
10+
11+
fn test_getentropy() {
12+
use libc::getentropy;
13+
14+
let mut buf1 = [0u8; 256];
15+
let mut buf2 = [0u8; 257];
16+
unsafe {
17+
assert_eq!(getentropy(buf1.as_mut_ptr() as *mut libc::c_void, buf1.len()), 0);
18+
assert_eq!(getentropy(buf2.as_mut_ptr() as *mut libc::c_void, buf2.len()), -1);
19+
assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::EIO);
20+
}
21+
}
22+
23+
#[cfg(not(target_os = "macos"))]
24+
fn test_getrandom() {
25+
use std::ptr;
26+
727
let mut buf = [0u8; 5];
828
unsafe {
929
#[cfg(target_os = "linux")]

0 commit comments

Comments
 (0)