vdso-rng

Crates.iovdso-rng
lib.rsvdso-rng
version0.3.0
created_at2025-07-14 19:04:21.472508+00
updated_at2025-07-14 21:28:56.089345+00
descriptionA Rust wrapper around the Linux vDSO random number generator.
homepagehttps://github.com/schrodingerzhu/useless
repositoryhttps://github.com/schrodingerzhu/useless
max_upload_size
id1752186
size61,704
Schrodinger ZHU Yifan (SchrodingerZhu)

documentation

README

vDSO-RNG

A Rust wrapper around the Linux vDSO random number generator.

Unfortunately, rustix does not currently expose sufficient APIs to access getrandom via vDSO.
This crate provides an alternative, dependency-free wrapper for such functionality, without relying on libc.

Overview

This crate provides two key data structures:

  • [Pool]: A synchronous, thread-safe state pool for managing shared vDSO random state.
  • [LocalState]: A thread-local state object rented from the pool, used for generating random bytes.

Example: Global Setup

To set up the random generator globally, you can use the following pattern:

use std::cell::RefCell;
use vdso_rng::{Pool, LocalState, Error};

fn global_pool() -> &'static Pool {
    static GLOBAL_STATE: std::sync::LazyLock<Pool> =
        std::sync::LazyLock::new(|| Pool::new().expect("Failed to create global pool"));
    &GLOBAL_STATE
}

fn fill(buf: &mut [u8], flag: u32) -> Result<(), Error> {
    std::thread_local! {
        static LOCAL_STATE: RefCell<LocalState<'static>> =
            RefCell::new(LocalState::new(global_pool()).expect("Failed to create local state"));
    }
    LOCAL_STATE.with(|local_state| {
        let mut state = local_state.borrow_mut();
        state.fill(buf, flag)
    })
}

fn main() {
    std::thread::scope(|scope| {
        for _ in 0..16 {
            scope.spawn(|| {
                for _ in 0..16 {
                    let mut buf = [0u8; 64];
                    let res = fill(&mut buf, 0);
                    assert!(res.is_ok(), "Failed to fill global state: {:?}", res);
                    assert!(buf.iter().any(|&x| x != 0), "Buffer should not be empty");
                }
            });
        }
    });
}

Safety

For safety considerations, including async-signal-safety and fork behavior, please refer to the documentation for:

  • [Pool]
  • [LocalState]
Commit count: 0

cargo fmt