Skip to content
40 changes: 40 additions & 0 deletions src/glibc/lind_syscall/lind_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,43 @@ int copy_handler_table_to_cage(uint64_t thiscage, uint64_t targetcage)
0 /* translate_errno=0: we want to return the raw result without errno translation */
);
}

// Special syscalls meant to be used exclusively for benchmarking purposes.

// This simulates the behaviour of a syscall that gets resolves through the
// kernel.
//
// To achieve this, it mimics the default behaviour of
// rawposix::geteuid_syscall(). The function signature therefore matches the
// function signature of geteuid().
int
libc_syscall ()
{
Comment thread
stupendoussuperpowers marked this conversation as resolved.
uint64_t __self = __lind_cageid;
return make_threei_call (LIBC_SYSCALL, NULL,
__self, __self,
0, __self, 0, __self,
0, __self, 0, __self,
0, __self, 0, __self, 0);
}

// This simulates the behaviour of a syscall that does not need the kernel for
// resolution.
//
// This is achieved by mimicing the default behaviour of
// rawposix::close_syscall(-1). i.e., trying to close an invalid file
// descriptor.
//
// To ensure that each invocation always skips the kernel, this function takes
// no input (unlike close(int fd)), and hardcodes the fd argument to -1.
int
fdtables_syscall ()
Comment thread
stupendoussuperpowers marked this conversation as resolved.
{
uint64_t __self = __lind_cageid;
return make_threei_call (FDTABLES_SYSCALL, NULL,
__self, __self,
-1, __self, // Set fd argument to -1.
0, __self, 0, __self,
0, __self, 0, __self,
0, __self, 0);
}
4 changes: 4 additions & 0 deletions src/glibc/lind_syscall/lind_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ int copy_data_between_cages(uint64_t thiscage, uint64_t targetcage,
uint64_t destaddr, uint64_t destcage,
uint64_t len, uint64_t copytype);

// Benchmarking syscalls.
int libc_syscall();
int fdtables_syscall();

#endif // _LIND_SYSCALL_H
4 changes: 4 additions & 0 deletions src/glibc/lind_syscall/lind_syscall_num.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,9 @@
#define COPY_DATA_BETWEEN_CAGES_SYSCALL 1002
#define COPY_HANDLER_TABLE_TO_CAGE_SYSCALL 1003

/* Benchmarking syscalls */
#define LIBC_SYSCALL 2001
#define FDTABLES_SYSCALL 2002

#endif /* _LIND_SYSCALL_NUM_H */

6 changes: 5 additions & 1 deletion src/lind-boot/src/perf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ pub fn enable_one_counter(name: &str) {
}

fn all_counters() -> impl Iterator<Item = &'static Counter> {
LIND_BOOT_COUNTERS.iter().copied()
LIND_BOOT_COUNTERS
.iter()
.copied()
.chain(rawposix::perf::ALL_COUNTERS.iter().copied())
}

/// Get a list of all counter names.
Expand All @@ -46,4 +49,5 @@ pub fn perf_report() {
// Note: `lind_perf::report*` are no-ops when lind-perf is built without
// its internal `enabled` feature.
lind_perf::report(LIND_BOOT_COUNTERS, format!("LIND-BOOT"));
lind_perf::report(rawposix::perf::ALL_COUNTERS, format!("RAWPOSIX"));
}
100 changes: 100 additions & 0 deletions src/rawposix/src/bench_calls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use fdtables;
use sysdefs::constants::Errno;
use typemap::datatype_conversion::sc_unusedarg;
use typemap::err_const::syscall_error;

use libc;

use crate::perf;

/// Special benchmark syscall for measuring a syscall that calls the kernel for resolution.
///
/// CALL_NUM: 2001
///
/// Simulates the behaviour of geteuid().
/// - publically exported through lind_syscall.h as `libc_syscall()`
pub extern "C" fn libc_syscall(
cageid: u64,
arg1: u64,
arg1_cageid: u64,
arg2: u64,
arg2_cageid: u64,
arg3: u64,
arg3_cageid: u64,
arg4: u64,
arg4_cageid: u64,
arg5: u64,
arg5_cageid: u64,
arg6: u64,
arg6_cageid: u64,
) -> i32 {
let _timer = lind_perf::get_timer!(perf::LIBC_CALL);

// Validate that each extra argument is unused.
if !(sc_unusedarg(arg1, arg1_cageid)
&& sc_unusedarg(arg2, arg2_cageid)
&& sc_unusedarg(arg3, arg3_cageid)
&& sc_unusedarg(arg4, arg4_cageid)
&& sc_unusedarg(arg5, arg5_cageid)
&& sc_unusedarg(arg6, arg6_cageid))
{
panic!(
"{}: unused arguments contain unexpected values -- security violation",
"libc_syscall"
);
}

(unsafe { libc::geteuid() }) as i32
}

