diff --git a/kernel/kprobe_hook.c b/kernel/kprobe_hook.c index 47c08870..779d2e8f 100644 --- a/kernel/kprobe_hook.c +++ b/kernel/kprobe_hook.c @@ -21,26 +21,50 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_prctl(option, arg2, arg3, arg4, arg5); } -static struct kprobe kp = { +static struct kprobe prctl_kp = { .symbol_name = PRCTL_SYMBOL, .pre_handler = handler_pre, }; +static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) + // https://elixir.bootlin.com/linux/v5.12-rc1/source/include/linux/fs.h + struct renamedata *rd = PT_REGS_PARM1(regs); + struct dentry *old_entry = rd->old_dentry; + struct dentry *new_entry = rd->new_dentry; +#else + struct dentry *old_entry = PT_REGS_PARM2(regs); + struct dentry *new_entry = PT_REGS_PARM4(regs); +#endif + + return ksu_handle_rename(old_entry, new_entry); +} + +static struct kprobe renameat_kp = { + .symbol_name = "vfs_rename", + .pre_handler = renameat_handler_pre, +}; + __maybe_unused int ksu_kprobe_init() { int rc = 0; - rc = register_kprobe(&kp); + rc = register_kprobe(&prctl_kp); if (rc) { - pr_info("prctl kprobe failed: %d, please check your kernel config.\n", - rc); + pr_info("prctl kprobe failed: %d.\n", rc); return rc; } - return rc; + rc = register_kprobe(&renameat_kp); + pr_info("renameat kp: %d\n", rc); + + return rc; } -__maybe_unused int ksu_kprobe_exit() { - unregister_kprobe(&kp); - return 0; +__maybe_unused int ksu_kprobe_exit() +{ + unregister_kprobe(&prctl_kp); + unregister_kprobe(&renameat_kp); + return 0; } \ No newline at end of file diff --git a/kernel/ksu.h b/kernel/ksu.h index e1fb5099..dcc057c0 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -1,6 +1,7 @@ #ifndef __KSU_H_KSU #define __KSU_H_KSU +#include #include #include @@ -52,4 +53,6 @@ int ksu_kprobe_exit(void); int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); +int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry); + #endif \ No newline at end of file diff --git a/kernel/lsm_hook.c b/kernel/lsm_hook.c index d1f60698..2872d894 100644 --- a/kernel/lsm_hook.c +++ b/kernel/lsm_hook.c @@ -1,5 +1,6 @@ -#include "asm-generic/errno.h" -#include "linux/kernel.h" +#include +#include +#include #include #include #include @@ -16,8 +17,15 @@ static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3, return -ENOSYS; } +static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry, + struct inode *new_inode, struct dentry *new_dentry) +{ + return ksu_handle_rename(old_dentry, new_dentry); +} + static struct security_hook_list ksu_hooks[] = { LSM_HOOK_INIT(task_prctl, ksu_task_prctl), + LSM_HOOK_INIT(inode_rename, ksu_inode_rename), }; void ksu_lsm_hook_init(void) diff --git a/kernel/uid_observer.c b/kernel/uid_observer.c index 003a0e25..7f482a9c 100644 --- a/kernel/uid_observer.c +++ b/kernel/uid_observer.c @@ -126,7 +126,7 @@ static void update_uid() ksu_queue_work(&ksu_update_uid_work); } -static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs) +int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry) { if (!current->mm) { // skip kernel threads @@ -138,27 +138,17 @@ static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs) return 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) - // https://elixir.bootlin.com/linux/v5.12-rc1/source/include/linux/fs.h - struct renamedata *rd = PT_REGS_PARM1(regs); - struct dentry *old_entry = rd->old_dentry; - struct dentry *new_entry = rd->new_dentry; -#else - struct dentry *old_entry = PT_REGS_PARM2(regs); - struct dentry *new_entry = PT_REGS_PARM4(regs); -#endif - - if (!old_entry || !new_entry) { + if (!old_dentry || !new_dentry) { return 0; } // /data/system/packages.list.tmp -> /data/system/packages.list - if (strcmp(new_entry->d_iname, "packages.list")) { + if (strcmp(new_dentry->d_iname, "packages.list")) { return 0; } char path[128]; - char *buf = dentry_path_raw(new_entry, path, sizeof(path)); + char *buf = dentry_path_raw(new_dentry, path, sizeof(path)); if (IS_ERR(buf)) { pr_err("dentry_path_raw failed.\n"); return 0; @@ -167,30 +157,21 @@ static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs) if (strcmp(buf, "/system/packages.list")) { return 0; } - pr_info("renameat: %s -> %s\n, new path: %s", old_entry->d_iname, - new_entry->d_iname, buf); + pr_info("renameat: %s -> %s\n, new path: %s", old_dentry->d_iname, + new_dentry->d_iname, buf); update_uid(); return 0; } -static struct kprobe renameat_kp = { - .symbol_name = "vfs_rename", - .pre_handler = renameat_handler_pre, -}; - int ksu_uid_observer_init() { INIT_WORK(&ksu_update_uid_work, do_update_uid); - - int rc = register_kprobe(&renameat_kp); - pr_info("renameat kp: %d\n", rc); - return rc; + return 0; } int ksu_uid_observer_exit() { - unregister_kprobe(&renameat_kp); return 0; } \ No newline at end of file