Skip to content
Merged
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
17 changes: 12 additions & 5 deletions src/ehypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,33 @@ 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"
);

return reg0;

#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"
);

Expand Down Expand Up @@ -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
#endif
2 changes: 1 addition & 1 deletion src/hooks/block_mounts.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/binfmts.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"

bool igloo_should_block_mount(struct path *path);
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/igloo_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/file.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"
#include <linux/binfmts.h>
#include <trace/syscall.h>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/ioctl_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"
#include <linux/binfmts.h>
#include <trace/syscall.h>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/signal_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"
#include "signal_hc.h"
#include "portal/portal.h"
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/sock_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include <linux/unistd.h>
#include <linux/socket.h>
#include <linux/ipv6.h>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/syscalls_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <linux/slab.h>
#include <linux/ftrace.h>
#include <asm/ftrace.h>
#include "hypercall.h" // Content is now included directly below
#include "igloo_hypercall.h" // Content is now included directly below
#include "igloo.h"
#include <linux/binfmts.h>
#include <linux/ptrace.h>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/uname_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"
#include <linux/binfmts.h>
#include <trace/syscall.h>
Expand Down
2 changes: 1 addition & 1 deletion src/hyperfs/hyperfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <linux/parser.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "portal/portal.h"
// #include "../internal.h"
#include "ioctl_hc.h"
Expand Down
2 changes: 1 addition & 1 deletion src/igloo_hc.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <linux/unistd.h>
#include "syscalls_hc.h"
#include "portal/portal.h"
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo_hypercall_consts.h"
#include "hyperfs/hyperfs.h"

Expand Down
28 changes: 28 additions & 0 deletions src/igloo_hypercall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef IGLOO_DRIVER_HYPERCALL_H
#define IGLOO_DRIVER_HYPERCALL_H

#include <linux/types.h>
#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
2 changes: 1 addition & 1 deletion src/portal/portal_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <trace/syscall.h>
#include <asm/syscall.h>
#include <linux/printk.h>
#include "hypercall.h"
#include "igloo_hypercall.h"
#include "igloo.h"
#include "syscalls_hc.h"
#include "igloo_debug.h"
Expand Down
70 changes: 51 additions & 19 deletions src/portal/portal_procfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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/<pid>)
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);

Expand Down Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/portal/portal_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading