From 6722d148c6394fd53dadb10cd621f1d58778d912 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 Nov 2023 08:40:40 +0100 Subject: [PATCH 1/2] organize pass-dep tests more by the crate they test --- test_dependencies/Cargo.toml | 4 ++-- tests/pass-dep/getrandom.rs | 9 +++++++++ tests/pass-dep/getrandom_1.rs | 8 -------- tests/pass-dep/{random.rs => rand.rs} | 11 +++++++---- 4 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 tests/pass-dep/getrandom.rs delete mode 100644 tests/pass-dep/getrandom_1.rs rename tests/pass-dep/{random.rs => rand.rs} (61%) diff --git a/test_dependencies/Cargo.toml b/test_dependencies/Cargo.toml index 670f5c895c..d54560608d 100644 --- a/test_dependencies/Cargo.toml +++ b/test_dependencies/Cargo.toml @@ -12,8 +12,8 @@ edition = "2021" libc = "0.2" num_cpus = "1.10.1" -getrandom_1 = { package = "getrandom", version = "0.1" } -getrandom = { version = "0.2", features = ["js"] } +getrandom_01 = { package = "getrandom", version = "0.1" } +getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] } rand = { version = "0.8", features = ["small_rng"] } [target.'cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))'.dependencies] diff --git a/tests/pass-dep/getrandom.rs b/tests/pass-dep/getrandom.rs new file mode 100644 index 0000000000..60d6dd31e7 --- /dev/null +++ b/tests/pass-dep/getrandom.rs @@ -0,0 +1,9 @@ +// mac-os `getrandom_01` does some pointer shenanigans +//@compile-flags: -Zmiri-permissive-provenance + +/// Test direct calls of getrandom 0.1 and 0.2 +fn main() { + let mut data = vec![0; 16]; + getrandom_01::getrandom(&mut data).unwrap(); + getrandom_02::getrandom(&mut data).unwrap(); +} diff --git a/tests/pass-dep/getrandom_1.rs b/tests/pass-dep/getrandom_1.rs deleted file mode 100644 index 2c7bd93fbd..0000000000 --- a/tests/pass-dep/getrandom_1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// mac-os `getrandom_1` does some pointer shenanigans -//@compile-flags: -Zmiri-permissive-provenance - -/// Test old version of `getrandom`. -fn main() { - let mut data = vec![0; 16]; - getrandom_1::getrandom(&mut data).unwrap(); -} diff --git a/tests/pass-dep/random.rs b/tests/pass-dep/rand.rs similarity index 61% rename from tests/pass-dep/random.rs rename to tests/pass-dep/rand.rs index 0cd8b06d63..0dce6d86cf 100644 --- a/tests/pass-dep/random.rs +++ b/tests/pass-dep/rand.rs @@ -1,10 +1,13 @@ //@compile-flags: -Zmiri-strict-provenance -use rand::{rngs::SmallRng, Rng, SeedableRng}; +use rand::prelude::*; +// Test using the `rand` crate to generate randomness. fn main() { - // Test `getrandom` directly. - let mut data = vec![0; 16]; - getrandom::getrandom(&mut data).unwrap(); + // Fully deterministic seeding. + let mut rng = SmallRng::seed_from_u64(42); + let _val = rng.gen::(); + let _val = rng.gen::(); + let _val = rng.gen::(); // Try seeding with "real" entropy. let mut rng = SmallRng::from_entropy(); From cb0d2c3cf68a2fe2515cd7b416407e15eb374284 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 Nov 2023 18:30:39 +0100 Subject: [PATCH 2/2] share getentropy shim across various unixes --- src/shims/unix/foreign_items.rs | 30 +++++++++++++++++++++++++ src/shims/unix/freebsd/foreign_items.rs | 17 -------------- src/shims/unix/macos/foreign_items.rs | 16 ++----------- tests/pass-dep/shims/libc-getentropy.rs | 2 +- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index c013d27502..13c86c508c 100644 --- a/src/shims/unix/foreign_items.rs +++ b/src/shims/unix/foreign_items.rs @@ -27,6 +27,8 @@ fn is_dyn_sym(name: &str, target_os: &str) -> bool { // `signal` is set up as a weak symbol in `init_extern_statics` (on Android) so we might as // well allow it in `dlsym`. "signal" => true, + // needed at least on macOS + "getentropy" => true, // Give specific OSes a chance to allow their symbols. _ => match target_os { @@ -525,6 +527,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let result = this.getpid()?; this.write_scalar(Scalar::from_i32(result), dest)?; } + "getentropy" => { + // This function is non-standard but exists with the same signature and behavior on + // Linux, macOS, and freeBSD. + if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd") { + throw_unsup_format!( + "`getentropy` is not supported on {}", + this.tcx.sess.target.os + ); + } + + let [buf, bufsize] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let buf = this.read_pointer(buf)?; + let bufsize = this.read_target_usize(bufsize)?; + + // getentropy sets errno to EIO when the buffer size exceeds 256 bytes. + // FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=getentropy&sektion=3&format=html + // Linux: https://man7.org/linux/man-pages/man3/getentropy.3.html + // macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html + if bufsize > 256 { + let err = this.eval_libc("EIO"); + this.set_last_error(err)?; + this.write_scalar(Scalar::from_i32(-1), dest)? + } else { + this.gen_random(buf, bufsize)?; + this.write_scalar(Scalar::from_i32(0), dest)?; + } + } // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. diff --git a/src/shims/unix/freebsd/foreign_items.rs b/src/shims/unix/freebsd/foreign_items.rs index f81710a41a..96e322c4cf 100644 --- a/src/shims/unix/freebsd/foreign_items.rs +++ b/src/shims/unix/freebsd/foreign_items.rs @@ -47,23 +47,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.read_scalar(len)?, )?; } - "getentropy" => { - let [buf, bufsize] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let buf = this.read_pointer(buf)?; - let bufsize = this.read_target_usize(bufsize)?; - - // getentropy sets errno to EIO when the buffer size exceeds 256 bytes. - // https://man.freebsd.org/cgi/man.cgi?query=getentropy&sektion=3&format=html - if bufsize > 256 { - let err = this.eval_libc("EIO"); - this.set_last_error(err)?; - this.write_scalar(Scalar::from_i32(-1), dest)? - } else { - this.gen_random(buf, bufsize)?; - this.write_scalar(Scalar::from_i32(0), dest)?; - } - } // errno "__error" => { diff --git a/src/shims/unix/macos/foreign_items.rs b/src/shims/unix/macos/foreign_items.rs index 5881a3f46f..e8f35e7ba5 100644 --- a/src/shims/unix/macos/foreign_items.rs +++ b/src/shims/unix/macos/foreign_items.rs @@ -6,8 +6,8 @@ use shims::foreign_items::EmulateForeignItemResult; use shims::unix::fs::EvalContextExt as _; use shims::unix::thread::EvalContextExt as _; -pub fn is_dyn_sym(name: &str) -> bool { - matches!(name, "getentropy") +pub fn is_dyn_sym(_name: &str) -> bool { + false } impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} @@ -113,18 +113,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(result, dest)?; } - // Random generation related shims - "getentropy" => { - let [buf, bufsize] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let buf = this.read_pointer(buf)?; - let bufsize = this.read_target_usize(bufsize)?; - - this.gen_random(buf, bufsize)?; - - this.write_scalar(Scalar::from_i32(0), dest)?; // KERN_SUCCESS - } - // Access to command-line arguments "_NSGetArgc" => { let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; diff --git a/tests/pass-dep/shims/libc-getentropy.rs b/tests/pass-dep/shims/libc-getentropy.rs index 468727f70e..351f635fe4 100644 --- a/tests/pass-dep/shims/libc-getentropy.rs +++ b/tests/pass-dep/shims/libc-getentropy.rs @@ -1,4 +1,4 @@ -//@only-target-freebsd +//@ignore-target-windows: no libc fn main() { let mut buf1 = [0u8; 256];