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
7 changes: 4 additions & 3 deletions src/entropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rand_chacha::rand_core::{Rng, SeedableRng};

use crate::arch::kernel::processor::{get_timer_ticks, seed_entropy};
use crate::errno::Errno;
use crate::io;

// Reseed every second for increased security while maintaining the performance of
// the PRNG.
Expand All @@ -29,14 +30,14 @@ static POOL: InterruptTicketMutex<Option<Pool>> = InterruptTicketMutex::new(None
///
/// Returns the number of bytes written or `-ENOSYS` if the system does not support
/// random data generation.
pub fn read(buf: &mut [u8], _flags: Flags) -> isize {
pub fn read(buf: &mut [u8], _flags: Flags) -> io::Result<usize> {
let pool = &mut *POOL.lock();
let now = get_timer_ticks();
let pool = match pool {
Some(pool) if now.saturating_sub(pool.last_reseed) <= RESEED_INTERVAL => pool,
pool => {
let Some(seed) = seed_entropy() else {
return -i32::from(Errno::Nosys) as isize;
return Err(Errno::Nosys);
};

pool.insert(Pool {
Expand All @@ -49,5 +50,5 @@ pub fn read(buf: &mut [u8], _flags: Flags) -> isize {
pool.rng.fill_bytes(buf);
// Slice lengths are always <= isize::MAX so this return value cannot conflict
// with error numbers.
buf.len() as isize
Ok(buf.len())
}
4 changes: 4 additions & 0 deletions src/fd/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use core::mem::MaybeUninit;
use delegate::delegate;

use crate::fd::eventfd::EventFd;
use crate::fd::random_file::RandomFile;
#[cfg(feature = "tcp")]
use crate::fd::socket::tcp;
#[cfg(feature = "udp")]
Expand Down Expand Up @@ -54,6 +55,7 @@ pub(crate) enum Fd {
DirectoryReader(DirectoryReader),
#[cfg(feature = "uhyve")]
UhyveFileHandle(UhyveFileHandle),
RandomFile(RandomFile),
}

macro_rules! fd_from {
Expand Down Expand Up @@ -103,6 +105,7 @@ fd_from! {
DirectoryReader(DirectoryReader),
#[cfg(feature = "uhyve")]
UhyveFileHandle(UhyveFileHandle),
RandomFile(RandomFile),
}

impl ObjectInterface for Fd {
Expand Down Expand Up @@ -136,6 +139,7 @@ impl ObjectInterface for Fd {
Self::DirectoryReader(fd) => fd,
#[cfg(feature = "uhyve")]
Self::UhyveFileHandle(fd) => fd,
Self::RandomFile(fd) => fd,
} {
async fn poll(&self, event: PollEvent) -> io::Result<PollEvent>;
async fn read(&self, buf: &mut [u8]) -> io::Result<usize>;
Expand Down
1 change: 1 addition & 0 deletions src/fd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::io;

mod delegate;
mod eventfd;
pub(crate) mod random_file;
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
pub(crate) mod socket;
pub(crate) mod stdio;
Expand Down
10 changes: 10 additions & 0 deletions src/fd/random_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::fd::ObjectInterface;
use crate::{entropy, io};

pub struct RandomFile;

impl ObjectInterface for RandomFile {
async fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
entropy::read(buf, entropy::Flags::empty())
}
}
39 changes: 39 additions & 0 deletions src/fs/dev_directory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use alloc::boxed::Box;
use alloc::sync::Arc;

use crate::errno::Errno;
use crate::fd::random_file::RandomFile;
use crate::fd::{AccessPermission, Fd, OpenOption};
use crate::fs::{NodeKind, VfsNode};
use crate::io;

pub(crate) fn init() {
crate::fs::FILESYSTEM
.get()
.unwrap()
.mount("/dev", Box::new(DevDirectory))
.unwrap();
}

#[derive(Debug)]
pub(crate) struct DevDirectory;

impl VfsNode for DevDirectory {
fn get_kind(&self) -> NodeKind {
NodeKind::Directory
}

fn traverse_open(
&self,
path: &str,
_option: OpenOption,
_mode: AccessPermission,
) -> io::Result<Arc<async_lock::RwLock<Fd>>> {
match path {
"urandom" | "random" => Ok(Arc::new(async_lock::RwLock::new(Fd::RandomFile(
RandomFile,
)))),
_ => Err(Errno::Noent),
}
}
}
1 change: 0 additions & 1 deletion src/fs/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,6 @@ impl VfsNode for MemDirectory {
)
}

#[cfg(any(feature = "uhyve", feature = "virtio-fs"))]
fn traverse_mount(&self, path: &str, obj: Box<dyn VfsNode>) -> io::Result<()> {
block_on(
async {
Expand Down
6 changes: 3 additions & 3 deletions src/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
pub(crate) mod dev_directory;
pub(crate) mod mem;
#[cfg(feature = "uhyve")]
pub(crate) mod uhyve;
#[cfg(feature = "virtio-fs")]
pub(crate) mod virtio_fs;

use alloc::borrow::ToOwned;
#[cfg(any(feature = "uhyve", feature = "virtio-fs"))]
use alloc::boxed::Box;
use alloc::string::String;
use alloc::sync::Arc;
Expand Down Expand Up @@ -98,7 +98,6 @@ pub(crate) trait VfsNode: Send + Sync + fmt::Debug {
}

/// Mounts a file system
#[cfg(any(feature = "uhyve", feature = "virtio-fs"))]
fn traverse_mount(&self, _path: &str, _obj: Box<dyn VfsNode>) -> io::Result<()> {
Err(Errno::Nosys)
}
Expand Down Expand Up @@ -228,7 +227,6 @@ impl Filesystem {
}

/// Create new backing-fs at mountpoint mntpath
#[cfg(any(feature = "uhyve", feature = "virtio-fs"))]
pub fn mount(&self, path: &str, obj: Box<dyn VfsNode>) -> io::Result<()> {
debug!("Mounting {path}");

Expand Down Expand Up @@ -336,6 +334,8 @@ pub(crate) fn init() {
if crate::env::is_uhyve() {
uhyve::init();
}

dev_directory::init();
}

pub fn create_file(name: &str, data: &'static [u8], mode: AccessPermission) -> io::Result<()> {
Expand Down
24 changes: 12 additions & 12 deletions src/syscalls/entropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ unsafe fn read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize {
slice::from_raw_parts_mut(buf, len)
};

let ret = entropy::read(buf, flags);
if ret < 0 {
warn!("Unable to read entropy! Fallback to a naive implementation!");
for byte in &mut *buf {
*byte = (generate_park_miller_lehmer_random_number() & 0xff)
.try_into()
.unwrap();
}
buf.len().try_into().unwrap()
} else {
ret
}
entropy::read(buf, flags)
.unwrap_or_else(|_| {
warn!("Unable to read entropy! Fallback to a naive implementation!");
for byte in &mut *buf {
*byte = (generate_park_miller_lehmer_random_number() & 0xff)
.try_into()
.unwrap();
}
buf.len()
})
.try_into()
.unwrap()
}

/// Fill `len` bytes in `buf` with cryptographically secure random data.
Expand Down
Loading