Skip to content

Commit

Permalink
fix(syscalls): don't call foreign __sys functions
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <[email protected]>
  • Loading branch information
mkroening committed Mar 23, 2024
1 parent d3b7516 commit 5716d40
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/arch/x86_64/kernel/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ pub fn configure() {
#[cfg(feature = "fsgsbase")]
if !supports_fsgs() {
error!("FSGSBASE support is enabled, but the processor doesn't support it!");
crate::__sys_shutdown(1);
crate::shutdown(1);
}

debug!("Set CR4 to {:#x}", cr4);
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,5 +267,5 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
let core_id = crate::arch::core_local::core_id();
println!("[{core_id}][PANIC] {info}");

crate::__sys_shutdown(1);
crate::shutdown(1);
}
2 changes: 1 addition & 1 deletion src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static mut SHELL: Lazy<Shell<'_>> = Lazy::new(|| {
ShellCommand {
help: "Shutdown HermitOS",
func: |_, shell| {
crate::__sys_shutdown(0);
crate::shutdown(0);
Ok(())
},
aliases: &["s"],
Expand Down
39 changes: 28 additions & 11 deletions src/syscalls/entropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn generate_park_miller_lehmer_random_number() -> u32 {
random
}

unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize {
unsafe fn read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize {
let Some(flags) = Flags::from_bits(flags) else {
return -EINVAL as isize;
};
Expand All @@ -44,28 +44,28 @@ unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) ->
}
}

unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize {
unsafe { read_entropy(buf, len, flags) }
}

/// Fill `len` bytes in `buf` with cryptographically secure random data.
///
/// Returns either the number of bytes written to buf (a positive value) or
/// * `-EINVAL` if `flags` contains unknown flags.
/// * `-ENOSYS` if the system does not support random data generation.
#[allow(unsafe_op_in_unsafe_fn)]
#[no_mangle]
#[cfg_attr(target_arch = "riscv64", allow(unsafe_op_in_unsafe_fn))] // FIXME
pub unsafe extern "C" fn sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize {
kernel_function!(__sys_read_entropy(buf, len, flags))
}

