back to kprobe setuid hook

This commit is contained in:
Ylarod
2025-11-02 10:56:29 +08:00
committed by ShirkNeko
parent c06d694ebc
commit 7e446efac4
3 changed files with 53 additions and 97 deletions

21
kernel/.gitignore vendored Normal file
View File

@@ -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

View File

@@ -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"

View File

@@ -23,7 +23,6 @@
#include <linux/uaccess.h>
#include <linux/uidgid.h>
#include <linux/version.h>
#include <linux/lsm_hooks.h>
#include <linux/binfmts.h>
#include <linux/tty.h>
@@ -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
}