diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 9b45cd0d..bfb8f52a 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -200,19 +200,7 @@ int ksu_handle_devpts(struct inode *inode) #ifdef CONFIG_KPROBES -__maybe_unused static int faccessat_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - int *dfd = (int *)&PT_REGS_PARM1(regs); - const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs); - int *mode = (int *)&PT_REGS_PARM3(regs); - // Both sys_ and do_ is C function - int *flags = (int *)&PT_REGS_CCALL_PARM4(regs); - - return ksu_handle_faccessat(dfd, filename_user, mode, flags); -} - -static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) +static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); int *dfd = (int *)&PT_REGS_PARM1(real_regs); @@ -223,23 +211,7 @@ static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_faccessat(dfd, filename_user, mode, NULL); } -__maybe_unused static int newfstatat_handler_pre(struct kprobe *p, - struct pt_regs *regs) -{ - int *dfd = (int *)&PT_REGS_PARM1(regs); - const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - // static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask) - int *flags = (int *)&PT_REGS_PARM3(regs); -#else - // int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag) - int *flags = (int *)&PT_REGS_CCALL_PARM4(regs); -#endif - - return ksu_handle_stat(dfd, filename_user, flags); -} - -static int sys_newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs) +static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); int *dfd = (int *)&PT_REGS_PARM1(real_regs); @@ -250,17 +222,7 @@ static int sys_newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_stat(dfd, filename_user, flags); } -// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864 static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - int *fd = (int *)&PT_REGS_PARM1(regs); - struct filename **filename_ptr = - (struct filename **)&PT_REGS_PARM2(regs); - - return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL); -} - -static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); const char __user **filename_user = @@ -270,56 +232,6 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) NULL); } -#if 1 -static struct kprobe faccessat_kp = { - .symbol_name = SYS_FACCESSAT_SYMBOL, - .pre_handler = sys_faccessat_handler_pre, -}; -#else -static struct kprobe faccessat_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) - .symbol_name = "do_faccessat", -#else - .symbol_name = "sys_faccessat", -#endif - .pre_handler = faccessat_handler_pre, -}; -#endif - -#if 1 -static struct kprobe newfstatat_kp = { - .symbol_name = SYS_NEWFSTATAT_SYMBOL, - .pre_handler = sys_newfstatat_handler_pre, -}; -#else -static struct kprobe newfstatat_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) - .symbol_name = "vfs_statx", -#else - .symbol_name = "vfs_fstatat", -#endif - .pre_handler = newfstatat_handler_pre, -}; -#endif - -#if 1 -static struct kprobe execve_kp = { - .symbol_name = SYS_EXECVE_SYMBOL, - .pre_handler = sys_execve_handler_pre, -}; -#else -static struct kprobe execve_kp = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) - .symbol_name = "do_execveat_common", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) - .symbol_name = "__do_execve_file", -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) - .symbol_name = "do_execveat_common", -#endif - .pre_handler = execve_handler_pre, -}; -#endif - static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs) { struct inode *inode; @@ -332,36 +244,52 @@ static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_devpts(inode); } - -static struct kprobe pts_unix98_lookup_kp = { .symbol_name = - "pts_unix98_lookup", - .pre_handler = - pts_unix98_lookup_pre }; - #endif +static struct kprobe *init_kprobe(const char *name, + kprobe_pre_handler_t handler) +{ +struct kprobe *kp = kzalloc(sizeof(struct kprobe), GFP_KERNEL); +if (!kp) +return NULL; +kp->symbol_name = name; +kp->pre_handler = handler; +int ret = register_kprobe(kp); +pr_info("sucompat: register_%s kprobe: %d\n", name, ret); +if (ret) { +kfree(kp); +return NULL; +} +return kp; +} +static void destroy_kprobe(struct kprobe **kp_ptr) +{ +struct kprobe *kp = *kp_ptr; +if (!kp) +return; +unregister_kprobe(kp); +synchronize_rcu(); +kfree(kp); +*kp_ptr = NULL; +} +static struct kprobe *su_kps[4]; + // sucompat: permited process can execute 'su' to gain root access. void ksu_sucompat_init() { #ifdef CONFIG_KPROBES - int ret; - ret = register_kprobe(&execve_kp); - pr_info("sucompat: execve_kp: %d\n", ret); - ret = register_kprobe(&newfstatat_kp); - pr_info("sucompat: newfstatat_kp: %d\n", ret); - ret = register_kprobe(&faccessat_kp); - pr_info("sucompat: faccessat_kp: %d\n", ret); - ret = register_kprobe(&pts_unix98_lookup_kp); - pr_info("sucompat: devpts_kp: %d\n", ret); + 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); + su_kps[3] = init_kprobe("pts_unix98_lookup", pts_unix98_lookup_pre); #endif } void ksu_sucompat_exit() { #ifdef CONFIG_KPROBES - unregister_kprobe(&execve_kp); - unregister_kprobe(&newfstatat_kp); - unregister_kprobe(&faccessat_kp); - unregister_kprobe(&pts_unix98_lookup_kp); + for (int i = 0; i < ARRAY_SIZE(su_kps); i++) { + destroy_kprobe(&su_kps[i]); + } #endif } diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt index eebbac70..88d40f9d 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt @@ -179,7 +179,6 @@ fun SettingScreen(navigator: DestinationsNavigator) { title = stringResource(id = R.string.settings_disable_su), summary = stringResource(id = R.string.settings_disable_su_summary), checked = isSuDisabled, - enabled = !isSuDisabled // we can't re-enable su if it's disabled. ) { checked -> val shouldEnable = !checked if (Natives.setSuEnabled(shouldEnable)) {