/// Create a cryptographicly secure 32bit random number with the support of
/// the underlying hardware. If the required hardware isn't available,
/// the function returns `-1`.
#[cfg(not(feature = "newlib"))]
#[no_mangle]
pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 {
unsafe extern "C" fn __sys_secure_rand32(value: *mut u32) -> i32 {
let mut buf = value.cast();
let mut len = size_of::<u32>();
while len != 0 {
let res = unsafe { sys_read_entropy(buf, len, 0) };
let res = unsafe { read_entropy(buf, len, 0) };
if res < 0 {
return -1;
}
Expand All @@ -77,16 +77,23 @@ pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 {
0
}

/// Create a cryptographicly secure 64bit random number with the support of
/// Create a cryptographicly secure 32bit random number with the support of
/// the underlying hardware. If the required hardware isn't available,
/// the function returns -1.
/// the function returns `-1`.
#[cfg(not(feature = "newlib"))]
#[allow(unsafe_op_in_unsafe_fn)]
#[no_mangle]
pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 {
pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 {
kernel_function!(__sys_secure_rand32(value))
}

#[cfg(not(feature = "newlib"))]
#[no_mangle]
unsafe extern "C" fn __sys_secure_rand64(value: *mut u64) -> i32 {
let mut buf = value.cast();
let mut len = size_of::<u64>();
while len != 0 {
let res = unsafe { sys_read_entropy(buf, len, 0) };
let res = unsafe { read_entropy(buf, len, 0) };
if res < 0 {
return -1;
}
Expand All @@ -98,6 +105,16 @@ pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 {
0
}

/// Create a cryptographicly secure 64bit random number with the support of
/// the underlying hardware. If the required hardware isn't available,
/// the function returns -1.
#[cfg(not(feature = "newlib"))]
#[allow(unsafe_op_in_unsafe_fn)]
#[no_mangle]
pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 {
kernel_function!(__sys_secure_rand64(value))
}

extern "C" fn __sys_rand() -> u32 {
generate_park_miller_lehmer_random_number()
}
Expand Down
12 changes: 10 additions & 2 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,17 @@ pub(crate) fn get_application_parameters() -> (i32, *const *const u8, *const *co
SYS.get_application_parameters()
}

pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! {
pub(crate) fn shutdown(arg: i32) -> ! {
// print some performance statistics
crate::arch::kernel::print_statistics();

SYS.shutdown(arg)
}

pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! {
shutdown(arg)
}

#[no_mangle]
pub extern "C" fn sys_shutdown(arg: i32) -> ! {
kernel_function!(__sys_shutdown(arg))
Expand Down Expand Up @@ -386,14 +390,18 @@ pub extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isiz
kernel_function!(__sys_read(fd, buf, len))
}

extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
let slice = unsafe { core::slice::from_raw_parts(buf, len) };
crate::fd::write(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
}

extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
write(fd, buf, len)
}

#[no_mangle]
pub extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
kernel_function!(__sys_write(fd, buf, len))
Expand Down
22 changes: 15 additions & 7 deletions src/syscalls/semaphore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ pub extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 {
kernel_function!(__sys_sem_trywait(sem))
}

/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds.
///
/// Blocks until semaphore is acquired or until wake-up time has elapsed.
///
/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout.
extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
if sem.is_null() {
return -EINVAL;
}
Expand All @@ -119,12 +114,25 @@ extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
}
}

/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds.
///
/// Blocks until semaphore is acquired or until wake-up time has elapsed.
///
/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout.
extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
sem_timedwait(sem, ms)
}

#[no_mangle]
pub extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
kernel_function!(__sys_sem_timedwait(sem, ms))
}

extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 {
sem_timedwait(sem, ms)
}

#[no_mangle]
pub extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 {
kernel_function!(__sys_sem_timedwait(sem, ms))
kernel_function!(__sys_sem_cancelablewait(sem, ms))
}
32 changes: 18 additions & 14 deletions src/syscalls/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::fd::socket::tcp;
#[cfg(feature = "udp")]
use crate::fd::socket::udp;
use crate::fd::{get_object, insert_object, replace_object, ObjectInterface, SocketOption};
use crate::syscalls::{IoCtl, __sys_write};
use crate::syscalls::IoCtl;

pub const AF_INET: i32 = 0;
pub const AF_INET6: i32 = 1;
Expand Down Expand Up @@ -565,6 +565,10 @@ extern "C" fn __sys_getaddrinfo(
-EINVAL
}

extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize {
super::write(s, mem.cast(), len)
}

extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 {
let obj = get_object(fd);
obj.map_or_else(
Expand All @@ -576,12 +580,16 @@ extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 {
)
}

extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize) -> isize {
let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) };
crate::fd::read(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize {
if flags == 0 {
let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) };
crate::fd::read(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
} else {
(-crate::errno::EINVAL).try_into().unwrap()
}
}

extern "C" fn __sys_sendto(
Expand Down Expand Up @@ -734,8 +742,8 @@ pub extern "C" fn sys_getaddrinfo(
}

#[no_mangle]
pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize {
kernel_function!(__sys_write(s, mem as *const u8, len))
pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize {
kernel_function!(__sys_send(s, mem, len, flags))
}

#[no_mangle]
Expand All @@ -745,11 +753,7 @@ pub extern "C" fn sys_shutdown_socket(s: i32, how: i32) -> i32 {

#[no_mangle]
pub extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize {
if flags == 0 {
kernel_function!(__sys_recv(fd, buf, len))
} else {
(-crate::errno::EINVAL).try_into().unwrap()
}
kernel_function!(__sys_recv(fd, buf, len, flags))
}

#[no_mangle]
Expand Down
49 changes: 37 additions & 12 deletions src/syscalls/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::mm::{task_heap_end, task_heap_start};
use crate::scheduler::task::{Priority, TaskHandle, TaskId};
use crate::scheduler::PerCoreSchedulerExt;
use crate::time::timespec;
use crate::{arch, scheduler, syscalls};
use crate::{arch, scheduler};

#[cfg(feature = "newlib")]
pub type SignalHandler = extern "C" fn(i32);
Expand Down Expand Up @@ -52,9 +52,13 @@ pub extern "C" fn sys_setprio(_id: *const Tid, _prio: i32) -> i32 {
-ENOSYS
}

extern "C" fn __sys_exit(arg: i32) -> ! {
fn exit(arg: i32) -> ! {
debug!("Exit program with error code {}!", arg);
syscalls::__sys_shutdown(arg)
super::shutdown(arg)
}

extern "C" fn __sys_exit(arg: i32) -> ! {
exit(arg)
}

#[no_mangle]
Expand All @@ -72,9 +76,13 @@ pub extern "C" fn sys_thread_exit(arg: i32) -> ! {
kernel_function!(__sys_thread_exit(arg))
}

extern "C" fn __sys_abort() -> ! {
exit(-1)
}

#[no_mangle]
pub extern "C" fn sys_abort() -> ! {
kernel_function!(__sys_exit(-1))
kernel_function!(__sys_abort())
}

#[cfg(feature = "newlib")]
Expand Down Expand Up @@ -109,7 +117,7 @@ pub extern "C" fn sys_sbrk(incr: isize) -> usize {
kernel_function!(__sys_sbrk(incr))
}

pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
pub(super) fn usleep(usecs: u64) {
if usecs >= 10_000 {
// Enough time to set a wakeup timer and block the current task.
debug!("sys_usleep blocking the task for {} microseconds", usecs);
Expand All @@ -123,19 +131,27 @@ pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
// Not enough time to set a wakeup timer, so just do busy-waiting.
let end = arch::processor::get_timestamp() + u64::from(get_frequency()) * usecs;
while get_timestamp() < end {
__sys_yield();
core_scheduler().reschedule();
}
}
}

pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
usleep(usecs)
}

#[no_mangle]
pub extern "C" fn sys_usleep(usecs: u64) {
kernel_function!(__sys_usleep(usecs))
}

pub(crate) extern "C" fn __sys_msleep(ms: u32) {
usleep(u64::from(ms) * 1000)
}

#[no_mangle]
pub extern "C" fn sys_msleep(ms: u32) {
kernel_function!(__sys_usleep(u64::from(ms) * 1000))
kernel_function!(__sys_msleep(ms))
}

extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 {
Expand All @@ -154,7 +170,7 @@ extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i3

let microseconds =
(requested_time.tv_sec as u64) * 1_000_000 + (requested_time.tv_nsec as u64) / 1_000;
__sys_usleep(microseconds);
usleep(microseconds);

0
}
Expand Down Expand Up @@ -248,7 +264,8 @@ extern "C" fn __sys_spawn(
prio: u8,
selector: isize,
) -> i32 {
let new_id = __sys_spawn2(func, arg, prio, USER_STACK_SIZE, selector);
let new_id =
scheduler::spawn(func, arg, Priority::from(prio), USER_STACK_SIZE, selector).into();

if !id.is_null() {
unsafe {
Expand Down Expand Up @@ -286,7 +303,7 @@ pub extern "C" fn sys_join(id: Tid) -> i32 {
static BLOCKED_TASKS: InterruptTicketMutex<BTreeMap<TaskId, TaskHandle>> =
InterruptTicketMutex::new(BTreeMap::new());

extern "C" fn __sys_block_current_task(timeout: &Option<u64>) {
fn block_current_task(timeout: &Option<u64>) {
let wakeup_time = timeout.map(|t| arch::processor::get_timer_ticks() + t * 1000);
let core_scheduler = core_scheduler();
let handle = core_scheduler.get_current_task_handle();
Expand All @@ -296,16 +313,24 @@ extern "C" fn __sys_block_current_task(timeout: &Option<u64>) {
core_scheduler.block_current_task(wakeup_time);
}

extern "C" fn __sys_block_current_task() {
block_current_task(&None)
}

/// Set the current task state to `blocked`
#[no_mangle]
pub extern "C" fn sys_block_current_task() {
kernel_function!(__sys_block_current_task(&None))
kernel_function!(__sys_block_current_task())
}

extern "C" fn __sys_block_current_task_with_timeout(timeout: u64) {
block_current_task(&Some(timeout))
}

/// Set the current task state to `blocked`
#[no_mangle]
pub extern "C" fn sys_block_current_task_with_timeout(timeout: u64) {
kernel_function!(__sys_block_current_task(&Some(timeout)))
kernel_function!(__sys_block_current_task_with_timeout(timeout))
}

extern "C" fn __sys_wakeup_task(id: Tid) {
Expand Down
Loading

0 comments on commit 5716d40

Please sign in to comment.