diff --git a/src/ehypercall.h b/src/ehypercall.h index 8f9def7..3ab906c 100644 --- a/src/ehypercall.h +++ b/src/ehypercall.h @@ -48,13 +48,16 @@ static inline unsigned long igloo_hypercall4(unsigned long num, unsigned long ar return reg0; #elif defined(CONFIG_X86_64) - unsigned long reg0 = num; + register unsigned long reg0 asm("rax") = num; + register unsigned long reg1 asm("rdi") = arg1; + register unsigned long reg2 asm("rsi") = arg2; + register unsigned long reg3 asm("rdx") = arg3; register unsigned long reg4 asm("r10") = arg4; // r10 used for 4th arg in syscall ABI asm volatile( "outl %%eax, $0x88" : "+a"(reg0) // hypercall num + return value in rax - : "D"(arg1), "S"(arg2), "d"(arg3), "r"(reg4) + : "r"(reg1), "r"(reg2), "r"(reg3), "r"(reg4) : "memory" ); @@ -62,12 +65,16 @@ static inline unsigned long igloo_hypercall4(unsigned long num, unsigned long ar #elif defined(CONFIG_I386) // Matches the "other implementation" (standard Linux Syscall ABI) - unsigned long reg0 = num; + register unsigned long reg0 asm("eax") = num; + register unsigned long reg1 asm("ebx") = arg1; + register unsigned long reg2 asm("ecx") = arg2; + register unsigned long reg3 asm("edx") = arg3; + register unsigned long reg4 asm("esi") = arg4; asm volatile( "outl %%eax, $0x88" : "+a"(reg0) // hypercall num + return value in eax - : "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) + : "r"(reg1), "r"(reg2), "r"(reg3), "r"(reg4) : "memory" ); @@ -124,4 +131,4 @@ static inline unsigned long igloo_hypercall4(unsigned long num, unsigned long ar #error "No igloo_hypercall4 support for architecture" #endif } -#endif \ No newline at end of file +#endif diff --git a/src/hooks/block_mounts.c b/src/hooks/block_mounts.c index babcc6d..3359640 100644 --- a/src/hooks/block_mounts.c +++ b/src/hooks/block_mounts.c @@ -6,7 +6,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" bool igloo_should_block_mount(struct path *path); diff --git a/src/hooks/igloo_open.c b/src/hooks/igloo_open.c index 0cea9ce..fec3651 100644 --- a/src/hooks/igloo_open.c +++ b/src/hooks/igloo_open.c @@ -6,7 +6,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" #include #include diff --git a/src/hooks/ioctl_hc.c b/src/hooks/ioctl_hc.c index a2fc890..831d6f1 100644 --- a/src/hooks/ioctl_hc.c +++ b/src/hooks/ioctl_hc.c @@ -5,7 +5,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" #include #include diff --git a/src/hooks/signal_hc.c b/src/hooks/signal_hc.c index 4e5d07b..0fc8058 100644 --- a/src/hooks/signal_hc.c +++ b/src/hooks/signal_hc.c @@ -5,7 +5,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" #include "signal_hc.h" #include "portal/portal.h" diff --git a/src/hooks/sock_hc.c b/src/hooks/sock_hc.c index 93ee2fb..a0c0a37 100644 --- a/src/hooks/sock_hc.c +++ b/src/hooks/sock_hc.c @@ -4,7 +4,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include #include #include diff --git a/src/hooks/syscalls_hc.c b/src/hooks/syscalls_hc.c index da29f0e..52bf0b3 100644 --- a/src/hooks/syscalls_hc.c +++ b/src/hooks/syscalls_hc.c @@ -7,7 +7,7 @@ #include #include #include -#include "hypercall.h" // Content is now included directly below +#include "igloo_hypercall.h" // Content is now included directly below #include "igloo.h" #include #include diff --git a/src/hooks/uname_hc.c b/src/hooks/uname_hc.c index 55c7957..3233f19 100644 --- a/src/hooks/uname_hc.c +++ b/src/hooks/uname_hc.c @@ -5,7 +5,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" #include #include diff --git a/src/hyperfs/hyperfs.c b/src/hyperfs/hyperfs.c index 675a6f0..b28d092 100644 --- a/src/hyperfs/hyperfs.c +++ b/src/hyperfs/hyperfs.c @@ -6,7 +6,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "portal/portal.h" // #include "../internal.h" #include "ioctl_hc.h" diff --git a/src/igloo_hc.c b/src/igloo_hc.c index 237047f..c6e17e6 100644 --- a/src/igloo_hc.c +++ b/src/igloo_hc.c @@ -11,7 +11,7 @@ #include #include "syscalls_hc.h" #include "portal/portal.h" -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo_hypercall_consts.h" #include "hyperfs/hyperfs.h" diff --git a/src/igloo_hypercall.h b/src/igloo_hypercall.h new file mode 100644 index 0000000..05e985f --- /dev/null +++ b/src/igloo_hypercall.h @@ -0,0 +1,28 @@ +#ifndef IGLOO_DRIVER_HYPERCALL_H +#define IGLOO_DRIVER_HYPERCALL_H + +#include +#include "ehypercall.h" + +static inline unsigned long igloo_hypercall(unsigned long num, + unsigned long arg1) +{ + return igloo_hypercall4(num, arg1, 0, 0, 0); +} + +static inline unsigned long igloo_hypercall2(unsigned long num, + unsigned long arg1, + unsigned long arg2) +{ + return igloo_hypercall4(num, arg1, arg2, 0, 0); +} + +static inline unsigned long igloo_hypercall3(unsigned long num, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3) +{ + return igloo_hypercall4(num, arg1, arg2, arg3, 0); +} + +#endif diff --git a/src/portal/portal_internal.h b/src/portal/portal_internal.h index d75a35b..568a6d0 100644 --- a/src/portal/portal_internal.h +++ b/src/portal/portal_internal.h @@ -18,7 +18,7 @@ #include #include #include -#include "hypercall.h" +#include "igloo_hypercall.h" #include "igloo.h" #include "syscalls_hc.h" #include "igloo_debug.h" diff --git a/src/portal/portal_procfs.c b/src/portal/portal_procfs.c index f659679..f8d0070 100644 --- a/src/portal/portal_procfs.c +++ b/src/portal/portal_procfs.c @@ -301,7 +301,8 @@ igloo_convert_ops_to_proc_ops(const struct igloo_proc_ops *ops, struct proc_ops out->proc_get_unmapped_area = ops->get_unmapped_area; return out; } -#else +#endif + static inline const struct file_operations * igloo_convert_ops_to_fops(const struct igloo_proc_ops *ops, struct file_operations *out) { @@ -325,7 +326,6 @@ igloo_convert_ops_to_fops(const struct igloo_proc_ops *ops, struct file_operatio out->get_unmapped_area = ops->get_unmapped_area; return out; } -#endif // Unified proc_create wrapper static struct proc_dir_entry *igloo_proc_create_data(const char *name, umode_t mode, @@ -599,6 +599,18 @@ static struct portal_procfs_entry *find_pid_template(const char *parent, const c } } spin_unlock(&procfs_pid_template_lock); + if (entry) + return entry; + + spin_lock(&procfs_pid_template_lock); + list_for_each_entry(tmpl, &procfs_pid_template_list, list) { + if (!strcmp(tmpl->parent, "*") && + strlen(tmpl->name) == len && !memcmp(tmpl->name, name, len)) { + entry = tmpl->entry; + break; + } + } + spin_unlock(&procfs_pid_template_lock); return entry; } @@ -769,6 +781,7 @@ void handle_op_procfs_create_file(portal_region *mem_region) int id; char *entry_name; bool exists, enable_default_mmap, synthetic_pid_parent = false; + const char *pid_template_key = NULL; req->path[PROCFS_MAX_PATH - 1] = '\0'; entry_name = req->path; @@ -780,35 +793,54 @@ void handle_op_procfs_create_file(portal_region *mem_region) goto out; } - // Parent must be provided (0 means root) + // Parent must be provided (0 means root, PROCFS_PID_PARENT_ID means /proc/) if (req->parent_id) { - parent_dir_struct = find_proc_dir_struct_by_id(req->parent_id); - if (!parent_dir_struct) { - printk(KERN_EMERG "portal_procfs: Invalid parent_id=%d for file '%s'\n", req->parent_id, entry_name); - mem_region->header.op = HYPER_RESP_WRITE_FAIL; - goto out; - } - synthetic_pid_parent = parent_dir_struct->synthetic_pid; - if (synthetic_pid_parent) { + if (req->parent_id == PROCFS_PID_PARENT_ID) { parent = ensure_pid_template_parent(); if (!parent) { printk(KERN_EMERG "portal_procfs: Failed to create pid template parent for '%s'\n", entry_name); mem_region->header.op = HYPER_RESP_WRITE_FAIL; goto out; } + synthetic_pid_parent = true; + pid_template_key = "*"; } else { - parent = parent_dir_struct->entry; - if (!parent) { - printk(KERN_EMERG "portal_procfs: Invalid empty parent_id=%d for file '%s'\n", req->parent_id, entry_name); + parent_dir_struct = find_proc_dir_struct_by_id(req->parent_id); + if (!parent_dir_struct) { + printk(KERN_EMERG "portal_procfs: Invalid parent_id=%d for file '%s'\n", req->parent_id, entry_name); mem_region->header.op = HYPER_RESP_WRITE_FAIL; goto out; } + synthetic_pid_parent = parent_dir_struct->synthetic_pid; + if (synthetic_pid_parent) { + parent = ensure_pid_template_parent(); + if (!parent) { + printk(KERN_EMERG "portal_procfs: Failed to create pid template parent for '%s'\n", entry_name); + mem_region->header.op = HYPER_RESP_WRITE_FAIL; + goto out; + } + } else { + parent = parent_dir_struct->entry; + if (!parent) { + printk(KERN_EMERG "portal_procfs: Invalid empty parent_id=%d for file '%s'\n", req->parent_id, entry_name); + mem_region->header.op = HYPER_RESP_WRITE_FAIL; + goto out; + } + } + if (synthetic_pid_parent) + pid_template_key = parent_dir_struct->path; } } - // Safety: Fetch the entry to check its type - existing = find_proc_subdir_entry(parent, entry_name); - exists = (existing != NULL); + // Safety: Fetch the entry to check its type. PID-relative entries are + // resolved by proc_tgid_base_lookup, not the root procfs rb-tree. + if (req->parent_id == PROCFS_PID_PARENT_ID) { + existing = NULL; + exists = false; + } else { + existing = find_proc_subdir_entry(parent, entry_name); + exists = (existing != NULL); + } // printk(KERN_EMERG "portal_procfs: parent=%p, entry_name='%s'\n", parent, entry_name); @@ -872,8 +904,8 @@ void handle_op_procfs_create_file(portal_region *mem_region) list_add(&pe->list, &procfs_entry_list); spin_unlock(&procfs_entry_lock); - if (synthetic_pid_parent) - remember_pid_template(parent_dir_struct->path, entry_name, pe); + if (synthetic_pid_parent && pid_template_key) + remember_pid_template(pid_template_key, entry_name, pe); // printk(KERN_EMERG "portal_procfs: Created procfs entry '%s' with id %d\n", entry_name, id); diff --git a/src/portal/portal_types.h b/src/portal/portal_types.h index 59b73f3..4304412 100644 --- a/src/portal/portal_types.h +++ b/src/portal/portal_types.h @@ -126,6 +126,7 @@ struct portal_hyperfs_add_hyperfile_args { #define PROCFS_MAX_PATH 256 +#define PROCFS_PID_PARENT_ID -1 // Universal proc ops struct struct igloo_proc_ops {