Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/nopanic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: No panic

on:
push:
branches: master
pull_request:
branches: master

permissions:
contents: read

defaults:
run:
working-directory: nopanic_check

env:
RUSTFLAGS: "-Dwarnings"

jobs:
linux:
name: Linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
# We need Nightly for the rust-std component for wasm32-wasip2
toolchain: nightly-2024-10-14
targets: wasm32-wasip1, wasm32-wasip2

- name: Build (linux_android_with_fallback.rs)
run: cargo build --release
- name: Check (linux_android_with_fallback.rs)
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]

- name: Build (linux_android.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
run: cargo build --release
- name: Check (linux_android.rs)
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]

- name: Build (rdrand.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rdrand"
run: cargo build --release
- name: Check (rdrand.rs)
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]

- name: Build (wasi.rs, preview 1)
run: cargo build --release --target wasm32-wasip1
- name: Check (wasi.rs, preview 1)
run: ret=$(grep panic target/wasm32-wasip1/release/getrandom_wrapper.wasm; echo $?); [ $ret -eq 1 ]

- name: Build (wasi.rs, preview 2)
run: cargo build --release --target wasm32-wasip2
- name: Check (wasi.rs, preview 2)
run: ret=$(grep panic target/wasm32-wasip2/release/getrandom_wrapper.wasm; echo $?); [ $ret -eq 1 ]

macos:
name: macOS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

- name: Build (getentropy.rs)
run: cargo build --release
- name: Check (getentropy.rs)
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]
16 changes: 16 additions & 0 deletions nopanic_check/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "nopanic_check"
description = "Helper crate for checking that getrandom implementation does not contain potential panics"
version = "0.1.0"
edition = "2021"
publish = false

[lib]
name = "getrandom_wrapper"
crate-type = ["cdylib"]

[dependencies]
getrandom = { path = ".." }

[profile.release]
panic = "abort"
18 changes: 18 additions & 0 deletions nopanic_check/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// WASI preview 2 requires enabled std
#![cfg_attr(not(all(target_arch = "wasm32", target_env = "p2")), no_std)]

#[cfg(not(any(test, all(target_arch = "wasm32", target_env = "p2"))))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
extern "C" {
fn panic_nonexistent() -> !;
}
unsafe { panic_nonexistent() }
}

#[no_mangle]
pub extern "C" fn getrandom_wrapper(buf_ptr: *mut u8, buf_len: usize) -> u32 {
let buf = unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), buf_len) };
let res = getrandom::getrandom_uninit(buf).map(|_| ());
unsafe { core::mem::transmute(res) }
}
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@
//! on every call to `getrandom`, hence after the first successful call one
//! can be reasonably confident that no errors will occur.
//!
//! ## Panic handling
//!
//! We strive to eliminate all potential panics from our implementation.
//! In other words, when compiled with enabled optimizations, generated
//! binary code for `getrandom` functions should not contain any panic
//! branches. Even if platform misbiheaves and returns an unexpected
//! result, our code should correctly handle it and return an error like
//! [`Error::UNEXPECTED`].
//!
//! [1]: https://manned.org/getrandom.2
//! [2]: https://manned.org/urandom.4
//! [3]: https://www.unix.com/man-page/mojave/2/getentropy/
Expand Down