From 14e482e58f820575714526c5cd6871dc0f2caac4 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 24 Mar 2021 15:09:22 +0100 Subject: [PATCH] Add support for getrandom syscall on DragonFly BSD DragonFly BSD supports the getrandom system call since version 5.7 [1]. Use it if available, otherwise fall back to /dev/random. [1] https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom Signed-off-by: Tobias Klauser --- src/dragonfly.rs | 26 ++++++++++++++++++++++++++ src/lib.rs | 11 ++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/dragonfly.rs diff --git a/src/dragonfly.rs b/src/dragonfly.rs new file mode 100644 index 000000000..f27e90690 --- /dev/null +++ b/src/dragonfly.rs @@ -0,0 +1,26 @@ +// Copyright 2021 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementation for DragonFly BSD +use crate::{ + use_file, + util_libc::{sys_fill_exact, Weak}, + Error, +}; + +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") }; + type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t; + + if let Some(fptr) = GETRANDOM.ptr() { + let func: GetRandomFn = unsafe { core::mem::transmute(fptr) }; + return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) }); + } else { + use_file::getrandom_inner(dest) + } +} diff --git a/src/lib.rs b/src/lib.rs index e77f3017f..bcee9d0fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ //! | FreeBSD | `*‑freebsd` | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5] //! | OpenBSD | `*‑openbsd` | [`getentropy`][6] //! | NetBSD | `*‑netbsd` | [`kern.arandom`][7] -//! | Dragonfly BSD | `*‑dragonfly` | [`/dev/random`][8] +//! | Dragonfly BSD | `*‑dragonfly` | [`getrandom()`][22] if available, otherwise [`/dev/random`][8] //! | Solaris, illumos | `*‑solaris`, `*‑illumos` | [`getrandom()`][9] if available, otherwise [`/dev/random`][10] //! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`][11] //! | Redox | `*‑redox` | [`rand:`][12] @@ -139,6 +139,7 @@ //! [19]: https://www.unix.com/man-page/mojave/2/getentropy/ //! [20]: https://www.unix.com/man-page/mojave/4/random/ //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable +//! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", @@ -167,8 +168,8 @@ pub use crate::error::Error; // // These should all provide getrandom_inner with the same signature as getrandom. cfg_if! { - if #[cfg(any(target_os = "dragonfly", target_os = "emscripten", - target_os = "haiku", target_os = "redox"))] { + if #[cfg(any(target_os = "emscripten", target_os = "haiku", + target_os = "redox"))] { mod util_libc; #[path = "use_file.rs"] mod imp; } else if #[cfg(any(target_os = "android", target_os = "linux"))] { @@ -182,6 +183,10 @@ cfg_if! { } else if #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] { mod util_libc; #[path = "bsd_arandom.rs"] mod imp; + } else if #[cfg(target_os = "dragonfly")] { + mod util_libc; + mod use_file; + #[path = "dragonfly.rs"] mod imp; } else if #[cfg(target_os = "fuchsia")] { #[path = "fuchsia.rs"] mod imp; } else if #[cfg(target_os = "ios")] {