From c0a86544d8f7caa84e98adde480ca445a30a52f9 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Wed, 5 Nov 2025 02:18:38 +0800 Subject: [PATCH] kernel: Remove macro definitions, pass variables using `ccflags -y`, and reapply manual su protection. kernel: stop printing useless message unless its ddk environment * In-tree build show empty KDIR -- KDIR: -- MDIR: /home/runner/work/KernelSU-Test/KernelSU-Test/kernel_414/KernelSU/kernel AR drivers/iommu/built-in.o CC drivers/input/misc/uinput.o -- KernelSU version: 12329 -- KernelSU: CONFIG_KSU_MANUAL_HOOK -- Supported KernelSU Manager(s): tiann, rsuntk, 5ec1cff CC drivers/kernelsu/ksu.o AR drivers/input/joystick/built-in.o CC drivers/hid/hid-roccat-pyra.o Co-authored-by: Faris Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> --- .github/workflows/ddk-lkm.yml | 4 ++-- kernel/Kconfig | 7 +++++++ kernel/Makefile | 10 +++++++++- kernel/allowlist.c | 4 +++- kernel/allowlist.h | 2 ++ kernel/core_hook.c | 22 ++++++++++++++++++++++ kernel/kernel_compat.h | 9 --------- kernel/ksu.c | 9 ++++++--- kernel/ksu.h | 2 ++ kernel/ksud.c | 18 +++++++++--------- kernel/sucompat.c | 18 +++++++++--------- kernel/supercalls.c | 3 +++ 12 files changed, 74 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ddk-lkm.yml b/.github/workflows/ddk-lkm.yml index 34b613cc..689fe9d1 100644 --- a/.github/workflows/ddk-lkm.yml +++ b/.github/workflows/ddk-lkm.yml @@ -18,7 +18,7 @@ jobs: name: Build kernelsu.ko for ${{ inputs.kmi }} runs-on: ubuntu-latest container: - image: ghcr.io/shirkneko/ddk:${{ inputs.kmi }}-${{ inputs.ddk_release }} + image: ghcr.io/ylarod/ddk:${{ inputs.kmi }}-${{ inputs.ddk_release }} options: --privileged steps: @@ -31,7 +31,7 @@ jobs: cd kernel echo "=== Building kernelsu.ko for KMI: ${{ inputs.kmi }} ===" - CONFIG_KSU=m make + CONFIG_KSU=m CONFIG_KSU_KPROBES_HOOK=y CONFIG_KSU_MANUAL_SU=y make echo "=== Build completed ===" # Create output directory in GitHub workspace diff --git a/kernel/Kconfig b/kernel/Kconfig index 7ef3d6e1..d197f65c 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -15,6 +15,13 @@ config KSU_DEBUG help Enable KernelSU debug mode. +config KSU_MANUAL_SU + bool "Use manual su" + depends on KSU + default y + help + Use manual su and authorize the corresponding command line and application via prctl + config KPM bool "Enable SukiSU KPM" depends on KSU && 64BIT diff --git a/kernel/Makefile b/kernel/Makefile index 2f922950..1c67ea10 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,7 +13,11 @@ kernelsu-objs += embed_ksud.o kernelsu-objs += kernel_compat.o kernelsu-objs += throne_comm.o kernelsu-objs += sulog.o + +ifeq ($(CONFIG_KSU_MANUAL_SU), y) +ccflags-y += -DCONFIG_KSU_MANUAL_SU kernelsu-objs += manual_su.o +endif ifeq ($(CONFIG_KSU_TRACEPOINT_HOOK), y) kernelsu-objs += ksu_trace.o @@ -46,8 +50,10 @@ CURL_BIN := /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin curl KDIR := $(KDIR) MDIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +ifneq ($(KDIR),) $(info -- KDIR: $(KDIR)) $(info -- MDIR: $(MDIR)) +endif KSU_GITHUB_VERSION := $(shell $(CURL_BIN) -s "https://api.github.com/repos/$(REPO_OWNER)/$(REPO_NAME)/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') KSU_GITHUB_VERSION_COMMIT := $(shell $(CURL_BIN) -sI "https://api.github.com/repos/$(REPO_OWNER)/$(REPO_NAME)/commits?sha=$(REPO_BRANCH)&per_page=1" | grep -i "link:" | sed -n 's/.*page=\([0-9]*\)>; rel="last".*/\1/p') @@ -120,10 +126,13 @@ endif ifeq ($(CONFIG_KSU_KPROBES_HOOK), y) $(info -- SukiSU: CONFIG_KSU_KPROBES_HOOK) +ccflags-y += -DCONFIG_KSU_KPROBES_HOOK else ifeq ($(CONFIG_KSU_TRACEPOINT_HOOK), y) $(info -- SukiSU: CONFIG_KSU_TRACEPOINT_HOOK) +ccflags-y += -DCONFIG_KSU_TRACEPOINT_HOOK else ifeq ($(CONFIG_KSU_MANUAL_HOOK), y) $(info -- SukiSU: CONFIG_KSU_MANUAL_HOOK) +ccflags-y += -DCONFIG_KSU_MANUAL_HOOK endif KERNEL_VERSION := $(VERSION).$(PATCHLEVEL) @@ -140,7 +149,6 @@ endif $(info -- KERNEL_VERSION: $(KERNEL_VERSION)) $(info -- KERNEL_TYPE: $(KERNEL_TYPE)) -$(info -- KERNEL_VERSION: $(KERNEL_VERSION)) ifeq ($(CONFIG_KPM), y) $(info -- KPM is enabled) else diff --git a/kernel/allowlist.c b/kernel/allowlist.c index 4d34528b..6db149eb 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -527,6 +527,7 @@ void ksu_allowlist_exit(void) mutex_unlock(&allowlist_mutex); } +#ifdef CONFIG_KSU_MANUAL_SU bool ksu_temp_grant_root_once(uid_t uid) { struct app_profile profile = { @@ -601,4 +602,5 @@ void ksu_temp_revoke_root_once(uid_t uid) ksu_set_app_profile(&profile, false); persistent_allow_list(); pr_info("pending_root: UID=%d removed and persist updated\n", uid); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/kernel/allowlist.h b/kernel/allowlist.h index 1b14b0b0..69297f84 100644 --- a/kernel/allowlist.h +++ b/kernel/allowlist.h @@ -25,6 +25,8 @@ bool ksu_set_app_profile(struct app_profile *, bool persist); bool ksu_uid_should_umount(uid_t uid); struct root_profile *ksu_get_root_profile(uid_t uid); +#ifdef CONFIG_KSU_MANUAL_SU bool ksu_temp_grant_root_once(uid_t uid); void ksu_temp_revoke_root_once(uid_t uid); #endif +#endif diff --git a/kernel/core_hook.c b/kernel/core_hook.c index c1b44338..5b7560ca 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -41,7 +41,10 @@ #include "kernel_compat.h" #include "supercalls.h" #include "sulog.h" + +#ifdef CONFIG_KSU_MANUAL_SU #include "manual_su.h" +#endif bool ksu_module_mounted = false; @@ -55,6 +58,7 @@ bool ksu_is_compat __read_mostly = false; extern int __ksu_handle_devpts(struct inode *inode); // sucompat.c +#ifdef CONFIG_KSU_MANUAL_SU static void ksu_try_escalate_for_uid(uid_t uid) { if (!is_pending_root(uid)) @@ -63,6 +67,7 @@ static void ksu_try_escalate_for_uid(uid_t uid) pr_info("pending_root: UID=%d temporarily allowed\n", uid); remove_pending_root(uid); } +#endif static bool ksu_kernel_umount_enabled = true; @@ -230,6 +235,8 @@ void escape_to_root(void) #endif } +#ifdef CONFIG_KSU_MANUAL_SU + static void disable_seccomp_for_task(struct task_struct *tsk) { if (!tsk->seccomp.filter && tsk->seccomp.mode == SECCOMP_MODE_DISABLED) @@ -252,6 +259,7 @@ static void disable_seccomp_for_task(struct task_struct *tsk) tsk->seccomp.filter = NULL; #endif } +#endif } void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid) @@ -387,7 +395,11 @@ static void sulog_prctl_cmd(uid_t uid, unsigned long cmd) const char *name = NULL; switch (cmd) { + +#ifdef CONFIG_KSU_MANUAL_SU case CMD_MANUAL_SU_REQUEST: name = "prctl_manual_su_request"; break; +#endif + default: name = "prctl_unknown"; break; } @@ -420,6 +432,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, pr_info("option: 0x%x, cmd: %ld\n", option, arg2); #endif +#ifdef CONFIG_KSU_MANUAL_SU if (arg2 == CMD_MANUAL_SU_REQUEST) { struct manual_su_request request; int su_option = (int)arg3; @@ -446,6 +459,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } return 0; } +#endif return 0; } @@ -770,7 +784,9 @@ static int ksu_bprm_check_handler_pre(struct kprobe *p, struct pt_regs *regs) ksu_handle_pre_ksud(filename); +#ifdef CONFIG_KSU_MANUAL_SU ksu_try_escalate_for_uid(current_uid().val); +#endif return 0; } @@ -780,6 +796,7 @@ static struct kprobe ksu_bprm_check_kp = { .pre_handler = ksu_bprm_check_handler_pre, }; +#ifdef CONFIG_KSU_MANUAL_SU // 6. task_alloc hook for handling manual su escalation static int ksu_task_alloc_handler_pre(struct kprobe *p, struct pt_regs *regs) { @@ -793,6 +810,7 @@ static struct kprobe ksu_task_alloc_kp = { .symbol_name = "security_task_alloc", .pre_handler = ksu_task_alloc_handler_pre, }; +#endif __maybe_unused int ksu_kprobe_init(void) { @@ -839,6 +857,7 @@ __maybe_unused int ksu_kprobe_init(void) pr_info("bprm_check_security kprobe registered successfully\n"); } +#ifdef CONFIG_KSU_MANUAL_SU // Register task_alloc kprobe rc = register_kprobe(&ksu_task_alloc_kp); if (rc) { @@ -846,6 +865,7 @@ __maybe_unused int ksu_kprobe_init(void) } else { pr_info("task_alloc kprobe registered successfully\n"); } +#endif return 0; } @@ -857,7 +877,9 @@ __maybe_unused int ksu_kprobe_exit(void) unregister_kprobe(&prctl_kp); unregister_kprobe(&ksu_inode_permission_kp); unregister_kprobe(&ksu_bprm_check_kp); +#ifdef CONFIG_KSU_MANUAL_SU unregister_kprobe(&ksu_task_alloc_kp); +#endif return 0; } diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index 39a0643f..3d0b685c 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -6,15 +6,6 @@ #include "ss/policydb.h" #include "linux/key.h" -#if defined(CONFIG_KPROBES) && !(defined(CONFIG_KSU_TRACEPOINT_HOOK) || defined(CONFIG_KSU_MANUAL_HOOK)) -#define __KPROBES_HOOK 1 -#elif (defined(CONFIG_KSU_TRACEPOINT_HOOK) || defined(CONFIG_KSU_MANUAL_HOOK)) && !defined(CONFIG_KSU_KPROBES_HOOK) -#define __KPROBES_HOOK 0 -#elif defined(CONFIG_KSU_KPROBES_HOOK) -#define __KPROBES_HOOK 1 -#endif - - #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) // arch/arm64/include/asm/barrier.h, adding dsb probably unneeded #define DONT_GET_SMART() do { barrier(); isb(); } while (0) diff --git a/kernel/ksu.c b/kernel/ksu.c index 5f11ceac..eaaae7d9 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -57,8 +57,10 @@ int __init kernelsu_init(void) ksu_allowlist_init(); ksu_throne_tracker_init(); -#ifdef __KPROBES_HOOK + ksu_sucompat_init(); + +#ifdef CONFIG_KSU_KPROBES_HOOK 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"); @@ -86,9 +88,10 @@ void kernelsu_exit(void) destroy_workqueue(ksu_workqueue); -#ifdef __KPROBES_HOOK - ksu_ksud_exit(); ksu_sucompat_exit(); + +#ifdef CONFIG_KSU_KPROBES_HOOK + ksu_ksud_exit(); #endif #ifdef CONFIG_KSU_TRACEPOINT_HOOK diff --git a/kernel/ksu.h b/kernel/ksu.h index b12f2c00..cb36e35a 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -9,7 +9,9 @@ extern bool ksu_uid_scanner_enabled; +#ifdef CONFIG_KSU_MANUAL_SU #define CMD_MANUAL_SU_REQUEST 50 +#endif #define EVENT_POST_FS_DATA 1 #define EVENT_BOOT_COMPLETED 2 diff --git a/kernel/ksud.c b/kernel/ksud.c index d488494b..fe153900 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 __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK static struct work_struct stop_vfs_read_work; static struct work_struct stop_execve_hook_work; static struct work_struct stop_input_hook_work; @@ -268,7 +268,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 __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_vfs_read_hook) { return 0; } @@ -381,7 +381,7 @@ static bool is_volumedown_enough(unsigned int count) int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value) { -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_input_hook) { return 0; } @@ -423,7 +423,7 @@ bool ksu_is_safe_mode() return false; } -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) { /* @@ -596,7 +596,7 @@ static void do_stop_input_hook(struct work_struct *work) static void stop_vfs_read_hook() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK bool ret = schedule_work(&stop_vfs_read_work); pr_info("unregister vfs_read kprobe: %d!\n", ret); #else @@ -607,7 +607,7 @@ static void stop_vfs_read_hook() static void stop_execve_hook() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK bool ret = schedule_work(&stop_execve_hook_work); pr_info("unregister execve kprobe: %d!\n", ret); #else @@ -623,7 +623,7 @@ static void stop_input_hook() return; } input_hook_stopped = true; -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK bool ret = schedule_work(&stop_input_hook_work); pr_info("unregister input kprobe: %d!\n", ret); #else @@ -635,7 +635,7 @@ static void stop_input_hook() // ksud: module support void ksu_ksud_init() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK int ret; ret = register_kprobe(&execve_kp); @@ -655,7 +655,7 @@ void ksu_ksud_init() void ksu_ksud_exit() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK 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 91c6d825..b710df6c 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -62,7 +62,7 @@ static const struct ksu_feature_handler su_compat_handler = { .set_handler = su_compat_feature_set, }; -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK static bool ksu_sucompat_hook_state __read_mostly = true; #endif @@ -94,7 +94,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, { const char su[] = SU_PATH; -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_hook_state) { return 0; } @@ -124,7 +124,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 __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_hook_state) { return 0; } @@ -182,7 +182,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, const char sh[] = KSUD_PATH; const char su[] = SU_PATH; -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_hook_state) { return 0; } @@ -228,7 +228,7 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, const char su[] = SU_PATH; char path[sizeof(su) + 1]; -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_hook_state){ return 0; } @@ -273,7 +273,7 @@ int ksu_handle_devpts(struct inode *inode) int __ksu_handle_devpts(struct inode *inode) { -#ifndef __KPROBES_HOOK +#ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_hook_state) return 0; #endif @@ -299,7 +299,7 @@ int __ksu_handle_devpts(struct inode *inode) return 0; } -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); @@ -381,7 +381,7 @@ static void destroy_kprobe(struct kprobe **kp_ptr) // sucompat: permited process can execute 'su' to gain root access. void ksu_sucompat_enable() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK 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); @@ -394,7 +394,7 @@ void ksu_sucompat_enable() void ksu_sucompat_disable() { -#ifdef __KPROBES_HOOK +#ifdef CONFIG_KSU_KPROBES_HOOK int i; for (i = 0; i < ARRAY_SIZE(su_kps); i++) { destroy_kprobe(&su_kps[i]); diff --git a/kernel/supercalls.c b/kernel/supercalls.c index 0051e85c..35c1629b 100644 --- a/kernel/supercalls.c +++ b/kernel/supercalls.c @@ -20,7 +20,10 @@ #include "kernel_compat.h" #include "throne_comm.h" #include "dynamic_manager.h" + +#ifdef CONFIG_KSU_MANUAL_SU #include "manual_su.h" +#endif // Forward declarations from core_hook.c extern void escape_to_root(void);