Skip to content

Commit dde806a

Browse files
committed
unregister_syscall
1 parent 53aceea commit dde806a

3 files changed

Lines changed: 50 additions & 79 deletions

File tree

src/hooks/syscalls_hc.c

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -533,82 +533,3 @@ int syscalls_hc_init(void) {
533533
hash_init(syscall_hook_table);
534534
return 0;
535535
}
536-
537-
/* Deferred unregistration so we can invoke from inside a syscall callback */
538-
struct deferred_unregister {
539-
struct kernel_syscall_hook *hook;
540-
struct list_head list;
541-
};
542-
static LIST_HEAD(deferred_unregister_list);
543-
static DEFINE_SPINLOCK(deferred_unregister_lock);
544-
545-
static void process_deferred_unregisters(struct work_struct *work)
546-
{
547-
struct deferred_unregister *deferred, *tmp;
548-
LIST_HEAD(local_list);
549-
550-
// Move all pending unregistrations to local list
551-
spin_lock(&deferred_unregister_lock);
552-
list_splice_init(&deferred_unregister_list, &local_list);
553-
spin_unlock(&deferred_unregister_lock);
554-
555-
// Process unregistrations outside of spinlock
556-
list_for_each_entry_safe(deferred, tmp, &local_list, list) {
557-
DBG_PRINTK("IGLOO: Processing deferred unregistration for hook %p\n",
558-
deferred->hook);
559-
560-
// Actually unregister the hook
561-
unregister_syscall_hook(deferred->hook);
562-
563-
// Clean up the deferred entry
564-
list_del(&deferred->list);
565-
kfree(deferred);
566-
}
567-
}
568-
569-
static DECLARE_WORK(deferred_unregister_work, process_deferred_unregisters);
570-
571-
static int do_unregister_syscall_hook(struct kernel_syscall_hook *hook_ptr)
572-
{
573-
if (!hook_ptr) {
574-
return -EINVAL;
575-
}
576-
577-
spin_lock(&syscall_hook_lock);
578-
579-
hash_del(&hook_ptr->hlist);
580-
hlist_del_rcu(&hook_ptr->name_hlist);
581-
582-
spin_unlock(&syscall_hook_lock);
583-
584-
kfree_rcu(hook_ptr, rcu);
585-
atomic_dec(&global_syscall_hook_count);
586-
587-
DBG_PRINTK("IGLOO: Unregistered syscall hook %p\n", hook_ptr);
588-
return 0;
589-
}
590-
591-
// Modified unregister function
592-
int unregister_syscall_hook(struct kernel_syscall_hook *hook_ptr)
593-
{
594-
struct deferred_unregister *deferred;
595-
596-
// Check if we're in syscall processing context
597-
if (in_interrupt() || rcu_read_lock_held()) {
598-
// Defer the unregistration
599-
deferred = kmalloc(sizeof(*deferred), GFP_ATOMIC);
600-
if (!deferred) return -ENOMEM;
601-
602-
deferred->hook = hook_ptr;
603-
spin_lock(&deferred_unregister_lock);
604-
list_add_tail(&deferred->list, &deferred_unregister_list);
605-
spin_unlock(&deferred_unregister_lock);
606-
607-
// Schedule work to process deferred unregistrations
608-
schedule_work(&deferred_unregister_work);
609-
return 0;
610-
}
611-
612-
// Safe to unregister immediately
613-
return do_unregister_syscall_hook(hook_ptr);
614-
}

src/portal/portal_op_list.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
X(register_uprobe, REGISTER_UPROBE) \
2020
X(unregister_uprobe, UNREGISTER_UPROBE) \
2121
X(register_syscall_hook, REGISTER_SYSCALL_HOOK) \
22+
X(unregister_syscall_hook, UNREGISTER_SYSCALL_HOOK) \
2223
X(ffi_exec, FFI_EXEC) \
2324
X(kallsyms_lookup, KALLSYMS_LOOKUP) \
2425
X(tramp_generate, TRAMP_GENERATE) \

src/portal/portal_syscall.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,53 @@ void handle_op_register_syscall_hook(portal_region *mem_region)
6868
// Return the hook's memory address in the size field
6969
mem_region->header.size = (unsigned long)kernel_hook;
7070
mem_region->header.op = HYPER_RESP_READ_NUM;
71+
}
72+
73+
int unregister_syscall_hook(struct kernel_syscall_hook *hook_ptr)
74+
{
75+
if (!hook_ptr) {
76+
return -EINVAL;
77+
}
78+
79+
// 1. Immediately disable the hook to stop it from firing
80+
hook_ptr->hook.enabled = false;
81+
82+
// 2. Remove from hash tables under lock
83+
spin_lock(&syscall_hook_lock);
84+
85+
hash_del_rcu(&hook_ptr->hlist);
86+
hlist_del_rcu(&hook_ptr->name_hlist);
87+
88+
spin_unlock(&syscall_hook_lock);
89+
90+
// 3. Decrement global count
91+
atomic_dec(&global_syscall_hook_count);
92+
93+
// 4. Free memory safely using RCU
94+
kfree_rcu(hook_ptr, rcu);
95+
96+
printk(KERN_EMERG "IGLOO: Unregistered syscall hook %p\n", hook_ptr);
97+
return 0;
98+
}
99+
100+
void handle_op_unregister_syscall_hook(portal_region *mem_region)
101+
{
102+
struct kernel_syscall_hook *kernel_hook;
103+
104+
igloo_pr_debug("igloo: Handling HYPER_OP_UNREGISTER_SYSCALL_HOOK\n");
105+
106+
// Safety check: Ensure we received a pointer-sized payload
107+
if (mem_region->header.size < sizeof(void *)) {
108+
mem_region->header.op = HYPER_RESP_READ_FAIL;
109+
return;
110+
}
111+
112+
// Retrieve the hook pointer from the portal data buffer
113+
kernel_hook = *(struct kernel_syscall_hook **)PORTAL_DATA(mem_region);
114+
115+
if (unregister_syscall_hook(kernel_hook) == 0) {
116+
mem_region->header.op = HYPER_RESP_READ_OK;
117+
} else {
118+
mem_region->header.op = HYPER_RESP_WRITE_FAIL;
119+
}
71120
}

0 commit comments

Comments
 (0)