Skip to content

Commit

Permalink
Move __getrandom_custom definition into an unnamed block
Browse files Browse the repository at this point in the history
This supersedes #341, and makes the following changes
  - All the code for implementing `__getrandom_custom` is now in an
    unnamed `const` block (stable since 1.37)
    - I found this approch [here](https://internals.rust-lang.org/t/anonymous-modules/15441)
    - Nothing inside the block can be referenced outside of it
  - `__getrandom_custom` is marked `unsafe`
    - It can't be accessed externally, but is "logically" unsafe as it
      dereferences raw pointers
  - The type of the function is moved to a typedef, so we can check that
    the defined type matches that of `getrandom:getrandom`.
  - Use `::core::result::Result` instead of `Result`
    - Similar to use use of `from_raw_parts_mut` this prevents
      compilation errors if `Result` is redefined.

Signed-off-by: Joe Richey <[email protected]>
  • Loading branch information
josephlr committed Mar 9, 2023
1 parent 93c3074 commit 419a6ae
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions src/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,23 @@ use core::{mem::MaybeUninit, num::NonZeroU32};
#[cfg_attr(docsrs, doc(cfg(feature = "custom")))]
macro_rules! register_custom_getrandom {
($path:path) => {
// We use an extern "C" function to get the guarantees of a stable ABI.
#[no_mangle]
extern "C" fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
let f: fn(&mut [u8]) -> Result<(), $crate::Error> = $path;
let slice = unsafe { ::core::slice::from_raw_parts_mut(dest, len) };
match f(slice) {
Ok(()) => 0,
Err(e) => e.code().get(),
// This unnamed block (stable since 1.37) prevents seeing __getrandom_custom
const _: () = {
// Make sure the passed function has the type of getrandom::getrandom
type F = fn(&mut [u8]) -> ::core::result::Result<(), $crate::Error>;
const _: F = $crate::getrandom;

// We use an extern "C" function to get the guarantees of a stable ABI.
#[no_mangle]
unsafe extern "C" fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
let f: F = $path;
let slice = ::core::slice::from_raw_parts_mut(dest, len);
match f(slice) {
Ok(()) => 0,
Err(e) => e.code().get(),
}
}
}
};
};
}

Expand Down

0 comments on commit 419a6ae

Please sign in to comment.