@@ -27,6 +27,8 @@ fn is_dyn_sym(name: &str, target_os: &str) -> bool {
27
27
// `signal` is set up as a weak symbol in `init_extern_statics` (on Android) so we might as
28
28
// well allow it in `dlsym`.
29
29
"signal" => true ,
30
+ // needed at least on macOS to avoid file-based fallback in getrandom
31
+ "getentropy" => true ,
30
32
// Give specific OSes a chance to allow their symbols.
31
33
_ =>
32
34
match target_os {
@@ -525,6 +527,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
525
527
let result = this. getpid ( ) ?;
526
528
this. write_scalar ( Scalar :: from_i32 ( result) , dest) ?;
527
529
}
530
+ "getentropy" => {
531
+ // This function is non-standard but exists with the same signature and behavior on
532
+ // Linux, macOS, and FreeBSD.
533
+ if !matches ! ( & * this. tcx. sess. target. os, "linux" | "macos" | "freebsd" ) {
534
+ throw_unsup_format ! (
535
+ "`getentropy` is not supported on {}" ,
536
+ this. tcx. sess. target. os
537
+ ) ;
538
+ }
539
+
540
+ let [ buf, bufsize] =
541
+ this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
542
+ let buf = this. read_pointer ( buf) ?;
543
+ let bufsize = this. read_target_usize ( bufsize) ?;
544
+
545
+ // getentropy sets errno to EIO when the buffer size exceeds 256 bytes.
546
+ // FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=getentropy&sektion=3&format=html
547
+ // Linux: https://man7.org/linux/man-pages/man3/getentropy.3.html
548
+ // macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html
549
+ if bufsize > 256 {
550
+ let err = this. eval_libc ( "EIO" ) ;
551
+ this. set_last_error ( err) ?;
552
+ this. write_scalar ( Scalar :: from_i32 ( -1 ) , dest) ?
553
+ } else {
554
+ this. gen_random ( buf, bufsize) ?;
555
+ this. write_scalar ( Scalar :: from_i32 ( 0 ) , dest) ?;
556
+ }
557
+ }
528
558
529
559
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
530
560
// These shims are enabled only when the caller is in the standard library.
@@ -594,7 +624,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
594
624
this. write_int ( super :: UID , dest) ?;
595
625
}
596
626
597
- "getpwuid_r" if this. frame_in_std ( ) => {
627
+ "getpwuid_r"
628
+ if this. frame_in_std ( ) => {
598
629
let [ uid, pwd, buf, buflen, result] =
599
630
this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
600
631
this. check_no_isolation ( "`getpwuid_r`" ) ?;
0 commit comments