Skip to content
Open
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
14 changes: 8 additions & 6 deletions src/glibc/lind_syscall/lind_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ int lind_syscall (unsigned int callnumber, unsigned long long callname, unsigned
// Entry point for wasmtime, lind_syscall is an imported function from wasmtime
int __imported_lind_3i_trampoline_register_syscall(uint64_t targetcage,
uint64_t targetcallnum,
uint64_t handlefunc_index_in_this_grate,
uint64_t this_grate_id) __attribute__((
uint64_t handlefunc_flag,
uint64_t this_grate_id,
uint64_t fn_ptr_u64) __attribute__((
__import_module__("lind"),
__import_name__("register-syscall")
));
Expand All @@ -78,12 +79,13 @@ int __imported_lind_3i_trampoline_register_syscall(uint64_t targetcage,
// targetcallnum: the syscall number to be registered in the target cage
// this_grate_id: the grate id of the syscall jump ends
// register_flag: deregister(0) or register(non-0)
int lind_register_syscall (uint64_t targetcage,
uint64_t targetcallnum,
int lind_register_syscall (int64_t targetcage,
uint64_t targetcallnum,
uint64_t handlefunc_flag,
uint64_t this_grate_id,
uint64_t register_flag)
uint64_t fn_ptr_u64)
{
int ret = __imported_lind_3i_trampoline_register_syscall(targetcage, targetcallnum, register_flag, this_grate_id);
int ret = __imported_lind_3i_trampoline_register_syscall(targetcage, targetcallnum, handlefunc_flag, this_grate_id, fn_ptr_u64);

return ret;
}
Expand Down
3 changes: 2 additions & 1 deletion src/glibc/lind_syscall/lind_syscall.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
int lind_syscall (unsigned int callnumber, unsigned long long callname, unsigned long long arg1, unsigned long long arg2, unsigned long long arg3, unsigned long long arg4, unsigned long long arg5, unsigned long long arg6, int raw);
int lind_register_syscall(uint64_t targetcage,
uint64_t targetcallnum,
uint64_t handlefunc_flag,
uint64_t this_grate_id,
uint64_t register_flag);
uint64_t fn_ptr_u64);
int lind_cp_data(uint64_t thiscage, uint64_t targetcage, uint64_t srcaddr, uint64_t srccage, uint64_t destaddr, uint64_t destcage, uint64_t len, uint64_t copytype);
4 changes: 2 additions & 2 deletions src/glibc/lind_syscall/register_handler.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <stdint.h> // For uint64_t definition
#include <syscall-template.h> // For make_syscall definition

int register_handler(uint64_t targetcage, uint64_t targetcallnum, uint64_t this_grate_id, uint64_t register_flag) {
return REGISTER_HANDLER_SYSCALL(targetcage, targetcallnum, handlefunc_index_in_this_grate, this_grate_id);
int register_handler(uint64_t targetcage, uint64_t targetcallnum, uint64_t handlefunc_flag, uint64_t this_grate_id, uint64_t fn_ptr_u64) {
return REGISTER_HANDLER_SYSCALL(targetcage, targetcallnum, handlefunc_flag, this_grate_id, fn_ptr_u64);
}
2 changes: 1 addition & 1 deletion src/glibc/lind_syscall/register_handler.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#include <stdint.h> // For uint64_t definition

int register_handler(uint64_t targetcage, uint64_t targetcallnum, uint64_t this_grate_id, uint64_t register_flag);
int register_handler(int64_t targetcage, uint64_t targetcallnum, uint64_t handlefunc_flag, uint64_t this_grate_id, uint64_t fn_ptr_u64);
5 changes: 3 additions & 2 deletions src/glibc/sysdeps/unix/syscall-template.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ lind_syscall(syscallnum, (unsigned long long)(callname), (unsigned long long)(NO

#define MAKE_RAW_SYSCALL MAKE_RAW_SYSCALL6

#define REGISTER_HANDLER_SYSCALL(targetcage, targetcallnum, handlefunc_index_in_this_grate, this_grate_id) \
#define REGISTER_HANDLER_SYSCALL(targetcage, targetcallnum, handlefunc_index_in_this_grate, this_grate_id, fn_ptr_u64) \
lind_register_syscall((uint64_t) targetcage, \
(uint64_t) targetcallnum, \
(uint64_t) handlefunc_flag, \
(uint64_t) this_grate_id, \
(uint64_t) register_flag)
(uint64_t) fn_ptr_u64)

#define CP_DATA_SYSCALL(thiscage, targetcage, srcaddr, srccage, destaddr, destcage, len, copytype) \
lind_cp_data((uint64_t) thiscage, \
Expand Down
59 changes: 44 additions & 15 deletions src/threei/src/handler_table/dashmap_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,47 @@ use std::sync::Mutex;
/// HANDLERTABLE:
/// A nested hash map used to define fine-grained per-syscall interposition rules.
///
/// <self_cageid, <callnum, (addr, dest_grateid)>
/// <self_cageid, <callnum, (in_grate_addr, dest_grateid)>
/// Keys are the grate, the value is a HashMap with a key of the callnum
/// and the values are a (target_call_index, grate) tuple for the actual handlers...
type TargetCageMap = DashMap<u64, u64>; // Maps destfunc to dest_grateid
/// and the values are a (in_grate_addr, grate) tuple for the actual handlers...
type TargetCageMap = DashMap<u64, u64>; // Maps destfunc in grate addr to dest_grateid
type CallnumMap = DashMap<u64, TargetCageMap>; // Maps targetcallnum to TargetCageMap
type CageHandlerTable = DashMap<u64, CallnumMap>; // Maps self_cageid to CallnumMap

lazy_static::lazy_static! {
// <self_cageid, <callnum, (target_call_index, dest_grateid)>
// <self_cageid, <callnum, (in_grate_addr, dest_grateid)>
// callnum is mapped to addr, not self
pub static ref HANDLERTABLE: CageHandlerTable = DashMap::new();
}

/// Helper function for debugging.
/// Prints the current contents of `HANDLERTABLE` in a readable format
/// to help inspect cage–callnum–target mappings during development.
pub fn print_handler_table() {
println!("=== HANDLERTABLE ===");
for cage_entry in HANDLERTABLE.iter() {
let self_cageid = cage_entry.key();
let callnum_map = cage_entry.value();
println!("CageID: {}", self_cageid);

for callnum_entry in callnum_map.iter() {
let callnum = callnum_entry.key();
let target_map = callnum_entry.value();
println!(" Callnum: {}", callnum);

for target_entry in target_map.iter() {
let destfunc = target_entry.key();
let dest_grateid = target_entry.value();
println!(
" destfunc: {} -> dest_grateid: {}",
destfunc, dest_grateid
);
}
}
}
println!("====================");
}

/// Checks if a given cage has any registered syscall handlers in HANDLERTABLE.
///
/// ## Arguments:
Expand Down Expand Up @@ -91,12 +119,13 @@ pub fn _rm_cage_from_handler(cageid: u64) {
pub fn register_handler_impl(
targetcage: u64,
targetcallnum: u64,
handlefunc: u64,
op_flag: u64,
handlefunccage: u64,
in_grate_fn_ptr_u64: u64,
) -> i32 {
// If `handlefunccage == THREEI_DEREGISTER`, remove the entire callnum entry
// for the given (targetcage, targetcallnum).
// We assume one (targetcage, targetcallnum) could be mapped to multiple (handlefunc, handlefunccage)
// We assume one (targetcage, targetcallnum) could be mapped to multiple (in_grate_fn_ptr_u64, handlefunccage)
// and each time calling will check the handlefunccage to determine the destination.
if handlefunccage == threei_const::THREEI_DEREGISTER {
let mut should_remove_cage = false;
Expand All @@ -118,7 +147,7 @@ pub fn register_handler_impl(
// Check if targetcallnum exists
if let Some(mut callnum_entry) = cage_entry.get_mut(&targetcallnum) {
// (targetcage, targetcallnum) exists
if handlefunc == 0 {
if op_flag == 0 {
// If deregistering a single syscall, remove the entry if it exists
callnum_entry.retain(|_, dest_grateid| *dest_grateid != handlefunccage);
// cleanup empties
Expand All @@ -134,7 +163,7 @@ pub fn register_handler_impl(
return 0;
}

match callnum_entry.get(&handlefunc) {
match callnum_entry.get(&in_grate_fn_ptr_u64) {
Some(existing_dest_grateid) if *existing_dest_grateid == handlefunccage => {
// Already registered with same mapping, do nothing
return 0;
Expand All @@ -143,19 +172,19 @@ pub fn register_handler_impl(
return threei_const::ELINDAPIABORTED as i32; // Return error if a conflicting mapping exists
}
None => {
// If `handlefunc` not exists, insert
callnum_entry.insert(handlefunc, handlefunccage);
// If `in_grate_fn_ptr` not exists, insert
callnum_entry.insert(in_grate_fn_ptr_u64, handlefunccage);
return 0;
}
}
} else {
// callnum does not exist yet under this cage
if handlefunc == 0 {
if op_flag == 0 {
// nothing to delete
return 0;
}
let mut m = DashMap::new();
m.insert(handlefunc, handlefunccage);
m.insert(in_grate_fn_ptr_u64, handlefunccage);
cage_entry.insert(targetcallnum, m);
return 0;
}
Expand All @@ -165,7 +194,7 @@ pub fn register_handler_impl(

// cage does not exist yet
// Inserts a new mapping in HANDLERTABLE.
if handlefunc == 0 {
if op_flag == 0 {
// nothing to delete
return 0;
}
Expand All @@ -177,7 +206,7 @@ pub fn register_handler_impl(
.entry(targetcallnum)
.or_insert_with(DashMap::new);

callmap.insert(handlefunc, handlefunccage);
callmap.insert(in_grate_fn_ptr_u64, handlefunccage);

0
}
Expand Down Expand Up @@ -213,6 +242,6 @@ pub fn copy_handler_table_to_cage_impl(srccage: u64, targetcage: u64) -> u64 {
"[3i|copy_handler_table_to_cage] srccage {} has no handler table",
srccage
);
threei_const::ELINDAPIABORTED as u64 // treat missing src table as an error
threei_const::ELINDAPIABORTED // treat missing src table as an error
}
}
50 changes: 36 additions & 14 deletions src/threei/src/handler_table/hashmap_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,40 @@ use std::sync::Mutex;
/// HANDLERTABLE:
/// A nested hash map used to define fine-grained per-syscall interposition rules.
///
/// <self_cageid, <callnum, (addr, dest_grateid)>
/// <self_cageid, <callnum, (in_grate_addr, dest_grateid)>
/// Keys are the grate, the value is a HashMap with a key of the callnum
/// and the values are a (target_call_index, grate) tuple for the actual handlers...
type TargetCageMap = HashMap<u64, u64>; // Maps destfunc to dest_grateid
/// and the values are a (in_grate_addr, grate) tuple for the actual handlers...
type TargetCageMap = HashMap<u64, u64>; // Maps destfunc in grate addr to dest_grateid
type CallnumMap = HashMap<u64, TargetCageMap>; // Maps targetcallnum to TargetCageMap
type CageHandlerTable = HashMap<u64, CallnumMap>; // Maps self_cageid to CallnumMap

lazy_static::lazy_static! {
// <self_cageid, <callnum, (target_call_index, dest_grateid)>
// <self_cageid, <callnum, (in_grate_addr, dest_grateid)>
// callnum is mapped to addr, not self
pub static ref HANDLERTABLE: Mutex<CageHandlerTable> = Mutex::new(HashMap::new());
}

/// Helper function for debugging.
/// Prints the current contents of `HANDLERTABLE` in a readable format
/// to help inspect cage–callnum–target mappings during development.
pub fn print_handler_table() {
let table = HANDLERTABLE.lock().unwrap();
println!("=== HANDLERTABLE ===");
for (self_cageid, callnum_map) in table.iter() {
println!("CageID: {}", self_cageid);
for (callnum, target_map) in callnum_map.iter() {
println!(" Callnum: {}", callnum);
for (destfunc, dest_grateid) in target_map.iter() {
println!(
" destfunc: {} -> dest_grateid: {}",
destfunc, dest_grateid
);
}
}
}
println!("====================");
}

/// Checks if a given cage has any registered syscall handlers in HANDLERTABLE.
///
/// ## Arguments:
Expand Down Expand Up @@ -93,8 +114,9 @@ pub fn _rm_cage_from_handler(cageid: u64) {
pub fn register_handler_impl(
targetcage: u64,
targetcallnum: u64,
handlefunc: u64,
op_flag: u64,
handlefunccage: u64,
in_grate_fn_ptr_u64: u64,
) -> i32 {
let mut handler_table = HANDLERTABLE.lock().unwrap();

Expand All @@ -119,7 +141,7 @@ pub fn register_handler_impl(
// Check if targetcallnum exists
if let Some(callnum_entry) = cage_entry.get_mut(&targetcallnum) {
// (targetcage, targetcallnum) exists
if handlefunc == 0 {
if op_flag == 0 {
// If deregistering a single syscall, remove the entry if it exists
callnum_entry.retain(|_, dest_grateid| *dest_grateid != handlefunccage);
// cleanup empties
Expand All @@ -136,7 +158,7 @@ pub fn register_handler_impl(
return 0;
}

match callnum_entry.get(&handlefunc) {
match callnum_entry.get(&in_grate_fn_ptr_u64) {
Some(existing_dest_grateid) if *existing_dest_grateid == handlefunccage => {
// Already registered with same mapping, do nothing
return 0;
Expand All @@ -145,27 +167,27 @@ pub fn register_handler_impl(
return threei_const::ELINDAPIABORTED as i32; // Return error if a conflicting mapping exists
}
None => {
// If `handlefunc` not exists, insert
callnum_entry.insert(handlefunc, handlefunccage);
// If `in_grate_fn_ptr` not exists, insert
callnum_entry.insert(in_grate_fn_ptr_u64, handlefunccage);
return 0;
}
}
} else {
// callnum does not exist yet under this cage
if handlefunc == 0 {
if op_flag == 0 {
// nothing to delete
return 0;
}
let mut m = HashMap::new();
m.insert(handlefunc, handlefunccage);
m.insert(in_grate_fn_ptr_u64, handlefunccage);
cage_entry.insert(targetcallnum, m);
return 0;
}
}

// cage does not exist yet
// Inserts a new mapping in HANDLERTABLE.
if handlefunc == 0 {
if op_flag == 0 {
// nothing to delete
return 0;
}
Expand All @@ -175,7 +197,7 @@ pub fn register_handler_impl(
.or_insert_with(HashMap::new)
.entry(targetcallnum)
.or_insert_with(HashMap::new)
.insert(handlefunc, handlefunccage);
.insert(in_grate_fn_ptr_u64, handlefunccage);

0
}
Expand Down Expand Up @@ -204,6 +226,6 @@ pub fn copy_handler_table_to_cage_impl(srccage: u64, targetcage: u64) -> u64 {
"[3i|copy_handler_table_to_cage] srccage {} has no handler table",
srccage
);
threei_const::ELINDAPIABORTED as u64 // treat missing src table as an error
threei_const::ELINDAPIABORTED // treat missing src table as an error
}
}
Loading
Loading