diff --git a/kernel/Kconfig b/kernel/Kconfig index 1f3802f6..0831a362 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -9,6 +9,14 @@ config KSU To compile as a module, choose M here: the module will be called kernelsu. +config KSU_WITH_KPROBES + bool "Use kprobes for kernelsu" + depends on KSU + depends on KPROBES + default y + help + Disable if you use manual hooks. + config KSU_DEBUG bool "KernelSU debug mode" depends on KSU diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 695ea33b..62fd6b53 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -968,7 +968,7 @@ void __init ksu_core_init(void) void ksu_core_exit(void) { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES pr_info("ksu_core_kprobe_exit\n"); // we dont use this now // ksu_kprobe_exit(); diff --git a/kernel/ksu.c b/kernel/ksu.c index 3639edc2..af374583 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -11,6 +11,10 @@ #include "ksu.h" #include "throne_tracker.h" +#ifdef MODULE +#define CONFIG_KSU_WITH_KPROBES +#endif + static struct workqueue_struct *ksu_workqueue; bool ksu_queue_work(struct work_struct *work) @@ -57,7 +61,7 @@ int __init kernelsu_init(void) ksu_throne_tracker_init(); -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES ksu_sucompat_init(); ksu_ksud_init(); #else @@ -80,7 +84,7 @@ void kernelsu_exit(void) destroy_workqueue(ksu_workqueue); -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES ksu_ksud_exit(); ksu_sucompat_exit(); #endif diff --git a/kernel/ksud.c b/kernel/ksud.c index 68e47352..e969db84 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -54,7 +54,7 @@ static void stop_vfs_read_hook(); static void stop_execve_hook(); static void stop_input_hook(); -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES static struct work_struct stop_vfs_read_work; static struct work_struct stop_execve_hook_work; static struct work_struct stop_input_hook_work; @@ -157,7 +157,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, struct user_arg_ptr *argv, struct user_arg_ptr *envp, int *flags) { -#ifndef CONFIG_KPROBES +#ifndef CONFIG_KSU_WITH_KPROBES if (!ksu_execveat_hook) { return 0; } @@ -313,7 +313,7 @@ static ssize_t read_iter_proxy(struct kiocb *iocb, struct iov_iter *to) int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, size_t *count_ptr, loff_t **pos) { -#ifndef CONFIG_KPROBES +#ifndef CONFIG_KSU_WITH_KPROBES if (!ksu_vfs_read_hook) { return 0; } @@ -426,7 +426,7 @@ static bool is_volumedown_enough(unsigned int count) int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value) { -#ifndef CONFIG_KPROBES +#ifndef CONFIG_KSU_WITH_KPROBES if (!ksu_input_hook) { return 0; } @@ -468,7 +468,7 @@ bool ksu_is_safe_mode() return false; } -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES // https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864 static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) @@ -598,7 +598,7 @@ static void do_stop_input_hook(struct work_struct *work) static void stop_vfs_read_hook() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES bool ret = schedule_work(&stop_vfs_read_work); pr_info("unregister vfs_read kprobe: %d!\n", ret); #else @@ -609,7 +609,7 @@ static void stop_vfs_read_hook() static void stop_execve_hook() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES bool ret = schedule_work(&stop_execve_hook_work); pr_info("unregister execve kprobe: %d!\n", ret); #else @@ -620,15 +620,16 @@ static void stop_execve_hook() static void stop_input_hook() { +#ifdef CONFIG_KSU_WITH_KPROBES static bool input_hook_stopped = false; if (input_hook_stopped) { return; } input_hook_stopped = true; -#ifdef CONFIG_KPROBES bool ret = schedule_work(&stop_input_hook_work); pr_info("unregister input kprobe: %d!\n", ret); #else + if (!ksu_input_hook) { return; } ksu_input_hook = false; pr_info("stop input_hook\n"); #endif @@ -637,7 +638,7 @@ static void stop_input_hook() // ksud: module support void ksu_ksud_init() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES int ret; ret = register_kprobe(&execve_kp); @@ -657,10 +658,10 @@ void ksu_ksud_init() void ksu_ksud_exit() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES unregister_kprobe(&execve_kp); // this should be done before unregister vfs_read_kp // unregister_kprobe(&vfs_read_kp); unregister_kprobe(&input_event_kp); #endif -} \ No newline at end of file +} diff --git a/kernel/sucompat.c b/kernel/sucompat.c index bfb8f52a..94eef0f3 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -198,7 +198,7 @@ int ksu_handle_devpts(struct inode *inode) return 0; } -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) { @@ -277,7 +277,7 @@ static struct kprobe *su_kps[4]; // sucompat: permited process can execute 'su' to gain root access. void ksu_sucompat_init() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES su_kps[0] = init_kprobe(SYS_EXECVE_SYMBOL, execve_handler_pre); su_kps[1] = init_kprobe(SYS_FACCESSAT_SYMBOL, faccessat_handler_pre); su_kps[2] = init_kprobe(SYS_NEWFSTATAT_SYMBOL, newfstatat_handler_pre); @@ -287,7 +287,7 @@ void ksu_sucompat_init() void ksu_sucompat_exit() { -#ifdef CONFIG_KPROBES +#ifdef CONFIG_KSU_WITH_KPROBES for (int i = 0; i < ARRAY_SIZE(su_kps); i++) { destroy_kprobe(&su_kps[i]); }