From 7e446efac41e77a8260d4b98d5639ca7f025c657 Mon Sep 17 00:00:00 2001 From: Ylarod Date: Sun, 2 Nov 2025 10:56:29 +0800 Subject: [PATCH] back to kprobe setuid hook --- kernel/.gitignore | 21 +++++++++ kernel/arch.h | 16 +------ kernel/core_hook.c | 113 ++++++++++++--------------------------------- 3 files changed, 53 insertions(+), 97 deletions(-) create mode 100644 kernel/.gitignore diff --git a/kernel/.gitignore b/kernel/.gitignore new file mode 100644 index 00000000..fc9dcf7a --- /dev/null +++ b/kernel/.gitignore @@ -0,0 +1,21 @@ +.cache/ +.thinlto-cache/ +compile_commands.json +*.ko +*.o +*.mod +*.lds +*.mod.o +.*.o* +.*.mod* +*.ko* +*.mod.c +*.symvers* +*.order +.*.ko.cmd +.tmp_versions/ +libs/ +obj/ + +CLAUDE.md +.ddk-version \ No newline at end of file diff --git a/kernel/arch.h b/kernel/arch.h index 0e1a2e09..95fddce5 100644 --- a/kernel/arch.h +++ b/kernel/arch.h @@ -18,18 +18,12 @@ #define __PT_SP_REG sp #define __PT_IP_REG pc -#define PRCTL_SYMBOL "__arm64_sys_prctl" #define REBOOT_SYMBOL "__arm64_sys_reboot" +#define PRCTL_SYMBOL "__arm64_sys_prctl" #define SYS_READ_SYMBOL "__arm64_sys_read" #define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat" #define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat" #define SYS_EXECVE_SYMBOL "__arm64_sys_execve" -/*LSM HOOK*/ -#define SECURITY_TASK_FIX_SETUID_SYMBOL "security_task_fix_setuid" -#define PRCTL_SYMBOL "__arm64_sys_prctl" -#define INODE_PERMISSION_SYMBOL "security_inode_permission" -#define BPRM_CHECK_SECURITY_SYMBOL "security_bprm_check" -#define TASK_ALLOC_SYMBOL "security_task_alloc" #elif defined(__x86_64__) @@ -46,18 +40,12 @@ #define __PT_RC_REG ax #define __PT_SP_REG sp #define __PT_IP_REG ip -#define PRCTL_SYMBOL "__x64_sys_prctl" #define REBOOT_SYMBOL "__x64_sys_reboot" +#define PRCTL_SYMBOL "__x64_sys_prctl" #define SYS_READ_SYMBOL "__x64_sys_read" #define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat" #define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat" #define SYS_EXECVE_SYMBOL "__x64_sys_execve" -/*LSM HOOK*/ -#define SECURITY_TASK_FIX_SETUID_SYMBOL "security_task_fix_setuid" -#define PRCTL_SYMBOL "__x64_sys_prctl" -#define INODE_PERMISSION_SYMBOL "security_inode_permission" -#define BPRM_CHECK_SECURITY_SYMBOL "security_bprm_check" -#define TASK_ALLOC_SYMBOL "security_task_alloc" #else #error "Unsupported arch" diff --git a/kernel/core_hook.c b/kernel/core_hook.c index dc487a27..b27624dc 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -70,9 +69,6 @@ static void ksu_try_escalate_for_uid(uid_t uid) } #endif -static int (*original_cap_task_fix_setuid)(struct cred *new, const struct cred *old, int flags); -static struct security_hook_list *ksu_hooked_security_hook; - static inline bool is_allow_su() { if (is_manager()) { @@ -604,17 +600,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) return 0; } -static int ksu_task_fix_setuid_hook(struct cred *new, const struct cred *old, int flags) -{ - ksu_handle_setuid(new, old); - - if (original_cap_task_fix_setuid) { - return original_cap_task_fix_setuid(new, old, flags); - } - - return 0; -} - // Init functons - kprobe hooks // 1. Reboot hook for installing fd @@ -644,6 +629,22 @@ static struct kprobe reboot_kp = { .pre_handler = reboot_handler_pre, }; +// 2. security_task_fix_setuid hook for handling setuid +static int security_task_fix_setuid_handler_pre(struct kprobe *p, struct pt_regs *regs) +{ + struct pt_regs *real_regs = PT_REAL_REGS(regs); + struct cred *new = (struct cred *)PT_REGS_PARM1(real_regs); + const struct cred *old = (const struct cred *)PT_REGS_PARM2(real_regs); + + ksu_handle_setuid(new, old); + + return 0; +} + +static struct kprobe security_task_fix_setuid_kp = { + .symbol_name = "security_task_fix_setuid", + .pre_handler = security_task_fix_setuid_handler_pre, +}; // 3. prctl hook for handling ksu prctl commands static int handler_pre(struct kprobe *p, struct pt_regs *regs) @@ -678,7 +679,7 @@ static int ksu_inode_permission_handler_pre(struct kprobe *p, struct pt_regs *re } static struct kprobe ksu_inode_permission_kp = { - .symbol_name = INODE_PERMISSION_SYMBOL, + .symbol_name = "security_inode_permission", .pre_handler = ksu_inode_permission_handler_pre, }; @@ -714,7 +715,7 @@ static int ksu_bprm_check_handler_pre(struct kprobe *p, struct pt_regs *regs) } static struct kprobe ksu_bprm_check_kp = { - .symbol_name = BPRM_CHECK_SECURITY_SYMBOL, + .symbol_name = "security_bprm_check", .pre_handler = ksu_bprm_check_handler_pre, }; @@ -729,73 +730,11 @@ static int ksu_task_alloc_handler_pre(struct kprobe *p, struct pt_regs *regs) } static struct kprobe ksu_task_alloc_kp = { - .symbol_name = TASK_ALLOC_SYMBOL, + .symbol_name = "security_task_alloc", .pre_handler = ksu_task_alloc_handler_pre, }; #endif -#define GET_SYMBOL_ADDR(sym) \ - ({ \ - void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \ - if (!addr) { \ - addr = kallsyms_lookup_name(#sym); \ - } \ - addr; \ - }) - - -void ksu_lsm_hook_init(void) -{ - void *cap_setuid = GET_SYMBOL_ADDR(cap_task_fix_setuid); - if (!cap_setuid) { - pr_err("Failed to find cap_task_fix_setuid symbol\n"); - return; - } - - - struct security_hook_list *hp; - hlist_for_each_entry(hp, &security_hook_heads.task_fix_setuid, list) { - if (hp->hook.task_fix_setuid == cap_setuid) { - pr_info("Found original task_fix_setuid LSM hook, patching it\n"); - - original_cap_task_fix_setuid = cap_setuid; - ksu_hooked_security_hook = hp; - - u64 page_addr = (u64)&hp->hook.task_fix_setuid & PAGE_MASK; - set_memory_rw(page_addr, 1); - hp->hook.task_fix_setuid = ksu_task_fix_setuid_hook; - set_memory_ro(page_addr, 1); - - pr_info("LSM hook patched successfully\n"); - break; - } - } - - smp_mb(); -} - -void ksu_lsm_hook_exit(void) -{ - if (!ksu_hooked_security_hook || !original_cap_task_fix_setuid) { - pr_info("No LSM hook to restore\n"); - return; - } - - pr_info("Restoring original task_fix_setuid LSM hook\n"); - - u64 page_addr = (u64)&ksu_hooked_security_hook->hook.task_fix_setuid & PAGE_MASK; - set_memory_rw(page_addr, 1); - ksu_hooked_security_hook->hook.task_fix_setuid = original_cap_task_fix_setuid; - set_memory_ro(page_addr, 1); - - smp_mb(); - - original_cap_task_fix_setuid = NULL; - ksu_hooked_security_hook = NULL; - - pr_info("LSM hook restored successfully\n"); -} - __maybe_unused int ksu_kprobe_init(void) { int rc = 0; @@ -808,6 +747,15 @@ __maybe_unused int ksu_kprobe_init(void) pr_info("reboot kprobe registered successfully\n"); } + rc = register_kprobe(&security_task_fix_setuid_kp); + if (rc) { + pr_err("security_task_fix_setuid kprobe failed: %d\n", rc); + unregister_kprobe(&reboot_kp); + } else { + pr_info("security_task_fix_setuid kprobe registered successfully\n"); + } + + // Register prctl kprobe rc = register_kprobe(&prctl_kp); if (rc) { @@ -848,6 +796,7 @@ __maybe_unused int ksu_kprobe_init(void) __maybe_unused int ksu_kprobe_exit(void) { unregister_kprobe(&reboot_kp); + unregister_kprobe(&security_task_fix_setuid_kp); unregister_kprobe(&prctl_kp); unregister_kprobe(&ksu_inode_permission_kp); unregister_kprobe(&ksu_bprm_check_kp); @@ -859,7 +808,6 @@ __maybe_unused int ksu_kprobe_exit(void) void __init ksu_core_init(void) { - ksu_lsm_hook_init(); #ifdef CONFIG_KPROBES int rc = ksu_kprobe_init(); if (rc) { @@ -875,9 +823,8 @@ void ksu_core_exit(void) #if __SULOG_GATE ksu_sulog_exit(); #endif - pr_info("ksu_core_exit\n"); - ksu_lsm_hook_exit(); #ifdef CONFIG_KPROBES + pr_info("ksu_core_exit\n"); ksu_kprobe_exit(); #endif } \ No newline at end of file