From 8489c442c95bf148fa5b41cdbe3452d761718ead Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Mon, 6 Oct 2025 00:08:57 +0800 Subject: [PATCH] kernel: Rearrange and eliminate potential call delays --- kernel/core_hook.c | 93 +++++++++++++++++++++++------------------- kernel/kernel_compat.h | 8 ++++ 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 53e1854d..9c9581e8 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -511,12 +511,16 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { + bool is_manual_su_cmd = false; +#ifdef CONFIG_KSU_MANUAL_SU + is_manual_su_cmd = (arg2 == CMD_SU_ESCALATION_REQUEST || + arg2 == CMD_ADD_PENDING_ROOT); +#endif + #ifdef CONFIG_KSU_SUSFS // - We straight up check if process is supposed to be umounted, return 0 if so // - This is to prevent side channel attack as much as possible #ifdef CONFIG_KSU_MANUAL_SU - bool is_manual_su_cmd = (arg2 == CMD_SU_ESCALATION_REQUEST || - arg2 == CMD_ADD_PENDING_ROOT); if (is_manual_su_cmd) { if (!is_system_uid()) return 0; @@ -549,48 +553,10 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, bool from_root = 0 == current_uid().val; bool from_manager = is_manager(); -#ifdef CONFIG_KSU_MANUAL_SU - if (arg2 == CMD_SU_ESCALATION_REQUEST) { - uid_t target_uid = (uid_t)arg3; - struct su_request_arg __user *user_req = (struct su_request_arg __user *)arg4; - - pid_t target_pid; - const char __user *user_password; - - if (copy_from_user(&target_pid, &user_req->target_pid, sizeof(target_pid))) - return -EFAULT; - if (copy_from_user(&user_password, &user_req->user_password, sizeof(user_password))) - return -EFAULT; - - int ret = ksu_manual_su_escalate(target_uid, target_pid, user_password); - - if (ret == 0) { - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("cmd_su_escalation: prctl reply error\n"); - } - } - return 0; - } - - if (arg2 == CMD_ADD_PENDING_ROOT) { - uid_t uid = (uid_t)arg3; - - if (!is_current_verified()) { - pr_warn("CMD_ADD_PENDING_ROOT: denied, password not verified\n"); - return -EPERM; - } - - add_pending_root(uid); - current_verified = false; - pr_info("prctl: pending root added for UID %d\n", uid); - - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) - pr_err("prctl: CMD_ADD_PENDING_ROOT reply error\n"); - return 0; - } -#endif + DONT_GET_SMART(); if (!from_root && !from_manager - && !(is_allow_su() && is_system_bin_su())) { + && !(is_manual_su_cmd ? is_system_uid(): + (is_allow_su() && is_system_bin_su()))) { // only root or manager can access this interface return 0; } @@ -915,6 +881,47 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, return 0; } +#ifdef CONFIG_KSU_MANUAL_SU + if (arg2 == CMD_SU_ESCALATION_REQUEST) { + uid_t target_uid = (uid_t)arg3; + struct su_request_arg __user *user_req = (struct su_request_arg __user *)arg4; + + pid_t target_pid; + const char __user *user_password; + + if (copy_from_user(&target_pid, &user_req->target_pid, sizeof(target_pid))) + return -EFAULT; + if (copy_from_user(&user_password, &user_req->user_password, sizeof(user_password))) + return -EFAULT; + + int ret = ksu_manual_su_escalate(target_uid, target_pid, user_password); + + if (ret == 0) { + if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { + pr_err("cmd_su_escalation: prctl reply error\n"); + } + } + return 0; + } + + if (arg2 == CMD_ADD_PENDING_ROOT) { + uid_t uid = (uid_t)arg3; + + if (!is_current_verified()) { + pr_warn("CMD_ADD_PENDING_ROOT: denied, password not verified\n"); + return -EPERM; + } + + add_pending_root(uid); + current_verified = false; + pr_info("prctl: pending root added for UID %d\n", uid); + + if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) + pr_err("prctl: CMD_ADD_PENDING_ROOT reply error\n"); + return 0; + } +#endif + #ifdef CONFIG_KSU_SUSFS if (current_uid_val == 0) { #ifdef CONFIG_KSU_SUSFS_SUS_PATH diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index 426f8177..810a74ed 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -7,6 +7,14 @@ #include "ss/policydb.h" #include "linux/key.h" +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +// arch/arm64/include/asm/barrier.h, adding dsb probably unneeded +#define DONT_GET_SMART() do { barrier(); isb(); } while (0) +#else +// well, compiler atleast, and not our targets +#define DONT_GET_SMART() barrier() +#endif + /** * list_count_nodes - count the number of nodes in a list * @head: the head of the list