From 4593ae81c78998dffbc81291eac15726a273a538 Mon Sep 17 00:00:00 2001 From: weishu Date: Sun, 16 Feb 2025 21:33:26 +0800 Subject: [PATCH] kernel: Allow to re-enable sucompat --- kernel/sucompat.c | 81 ++++++++++--------- .../me/weishu/kernelsu/ui/screen/Settings.kt | 3 +- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 966cbf8fa854..44840e3392ff 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -191,7 +191,7 @@ int ksu_handle_devpts(struct inode *inode) #ifdef CONFIG_KPROBES -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); @@ -202,17 +202,18 @@ static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs) return ksu_handle_faccessat(dfd, filename_user, mode, NULL); } -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); - const char __user **filename_user = (const char **)&PT_REGS_PARM2(real_regs); + const char __user **filename_user = + (const char **)&PT_REGS_PARM2(real_regs); int *flags = (int *)&PT_REGS_SYSCALL_PARM4(real_regs); return ksu_handle_stat(dfd, filename_user, flags); } -static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) +static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct pt_regs *real_regs = PT_REAL_REGS(regs); const char __user **filename_user = @@ -222,21 +223,6 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) NULL); } -static struct kprobe faccessat_kp = { - .symbol_name = SYS_FACCESSAT_SYMBOL, - .pre_handler = sys_faccessat_handler_pre, -}; - -static struct kprobe newfstatat_kp = { - .symbol_name = SYS_NEWFSTATAT_SYMBOL, - .pre_handler = sys_newfstatat_handler_pre, -}; - -static struct kprobe execve_kp = { - .symbol_name = SYS_EXECVE_SYMBOL, - .pre_handler = sys_execve_handler_pre, -}; - static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs) { struct inode *inode; @@ -246,35 +232,56 @@ 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/me/weishu/kernelsu/ui/screen/Settings.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt index 951f12df3c01..63c2a81ffe7b 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt @@ -181,7 +181,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)) { @@ -502,4 +501,4 @@ private fun TopBar( @Composable private fun SettingsPreview() { SettingScreen(EmptyDestinationsNavigator) -} \ No newline at end of file +}