diff --git a/kernel/Kconfig b/kernel/Kconfig index a50a38d6..33a3a1f2 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -16,6 +16,38 @@ config KSU_DEBUG help Enable KernelSU debug mode. +config KSU_MANUAL_HOOK + bool "Manual hooking GKI kernels without kprobes" + depends on KSU && KSU != m + depends on KPROBES + default y if KSU_GKI_KERNEL + default n + help + Keep KPROBES enabled but do not use KPROBES to implement + the hooks required by KernelSU, but instead hook them manually. + This function is automatically enabled for GKI kernels. + +config KSU_GKI_KERNEL + bool + default y if (VERSION >= 5 && PATCHLEVEL >= 10) + help + Internal flag to indicate whether the kernel is GKI. + +config KSU_HOOK_KPROBES + bool + default y if !KSU_MANUAL_HOOK + default n + help + Internal flag to indicate whether KPROBES should be used for hooking. + +config KSU_ALLOWLIST_WORKAROUND + bool "KernelSU Session Keyring Init workaround" + depends on KSU + default n + help + Enable session keyring init workaround for problematic devices. + Useful for situations where the SU allowlist is not kept after a reboot + config KPM bool "Enable SukiSU KPM" default n @@ -24,25 +56,6 @@ config KPM This option is suitable for scenarios where you need to force KPM to be enabled. but it may affect system stability. -config KSU_ALLOWLIST_WORKAROUND - bool "KernelSU Session Keyring Init workaround" - depends on KSU - default n - help - Enable session keyring init workaround for problematic devices. - Useful for situations where the SU allowlist is not kept after a reboot - -config KSU_MANUAL_HOOK - bool "Manual hooking GKI kernels without kprobes" - depends on KSU && KSU != m - depends on KPROBES - default n - help - Keep KPROBES enabled but do not use KPROBES to implement - the hooks required by KernelSU, but instead hook them manually. - This function only available on GKI kernels, non-GKI are not - affected. - menu "KernelSU - SUSFS" config KSU_SUSFS bool "KernelSU addon - SUSFS" diff --git a/kernel/Makefile b/kernel/Makefile index 73fa65dc..3dc88482 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -23,27 +23,13 @@ obj-$(CONFIG_KSU) += kernelsu.o obj-$(CONFIG_KPM) += kpm/ -# https://github.com/tiann/KernelSU/pull/2102/files#diff-3a325663233178293ee38b8161f3be511a466af7e0156b9d03d5aed0497564bfR19 -IS_GKI := $(strip $(shell \ - if [ "$(VERSION)" -ge "5" -a "$(PATCHLEVEL)" -ge "10" ]; then \ - echo TRUE; \ - else \ - echo FALSE; \ - fi \ - )) - -ifeq ($(IS_GKI),TRUE) -$(info -- SukiSU: Kernel version is GKI.) -# GKI manual hook checks -# https://github.com/Pzqqt/android_kernel_xiaomi_marble/commit/5b8596b5604bcd0e6e12697a01136a0bb9eb0257 -ifeq ($(strip $(CONFIG_KSU_MANUAL_HOOK)),y) -$(info -- SukiSU: Hooks with Manual hook!) +ifeq ($(strip $(CONFIG_KSU_HOOK_KPROBES)),y) +$(info -- SukiSU: KPROBES hooking enabled!) +else +$(info -- SukiSU: Manual hooking enabled!) ifeq ($(strip $(CONFIG_KSU)),m) $(error CONFIG_KSU_MANUAL_HOOK cannot be enabled when compiling SukiSU as LKM!) endif -else -ccflags-y += -DKSU_HOOK_WITH_KPROBES -endif endif # .git is a text file while the module is imported by 'git submodule add'. @@ -76,9 +62,27 @@ $(info -- SukiSU Manager signature size: $(KSU_EXPECTED_SIZE)) $(info -- SukiSU Manager signature hash: $(KSU_EXPECTED_HASH)) $(info -- Supported Unofficial Manager: 5ec1cff (GKI) rsuntk (Non-GKI) ShirkNeko udochina (GKI and non-GKI and KPM)) KERNEL_VERSION := $(VERSION).$(PATCHLEVEL) - -# 检查KPM是否开启 +KERNEL_MAJOR_VERSION := $(word 1, $(subst ., , $(KERNEL_VERSION))) +KERNEL_MINOR_VERSION := $(word 2, $(subst ., , $(KERNEL_VERSION))) +ifeq ($(KERNEL_MAJOR_VERSION),5) + ifeq ($(KERNEL_MINOR_VERSION),4) + KSU_KERNEL_TYPE := GKI 1.0 + else ifeq ($(findstring $(KERNEL_MINOR_VERSION),$(filter $(KERNEL_MINOR_VERSION),10 11 12 13 14 15 16 17 18 19 20)),1) + KSU_KERNEL_TYPE := GKI 2.0 + else + KSU_KERNEL_TYPE := Non-GKI + endif +else ifeq ($(KERNEL_MAJOR_VERSION),4) + KSU_KERNEL_TYPE := Non-GKI +else ifeq ($(KERNEL_MAJOR_VERSION),6) + KSU_KERNEL_TYPE := GKI 2.0 +else + KSU_KERNEL_TYPE := Non-GKI +endif $(info -- KERNEL_VERSION: $(KERNEL_VERSION)) +$(info -- KERNEL_TYPE: $(KSU_KERNEL_TYPE)) + +# Check if KPM is enabled ifeq ($(CONFIG_KPM),y) $(info -- KPM is enabled) else diff --git a/kernel/arch.h b/kernel/arch.h index 4004ee67..cb5d4d4b 100644 --- a/kernel/arch.h +++ b/kernel/arch.h @@ -70,7 +70,7 @@ #endif #else -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES #error "Unsupported arch" #endif #endif diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 8b888e43..70ff046c 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -1439,7 +1439,7 @@ void __init ksu_core_init(void) void ksu_core_exit(void) { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_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 e4afbf66..fc6bd801 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -67,7 +67,7 @@ int __init ksu_kernelsu_init(void) ksu_sucompat_init(); -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES ksu_ksud_init(); #else pr_alert("KPROBES is disabled, KernelSU may not work, please check https://kernelsu.org/guide/how-to-integrate-for-non-gki.html"); @@ -89,7 +89,7 @@ void ksu_kernelsu_exit(void) destroy_workqueue(ksu_workqueue); -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES ksu_ksud_exit(); #endif ksu_sucompat_exit(); diff --git a/kernel/ksud.c b/kernel/ksud.c index 50f40bfd..5048ee85 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -49,7 +49,7 @@ static void stop_vfs_read_hook(); static void stop_execve_hook(); static void stop_input_hook(); -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_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; @@ -162,7 +162,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 KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_execveat_hook) { return 0; } @@ -318,7 +318,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 KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_vfs_read_hook) { return 0; } @@ -431,7 +431,7 @@ static bool is_volumedown_enough(unsigned int count) int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value) { -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_input_hook) { return 0; } @@ -472,7 +472,7 @@ bool ksu_is_safe_mode() return false; } -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) { @@ -630,7 +630,7 @@ static void do_stop_input_hook(struct work_struct *work) static void stop_vfs_read_hook() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES bool ret = schedule_work(&stop_vfs_read_work); pr_info("unregister vfs_read kprobe: %d!\n", ret); #else @@ -641,7 +641,7 @@ static void stop_vfs_read_hook() static void stop_execve_hook() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES bool ret = schedule_work(&stop_execve_hook_work); pr_info("unregister execve kprobe: %d!\n", ret); #else @@ -656,7 +656,7 @@ static void stop_execve_hook() static void stop_input_hook() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES static bool input_hook_stopped = false; if (input_hook_stopped) { return; @@ -675,7 +675,7 @@ static void stop_input_hook() // ksud: module support void ksu_ksud_init() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES int ret; ret = register_kprobe(&execve_kp); @@ -695,7 +695,7 @@ void ksu_ksud_init() void ksu_ksud_exit() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES unregister_kprobe(&execve_kp); // this should be done before unregister vfs_read_kp // unregister_kprobe(&vfs_read_kp); diff --git a/kernel/sucompat.c b/kernel/sucompat.c index bdd59f86..b52cc730 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -60,7 +60,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, { const char su[] = SU_PATH; -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_faccessat_hook) { return 0; } @@ -111,7 +111,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) // const char sh[] = SH_PATH; const char su[] = SU_PATH; -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_stat_hook){ return 0; } @@ -157,7 +157,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void * struct filename *filename; const char su[] = SU_PATH; const char ksud[] = KSUD_PATH; -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_execveat_sucompat_hook) { return 0; } @@ -192,7 +192,7 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, void const char su[] = SU_PATH; char path[sizeof(su) + 1]; -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_execve_sucompat_hook) { return 0; } @@ -220,7 +220,7 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, void int ksu_handle_devpts(struct inode *inode) { -#ifndef KSU_HOOK_WITH_KPROBES +#ifndef CONFIG_KSU_HOOK_KPROBES if (!ksu_devpts_hook) { return 0; } @@ -252,7 +252,7 @@ int ksu_handle_devpts(struct inode *inode) return 0; } -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); @@ -389,7 +389,7 @@ static struct kprobe *su_kps[4]; // sucompat: permited process can execute 'su' to gain root access. void ksu_sucompat_init() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_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); @@ -406,7 +406,7 @@ void ksu_sucompat_init() void ksu_sucompat_exit() { -#ifdef KSU_HOOK_WITH_KPROBES +#ifdef CONFIG_KSU_HOOK_KPROBES for (int i = 0; i < ARRAY_SIZE(su_kps); i++) { destroy_kprobe(&su_kps[i]); }