/// Special benchmark syscall for measuring a syscall that does not get resolved through the
/// kernel.
///
/// CALL_NUM: 2002
///
/// Simulates the behaviour of close(-1) i.e closing an invalid file descriptor.
/// - vfd_arg is hardcoded to -1 through glibc.
/// - publically exported through lind_syscall.h as `fdtables_syscall()`
pub extern "C" fn fdtables_syscall(
cageid: u64,
vfd_arg: u64,
vfd_cageid: u64,
arg2: u64,
arg2_cageid: u64,
arg3: u64,
arg3_cageid: u64,
arg4: u64,
arg4_cageid: u64,
arg5: u64,
arg5_cageid: u64,
arg6: u64,
arg6_cageid: u64,
) -> i32 {
let _timer = lind_perf::get_timer!(perf::FDTABLES_CALL);

if !(sc_unusedarg(arg2, arg2_cageid)
&& sc_unusedarg(arg3, arg3_cageid)
&& sc_unusedarg(arg4, arg4_cageid)
&& sc_unusedarg(arg5, arg5_cageid)
&& sc_unusedarg(arg6, arg6_cageid))
{
panic!(
"{}: unused arguments contain unexpected values -- security violation",
"fdtables_syscall"
);
}

// Call close(-1)
match fdtables::close_virtualfd(cageid, vfd_arg) {
Ok(()) => 0,
Err(e) => {
if e == Errno::EBADFD as u64 {
syscall_error(Errno::EBADF, "close", "Bad File Descriptor")
} else if e == Errno::EINTR as u64 {
syscall_error(Errno::EINTR, "close", "Interrupted system call")
} else {
syscall_error(Errno::EIO, "close", "I/O error")
}
}
}
}
2 changes: 2 additions & 0 deletions src/rawposix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// This library provides POSIX-compliant system call implementations that operate
// within the Lind-WASM sandbox environment using the 3i (Three Interposition) system.

pub mod bench_calls;
pub mod fs_calls;
pub mod init;
pub mod net_calls;
pub mod perf;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also redundant

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a pub mod because lind-boot will need to access rawposix counters through rawposix::perf::ALL_COUNTERS.

Same with the threei PR, although I did not need a pub use on there which I've removed now.

pub mod sys_calls;
pub mod syscall_table;

Expand Down
6 changes: 6 additions & 0 deletions src/rawposix/src/perf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use lind_perf::Counter;

pub static LIBC_CALL: Counter = Counter::new("rawposix::libc_call");
pub static FDTABLES_CALL: Counter = Counter::new("rawposix::fdtables_call");

pub static ALL_COUNTERS: &[&Counter] = &[&LIBC_CALL, &FDTABLES_CALL];
3 changes: 3 additions & 0 deletions src/rawposix/src/syscall_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! https://github.com/torvalds/linux/blob/v6.16-rc1/arch/x86/entry/syscalls/syscall_64.tbl
//! https://filippo.io/linux-syscall-table/
//! Keep these in sync with glibc's lind_syscall_num.h
use super::bench_calls::{fdtables_syscall, libc_syscall};
use super::fs_calls::{
access_syscall, brk_syscall, chdir_syscall, chmod_syscall, clock_gettime_syscall,
close_syscall, dup2_syscall, dup3_syscall, dup_syscall, fchdir_syscall, fchmod_syscall,
Expand Down Expand Up @@ -122,4 +123,6 @@ pub const SYSCALL_TABLE: &[(u64, RawCallFunc)] = &[
(292, dup3_syscall),
(293, pipe2_syscall),
(318, getrandom_syscall),
(2001, libc_syscall),
(2002, fdtables_syscall),
];