share getentropy shim across various unixes
This commit is contained in:
parent
6e907fa6ec
commit
edb4c0aece
@ -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
|
// `signal` is set up as a weak symbol in `init_extern_statics` (on Android) so we might as
|
||||||
// well allow it in `dlsym`.
|
// well allow it in `dlsym`.
|
||||||
"signal" => true,
|
"signal" => true,
|
||||||
|
// needed at least on macOS to avoid file-based fallback in getrandom
|
||||||
|
"getentropy" => true,
|
||||||
// Give specific OSes a chance to allow their symbols.
|
// Give specific OSes a chance to allow their symbols.
|
||||||
_ =>
|
_ =>
|
||||||
match target_os {
|
match target_os {
|
||||||
@ -525,6 +527,34 @@ fn emulate_foreign_item_inner(
|
|||||||
let result = this.getpid()?;
|
let result = this.getpid()?;
|
||||||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
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.
|
// 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.
|
// These shims are enabled only when the caller is in the standard library.
|
||||||
@ -594,7 +624,8 @@ fn emulate_foreign_item_inner(
|
|||||||
this.write_int(super::UID, dest)?;
|
this.write_int(super::UID, dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
"getpwuid_r" if this.frame_in_std() => {
|
"getpwuid_r"
|
||||||
|
if this.frame_in_std() => {
|
||||||
let [uid, pwd, buf, buflen, result] =
|
let [uid, pwd, buf, buflen, result] =
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
this.check_no_isolation("`getpwuid_r`")?;
|
this.check_no_isolation("`getpwuid_r`")?;
|
||||||
|
@ -47,23 +47,6 @@ fn emulate_foreign_item_inner(
|
|||||||
this.read_scalar(len)?,
|
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
|
// errno
|
||||||
"__error" => {
|
"__error" => {
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
use shims::unix::fs::EvalContextExt as _;
|
use shims::unix::fs::EvalContextExt as _;
|
||||||
use shims::unix::thread::EvalContextExt as _;
|
use shims::unix::thread::EvalContextExt as _;
|
||||||
|
|
||||||
pub fn is_dyn_sym(name: &str) -> bool {
|
pub fn is_dyn_sym(_name: &str) -> bool {
|
||||||
matches!(name, "getentropy")
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||||
@ -113,18 +113,6 @@ fn emulate_foreign_item_inner(
|
|||||||
this.write_scalar(result, dest)?;
|
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
|
// Access to command-line arguments
|
||||||
"_NSGetArgc" => {
|
"_NSGetArgc" => {
|
||||||
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// mac-os `getrandom_01` does some pointer shenanigans
|
// mac-os `getrandom_01` does some pointer shenanigans
|
||||||
//@compile-flags: -Zmiri-permissive-provenance
|
//@compile-flags: -Zmiri-permissive-provenance
|
||||||
|
|
||||||
/// Test direct calls of getrandom 0.1 and 0.2
|
/// Test direct calls of getrandom 0.1 and 0.2.
|
||||||
|
/// Make sure they work even with isolation enabled (i.e., we do not hit a file-based fallback path).
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut data = vec![0; 16];
|
let mut data = vec![0; 16];
|
||||||
getrandom_01::getrandom(&mut data).unwrap();
|
getrandom_01::getrandom(&mut data).unwrap();
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
//@only-target-freebsd
|
//@ignore-target-windows: no libc
|
||||||
|
|
||||||
|
// on macOS this is not in the `libc` crate.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
extern "C" {
|
||||||
|
fn getentropy(bytes: *mut libc::c_void, count: libc::size_t) -> libc::c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
use libc::getentropy;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut buf1 = [0u8; 256];
|
let mut buf1 = [0u8; 256];
|
||||||
let mut buf2 = [0u8; 257];
|
let mut buf2 = [0u8; 257];
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_eq!(libc::getentropy(buf1.as_mut_ptr() as *mut libc::c_void, buf1.len()), 0);
|
assert_eq!(getentropy(buf1.as_mut_ptr() as *mut libc::c_void, buf1.len()), 0);
|
||||||
assert_eq!(libc::getentropy(buf2.as_mut_ptr() as *mut libc::c_void, buf2.len()), -1);
|
assert_eq!(getentropy(buf2.as_mut_ptr() as *mut libc::c_void, buf2.len()), -1);
|
||||||
assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::EIO);
|
assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user