back to kprobe setuid hook
This commit is contained in:
21
kernel/.gitignore
vendored
Normal file
21
kernel/.gitignore
vendored
Normal 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
|
||||||
@@ -18,18 +18,12 @@
|
|||||||
#define __PT_SP_REG sp
|
#define __PT_SP_REG sp
|
||||||
#define __PT_IP_REG pc
|
#define __PT_IP_REG pc
|
||||||
|
|
||||||
#define PRCTL_SYMBOL "__arm64_sys_prctl"
|
|
||||||
#define REBOOT_SYMBOL "__arm64_sys_reboot"
|
#define REBOOT_SYMBOL "__arm64_sys_reboot"
|
||||||
|
#define PRCTL_SYMBOL "__arm64_sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "__arm64_sys_read"
|
#define SYS_READ_SYMBOL "__arm64_sys_read"
|
||||||
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
|
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
|
||||||
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
|
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
|
||||||
#define SYS_EXECVE_SYMBOL "__arm64_sys_execve"
|
#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__)
|
#elif defined(__x86_64__)
|
||||||
|
|
||||||
@@ -46,18 +40,12 @@
|
|||||||
#define __PT_RC_REG ax
|
#define __PT_RC_REG ax
|
||||||
#define __PT_SP_REG sp
|
#define __PT_SP_REG sp
|
||||||
#define __PT_IP_REG ip
|
#define __PT_IP_REG ip
|
||||||
#define PRCTL_SYMBOL "__x64_sys_prctl"
|
|
||||||
#define REBOOT_SYMBOL "__x64_sys_reboot"
|
#define REBOOT_SYMBOL "__x64_sys_reboot"
|
||||||
|
#define PRCTL_SYMBOL "__x64_sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "__x64_sys_read"
|
#define SYS_READ_SYMBOL "__x64_sys_read"
|
||||||
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
|
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
|
||||||
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
|
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
|
||||||
#define SYS_EXECVE_SYMBOL "__x64_sys_execve"
|
#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
|
#else
|
||||||
#error "Unsupported arch"
|
#error "Unsupported arch"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/uidgid.h>
|
#include <linux/uidgid.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <linux/lsm_hooks.h>
|
|
||||||
#include <linux/binfmts.h>
|
#include <linux/binfmts.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
|
|
||||||
@@ -70,9 +69,6 @@ static void ksu_try_escalate_for_uid(uid_t uid)
|
|||||||
}
|
}
|
||||||
#endif
|
#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()
|
static inline bool is_allow_su()
|
||||||
{
|
{
|
||||||
if (is_manager()) {
|
if (is_manager()) {
|
||||||
@@ -604,17 +600,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
|||||||
return 0;
|
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
|
// Init functons - kprobe hooks
|
||||||
|
|
||||||
// 1. Reboot hook for installing fd
|
// 1. Reboot hook for installing fd
|
||||||
@@ -644,6 +629,22 @@ static struct kprobe reboot_kp = {
|
|||||||
.pre_handler = reboot_handler_pre,
|
.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
|
// 3. prctl hook for handling ksu prctl commands
|
||||||
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
|
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 = {
|
static struct kprobe ksu_inode_permission_kp = {
|
||||||
.symbol_name = INODE_PERMISSION_SYMBOL,
|
.symbol_name = "security_inode_permission",
|
||||||
.pre_handler = ksu_inode_permission_handler_pre,
|
.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 = {
|
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,
|
.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 = {
|
static struct kprobe ksu_task_alloc_kp = {
|
||||||
.symbol_name = TASK_ALLOC_SYMBOL,
|
.symbol_name = "security_task_alloc",
|
||||||
.pre_handler = ksu_task_alloc_handler_pre,
|
.pre_handler = ksu_task_alloc_handler_pre,
|
||||||
};
|
};
|
||||||
#endif
|
#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)
|
__maybe_unused int ksu_kprobe_init(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -808,6 +747,15 @@ __maybe_unused int ksu_kprobe_init(void)
|
|||||||
pr_info("reboot kprobe registered successfully\n");
|
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
|
// Register prctl kprobe
|
||||||
rc = register_kprobe(&prctl_kp);
|
rc = register_kprobe(&prctl_kp);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -848,6 +796,7 @@ __maybe_unused int ksu_kprobe_init(void)
|
|||||||
__maybe_unused int ksu_kprobe_exit(void)
|
__maybe_unused int ksu_kprobe_exit(void)
|
||||||
{
|
{
|
||||||
unregister_kprobe(&reboot_kp);
|
unregister_kprobe(&reboot_kp);
|
||||||
|
unregister_kprobe(&security_task_fix_setuid_kp);
|
||||||
unregister_kprobe(&prctl_kp);
|
unregister_kprobe(&prctl_kp);
|
||||||
unregister_kprobe(&ksu_inode_permission_kp);
|
unregister_kprobe(&ksu_inode_permission_kp);
|
||||||
unregister_kprobe(&ksu_bprm_check_kp);
|
unregister_kprobe(&ksu_bprm_check_kp);
|
||||||
@@ -859,7 +808,6 @@ __maybe_unused int ksu_kprobe_exit(void)
|
|||||||
|
|
||||||
void __init ksu_core_init(void)
|
void __init ksu_core_init(void)
|
||||||
{
|
{
|
||||||
ksu_lsm_hook_init();
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
int rc = ksu_kprobe_init();
|
int rc = ksu_kprobe_init();
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -875,9 +823,8 @@ void ksu_core_exit(void)
|
|||||||
#if __SULOG_GATE
|
#if __SULOG_GATE
|
||||||
ksu_sulog_exit();
|
ksu_sulog_exit();
|
||||||
#endif
|
#endif
|
||||||
pr_info("ksu_core_exit\n");
|
|
||||||
ksu_lsm_hook_exit();
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
|
pr_info("ksu_core_exit\n");
|
||||||
ksu_kprobe_exit();
|
ksu_kprobe_exit();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user