Skip to main content

shadow_rs/host/syscall/handler/
random.rs

1use linux_api::errno::Errno;
2use log::*;
3use rand::Rng;
4use shadow_shim_helper_rs::syscall_types::ForeignPtr;
5
6use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
7use crate::host::syscall::types::ForeignArrayPtr;
8
9impl SyscallHandler {
10    log_syscall!(
11        getrandom,
12        /* rv */ isize,
13        /* buf */ *const std::ffi::c_void,
14        /* count */ usize,
15        /* flags */ std::ffi::c_uint,
16    );
17    pub fn getrandom(
18        ctx: &mut SyscallContext,
19        buf_ptr: ForeignPtr<u8>,
20        count: usize,
21        _flags: std::ffi::c_uint,
22    ) -> Result<isize, Errno> {
23        // We ignore the flags arg, because we use the same random source for both
24        // random and urandom, and it never blocks anyway.
25
26        trace!("Trying to read {count} random bytes.");
27
28        // Get random bytes using host rng to maintain determinism.
29        let rnd_bytes = {
30            let mut v = vec![0u8; count];
31            let mut rng = ctx.objs.host.random_mut();
32            rng.fill_bytes(&mut v);
33            v
34        };
35
36        // Copy to managed process.
37        ctx.objs
38            .process
39            .memory_borrow_mut()
40            .copy_to_ptr(ForeignArrayPtr::new(buf_ptr, count), &rnd_bytes)?;
41
42        Ok(isize::try_from(count).unwrap())
43    }
44}