diff --git a/kernel/sucompat.c b/kernel/sucompat.c index a7a2f6f3..95dfcbad 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -440,6 +440,42 @@ static struct kprobe *pts_kp = NULL; #ifdef CONFIG_KRETPROBES +static struct kretprobe *init_kretprobe(const char *name, + kretprobe_handler_t handler) +{ + struct kretprobe *rp = kzalloc(sizeof(struct kretprobe), GFP_KERNEL); + if (!rp) + return NULL; + rp->kp.symbol_name = name; + rp->handler = handler; + rp->data_size = 0; + rp->maxactive = 0; + + int ret = register_kretprobe(rp); + pr_info("sucompat: register_%s kretprobe: %d\n", name, ret); + if (ret) { + kfree(rp); + return NULL; + } + + return rp; +} + +static void destroy_kretprobe(struct kretprobe **rp_ptr) +{ + struct kretprobe *rp = *rp_ptr; + if (!rp) + return; + unregister_kretprobe(rp); + synchronize_rcu(); + kfree(rp); + *rp_ptr = NULL; +} + +#endif + +#ifdef CONFIG_KRETPROBES + static int tracepoint_reg_count = 0; static DEFINE_SPINLOCK(tracepoint_reg_lock); @@ -477,21 +513,8 @@ static int syscall_unregfunc_handler(struct kretprobe_instance *ri, struct pt_re return 0; } -struct kretprobe syscall_regfunc_rp = { - .kp.symbol_name = "syscall_regfunc", - .handler = syscall_regfunc_handler, - .entry_handler = NULL, - .data_size = 0, - .maxactive = 0, -}; - -struct kretprobe syscall_unregfunc_rp = { - .kp.symbol_name = "syscall_unregfunc", - .handler = syscall_unregfunc_handler, - .entry_handler = NULL, - .data_size = 0, - .maxactive = 0, -}; +static struct kretprobe *syscall_regfunc_rp = NULL; +static struct kretprobe *syscall_unregfunc_rp = NULL; #endif void ksu_sucompat_enable() @@ -505,22 +528,13 @@ void ksu_sucompat_enable() #endif #ifdef CONFIG_KRETPROBES - ret = register_kretprobe(&syscall_regfunc_rp); - if (ret) { - pr_err("sucompat: failed to register syscall_regfunc kretprobe: %d\n", ret); - } else { - pr_info("sucompat: syscall_regfunc kretprobe registered\n"); - } - ret = register_kretprobe(&syscall_unregfunc_rp); - if (ret) { - pr_err("sucompat: failed to register syscall_unregfunc kretprobe: %d\n", ret); - } else { - pr_info("sucompat: syscall_unregfunc kretprobe registered\n"); - } + // Register kretprobe for syscall_regfunc + syscall_regfunc_rp = init_kretprobe("syscall_regfunc", syscall_regfunc_handler); + // Register kretprobe for syscall_unregfunc + syscall_unregfunc_rp = init_kretprobe("syscall_unregfunc", syscall_unregfunc_handler); #endif #ifdef KSU_HAVE_SYSCALL_TRACEPOINTS_HOOK - // Register sys_enter tracepoint for syscall interception ret = register_trace_sys_enter(sucompat_sys_enter_handler, NULL); #ifndef CONFIG_KRETPROBES unmark_all_process(); @@ -541,7 +555,6 @@ void ksu_sucompat_disable() { pr_info("sucompat: ksu_sucompat_disable called\n"); #ifdef KSU_HAVE_SYSCALL_TRACEPOINTS_HOOK - // Unregister sys_enter tracepoint unregister_trace_sys_enter(sucompat_sys_enter_handler, NULL); tracepoint_synchronize_unregister(); pr_info("sucompat: sys_enter tracepoint unregistered\n"); @@ -551,16 +564,11 @@ void ksu_sucompat_disable() #endif #ifdef CONFIG_KRETPROBES - // Unregister syscall_regfunc kretprobe - unregister_kretprobe(&syscall_regfunc_rp); - pr_info("sucompat: syscall_regfunc kretprobe unregistered\n"); - // Unregister syscall_unregfunc kretprobe - unregister_kretprobe(&syscall_unregfunc_rp); - pr_info("sucompat: syscall_unregfunc kretprobe unregistered\n"); + destroy_kretprobe(&syscall_regfunc_rp); + destroy_kretprobe(&syscall_unregfunc_rp); #endif #ifdef KSU_KPROBES_HOOK - // Unregister pts_unix98_lookup kprobe destroy_kprobe(&pts_kp); #endif }