mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Add syscall getrandom
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
3600a3a439
commit
5815f248fc
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -302,6 +302,17 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost"
|
name = "ghost"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -564,6 +575,7 @@ dependencies = [
|
|||||||
"controlled",
|
"controlled",
|
||||||
"core2",
|
"core2",
|
||||||
"cpio-decoder",
|
"cpio-decoder",
|
||||||
|
"getrandom",
|
||||||
"int-to-c-enum",
|
"int-to-c-enum",
|
||||||
"intrusive-collections",
|
"intrusive-collections",
|
||||||
"jinux-block",
|
"jinux-block",
|
||||||
@ -650,9 +662,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.137"
|
version = "0.2.146"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libflate"
|
name = "libflate"
|
||||||
@ -1130,6 +1142,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -42,6 +42,7 @@ spin = "0.9.4"
|
|||||||
vte = "0.10"
|
vte = "0.10"
|
||||||
lru = "0.9.0"
|
lru = "0.9.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
getrandom = { version = "0.2.10", default-features = false, features = ["rdrand"] }
|
||||||
|
|
||||||
[dependencies.lazy_static]
|
[dependencies.lazy_static]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
mod null;
|
mod null;
|
||||||
|
mod random;
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
|
mod urandom;
|
||||||
mod zero;
|
mod zero;
|
||||||
|
|
||||||
use crate::fs::device::{add_node, Device, DeviceId, DeviceType};
|
use crate::fs::device::{add_node, Device, DeviceId, DeviceType};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
pub use random::Random;
|
||||||
|
pub use urandom::Urandom;
|
||||||
|
|
||||||
/// Init the device node in fs, must be called after mounting rootfs.
|
/// Init the device node in fs, must be called after mounting rootfs.
|
||||||
pub fn init() -> Result<()> {
|
pub fn init() -> Result<()> {
|
||||||
@ -14,5 +18,9 @@ pub fn init() -> Result<()> {
|
|||||||
tty::init();
|
tty::init();
|
||||||
let tty = tty::get_n_tty().clone();
|
let tty = tty::get_n_tty().clone();
|
||||||
add_node(tty, "tty")?;
|
add_node(tty, "tty")?;
|
||||||
|
let random = Arc::new(random::Random);
|
||||||
|
add_node(random, "random")?;
|
||||||
|
let urandom = Arc::new(urandom::Urandom);
|
||||||
|
add_node(urandom, "urandom")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
36
services/libs/jinux-std/src/device/random.rs
Normal file
36
services/libs/jinux-std/src/device/random.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use crate::fs::device::{Device, DeviceId, DeviceType};
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub struct Random;
|
||||||
|
|
||||||
|
impl Random {
|
||||||
|
pub fn getrandom(buf: &mut [u8]) -> Result<usize> {
|
||||||
|
getrandom::getrandom(buf)?;
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device for Random {
|
||||||
|
fn type_(&self) -> DeviceType {
|
||||||
|
DeviceType::CharDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> DeviceId {
|
||||||
|
// The same value as Linux
|
||||||
|
DeviceId::new(1, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||||
|
Self::getrandom(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<getrandom::Error> for Error {
|
||||||
|
fn from(value: getrandom::Error) -> Self {
|
||||||
|
Error::with_message(Errno::ENOSYS, "cannot generate random bytes")
|
||||||
|
}
|
||||||
|
}
|
30
services/libs/jinux-std/src/device/urandom.rs
Normal file
30
services/libs/jinux-std/src/device/urandom.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::fs::device::{Device, DeviceId, DeviceType};
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub struct Urandom;
|
||||||
|
|
||||||
|
impl Urandom {
|
||||||
|
pub fn getrandom(buf: &mut [u8]) -> Result<usize> {
|
||||||
|
getrandom::getrandom(buf)?;
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device for Urandom {
|
||||||
|
fn type_(&self) -> DeviceType {
|
||||||
|
DeviceType::CharDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> DeviceId {
|
||||||
|
// The same value as Linux
|
||||||
|
DeviceId::new(1, 9)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||||
|
Self::getrandom(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
}
|
36
services/libs/jinux-std/src/syscall/getrandom.rs
Normal file
36
services/libs/jinux-std/src/syscall/getrandom.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use crate::device;
|
||||||
|
use crate::log_syscall_entry;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::syscall::SYS_GETRANDOM;
|
||||||
|
use crate::util::write_bytes_to_user;
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_getrandom(buf: Vaddr, count: usize, flags: u32) -> Result<SyscallReturn> {
|
||||||
|
log_syscall_entry!(SYS_GETRANDOM);
|
||||||
|
let flags = GetRandomFlags::from_bits_truncate(flags);
|
||||||
|
debug!(
|
||||||
|
"buf = 0x{:x}, count = 0x{:x}, flags = {:?}",
|
||||||
|
buf, count, flags
|
||||||
|
);
|
||||||
|
// TODO: support nonblock flag.
|
||||||
|
// Currently our getrandom implementation relies on x86-specific `rdrand` instruction, so it will never block.
|
||||||
|
let mut buffer = vec![0u8; count];
|
||||||
|
let read_len = if flags.contains(GetRandomFlags::GRND_RANDOM) {
|
||||||
|
device::Random::getrandom(&mut buffer)?
|
||||||
|
} else {
|
||||||
|
device::Urandom::getrandom(&mut buffer)?
|
||||||
|
};
|
||||||
|
write_bytes_to_user(buf, &buffer)?;
|
||||||
|
Ok(SyscallReturn::Return(read_len as isize))
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
#[derive(Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct GetRandomFlags: u32 {
|
||||||
|
const GRND_NONBLOCK = 0x0001;
|
||||||
|
const GRND_RANDOM = 0x0002;
|
||||||
|
const GRND_INSECURE = 0x0004;
|
||||||
|
}
|
||||||
|
}
|
@ -75,6 +75,7 @@ use self::accept::sys_accept;
|
|||||||
use self::bind::sys_bind;
|
use self::bind::sys_bind;
|
||||||
use self::connect::sys_connect;
|
use self::connect::sys_connect;
|
||||||
use self::getpeername::sys_getpeername;
|
use self::getpeername::sys_getpeername;
|
||||||
|
use self::getrandom::sys_getrandom;
|
||||||
use self::getsockname::sys_getsockname;
|
use self::getsockname::sys_getsockname;
|
||||||
use self::listen::sys_listen;
|
use self::listen::sys_listen;
|
||||||
use self::pread64::sys_pread64;
|
use self::pread64::sys_pread64;
|
||||||
@ -114,6 +115,7 @@ mod getpeername;
|
|||||||
mod getpgrp;
|
mod getpgrp;
|
||||||
mod getpid;
|
mod getpid;
|
||||||
mod getppid;
|
mod getppid;
|
||||||
|
mod getrandom;
|
||||||
mod getsockname;
|
mod getsockname;
|
||||||
mod gettid;
|
mod gettid;
|
||||||
mod gettimeofday;
|
mod gettimeofday;
|
||||||
@ -295,7 +297,8 @@ define_syscall_nums!(
|
|||||||
SYS_UTIMENSAT = 280,
|
SYS_UTIMENSAT = 280,
|
||||||
SYS_EPOLL_CREATE1 = 291,
|
SYS_EPOLL_CREATE1 = 291,
|
||||||
SYS_PIPE2 = 293,
|
SYS_PIPE2 = 293,
|
||||||
SYS_PRLIMIT64 = 302
|
SYS_PRLIMIT64 = 302,
|
||||||
|
SYS_GETRANDOM = 318
|
||||||
);
|
);
|
||||||
|
|
||||||
pub struct SyscallArgument {
|
pub struct SyscallArgument {
|
||||||
@ -453,6 +456,7 @@ pub fn syscall_dispatch(
|
|||||||
SYS_EPOLL_CREATE1 => syscall_handler!(1, sys_epoll_create1, args),
|
SYS_EPOLL_CREATE1 => syscall_handler!(1, sys_epoll_create1, args),
|
||||||
SYS_PIPE2 => syscall_handler!(2, sys_pipe2, args),
|
SYS_PIPE2 => syscall_handler!(2, sys_pipe2, args),
|
||||||
SYS_PRLIMIT64 => syscall_handler!(4, sys_prlimit64, args),
|
SYS_PRLIMIT64 => syscall_handler!(4, sys_prlimit64, args),
|
||||||
|
SYS_GETRANDOM => syscall_handler!(3, sys_getrandom, args),
|
||||||
_ => {
|
_ => {
|
||||||
error!("Unimplemented syscall number: {}", syscall_number);
|
error!("Unimplemented syscall number: {}", syscall_number);
|
||||||
return_errno_with_message!(Errno::ENOSYS, "Syscall was unimplemented");
|
return_errno_with_message!(Errno::ENOSYS, "Syscall was unimplemented");
|
||||||
|
Reference in New Issue
Block a user