From 3701d47fbb9f411527a53109ebdd361f3b674f5f Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:14:35 +0800 Subject: [PATCH] kernel: Simplified manual SU command processing for code --- kernel/core_hook.c | 78 +++++++++++----------------------------- kernel/ksu.h | 4 +-- kernel/manual_su.c | 90 +++++++++++++++++++++++++++++++++++++--------- kernel/manual_su.h | 30 +++++++++++----- 4 files changed, 117 insertions(+), 85 deletions(-) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index f3d3e0b9..27942408 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -559,9 +559,7 @@ static void sulog_prctl_cmd(uid_t uid, unsigned long cmd) case CMD_GET_APP_PROFILE: name = "prctl_get_app_profile"; break; #ifdef CONFIG_KSU_MANUAL_SU - case CMD_SU_ESCALATION_REQUEST: name = "prctl_su_escalation_request"; break; - case CMD_ADD_PENDING_ROOT: name = "prctl_add_pending_root"; break; - case CMD_GENERATE_AUTH_TOKEN: name = "prctl_generate_auth_token"; break; + case CMD_MANUAL_SU_REQUEST: name = "prctl_manual_su_request"; break; #endif #ifdef CONFIG_KSU_SUSFS @@ -605,7 +603,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, 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 || arg2 == CMD_GENERATE_AUTH_TOKEN ); + is_manual_su_cmd = (arg2 == CMD_MANUAL_SU_REQUEST); #endif #ifdef CONFIG_KSU_SUSFS @@ -958,64 +956,30 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } #ifdef CONFIG_KSU_MANUAL_SU - if (arg2 == CMD_SU_ESCALATION_REQUEST) { - uid_t target_uid = (uid_t)arg3; - pid_t target_pid = (pid_t)arg4; - - int ret = ksu_manual_su_escalate(target_uid, target_pid); - - if (ret == 0 && copy_to_user(result, &reply_ok, sizeof(reply_ok))) - return -EFAULT; - return 0; - } - - if (arg2 == CMD_GENERATE_AUTH_TOKEN) { - char __user *token_buffer = (char __user *)arg3; - size_t buffer_size = (size_t)arg4; - - if (current_uid().val > 2000) { - pr_warn("CMD_GENERATE_AUTH_TOKEN: denied for app UID %d\n", current_uid().val); + if (arg2 == CMD_MANUAL_SU_REQUEST) { + struct manual_su_request request; + int su_option = (int)arg3; + + if (copy_from_user(&request, (void __user *)arg4, sizeof(request))) { + pr_err("manual_su: failed to copy request from user\n"); return 0; } - - if (buffer_size < KSU_TOKEN_LENGTH + 1) { - pr_err("CMD_GENERATE_AUTH_TOKEN: buffer too small\n"); - return -EINVAL; - } - - char *new_token = ksu_generate_auth_token(); - if (!new_token) { - pr_err("CMD_GENERATE_AUTH_TOKEN: failed to generate token\n"); - return -ENOMEM; - } - - if (copy_to_user(token_buffer, new_token, KSU_TOKEN_LENGTH + 1)) { - pr_err("CMD_GENERATE_AUTH_TOKEN: failed to copy token to user\n"); - return -EFAULT; - } - - if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { - pr_err("CMD_GENERATE_AUTH_TOKEN: prctl reply error\n"); - } - - pr_info("prctl: auth token generated successfully\n"); - return 0; - } - if (arg2 == CMD_ADD_PENDING_ROOT) { - uid_t uid = (uid_t)arg3; + int ret = ksu_handle_manual_su_request(su_option, &request); - if (!is_current_verified()) { - pr_warn("CMD_ADD_PENDING_ROOT: denied, password not verified\n"); - return -EPERM; + // Copy back result for token generation + if (ret == 0 && su_option == MANUAL_SU_OP_GENERATE_TOKEN) { + if (copy_to_user((void __user *)arg4, &request, sizeof(request))) { + pr_err("manual_su: failed to copy request back to user\n"); + return 0; + } + } + + if (ret == 0) { + if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { + pr_err("manual_su: prctl reply error\n"); + } } - - 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 diff --git a/kernel/ksu.h b/kernel/ksu.h index e5115a14..72d60b29 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -25,9 +25,7 @@ #define CMD_ENABLE_SU 15 #ifdef CONFIG_KSU_MANUAL_SU -#define CMD_SU_ESCALATION_REQUEST 50 -#define CMD_ADD_PENDING_ROOT 51 -#define CMD_GENERATE_AUTH_TOKEN 52 +#define CMD_MANUAL_SU_REQUEST 50 #endif #define CMD_GET_FULL_VERSION 0xC0FFEE1A diff --git a/kernel/manual_su.c b/kernel/manual_su.c index ec8f194a..12b071dd 100644 --- a/kernel/manual_su.c +++ b/kernel/manual_su.c @@ -15,15 +15,10 @@ #include "allowlist.h" extern void escape_to_root_for_cmd_su(uid_t, pid_t); -#define MAX_PENDING 16 -#define REMOVE_DELAY_CALLS 150 -#define MAX_TOKENS 10 - -struct pending_uid { - uid_t uid; - int use_count; - int remove_calls; -}; +static bool current_verified = false; +static void ksu_cleanup_expired_tokens(void); +static bool is_current_verified(void); +static void add_pending_root(uid_t uid); static struct pending_uid pending_uids[MAX_PENDING] = {0}; static int pending_cnt = 0; @@ -31,8 +26,6 @@ static struct ksu_token_entry auth_tokens[MAX_TOKENS] = {0}; static int token_count = 0; static DEFINE_SPINLOCK(token_lock); -bool current_verified = false; - static char* get_token_from_envp(void) { struct mm_struct *mm; @@ -97,7 +90,7 @@ static char* get_token_from_envp(void) return token; } -char* ksu_generate_auth_token(void) +static char* ksu_generate_auth_token(void) { static char token_buffer[KSU_TOKEN_LENGTH + 1]; unsigned long flags; @@ -139,7 +132,7 @@ char* ksu_generate_auth_token(void) return token_buffer; } -bool ksu_verify_auth_token(const char *token) +static bool ksu_verify_auth_token(const char *token) { unsigned long flags; bool valid = false; @@ -172,7 +165,7 @@ bool ksu_verify_auth_token(const char *token) return valid; } -void ksu_cleanup_expired_tokens(void) +static void ksu_cleanup_expired_tokens(void) { unsigned long flags; int i, j; @@ -194,8 +187,29 @@ void ksu_cleanup_expired_tokens(void) spin_unlock_irqrestore(&token_lock, flags); } -int ksu_manual_su_escalate(uid_t target_uid, pid_t target_pid) +static int handle_token_generation(struct manual_su_request *request) { + if (current_uid().val > 2000) { + pr_warn("manual_su: token generation denied for app UID %d\n", current_uid().val); + return -EPERM; + } + + char *new_token = ksu_generate_auth_token(); + if (!new_token) { + pr_err("manual_su: failed to generate token\n"); + return -ENOMEM; + } + + strncpy(request->token_buffer, new_token, KSU_TOKEN_LENGTH + 1); + pr_info("manual_su: auth token generated successfully\n"); + return 0; +} + +static int handle_escalation_request(struct manual_su_request *request) +{ + uid_t target_uid = request->target_uid; + pid_t target_pid = request->target_pid; + if (current_uid().val == 0 || is_manager() || ksu_is_allow_uid(current_uid().val)) goto allowed; @@ -219,7 +233,49 @@ allowed: return 0; } -bool is_current_verified(void) +static int handle_add_pending_request(struct manual_su_request *request) +{ + uid_t target_uid = request->target_uid; + + if (!is_current_verified()) { + pr_warn("manual_su: add_pending denied, not verified\n"); + return -EPERM; + } + + add_pending_root(target_uid); + current_verified = false; + pr_info("manual_su: pending root added for UID %d\n", target_uid); + return 0; +} + +int ksu_handle_manual_su_request(int option, struct manual_su_request *request) +{ + if (!request) { + pr_err("manual_su: invalid request pointer\n"); + return -EINVAL; + } + + switch (option) { + case MANUAL_SU_OP_GENERATE_TOKEN: + pr_info("manual_su: handling token generation request\n"); + return handle_token_generation(request); + + case MANUAL_SU_OP_ESCALATE: + pr_info("manual_su: handling escalation request for UID %d, PID %d\n", + request->target_uid, request->target_pid); + return handle_escalation_request(request); + + case MANUAL_SU_OP_ADD_PENDING: + pr_info("manual_su: handling add pending request for UID %d\n", request->target_uid); + return handle_add_pending_request(request); + + default: + pr_err("manual_su: unknown option %d\n", option); + return -EINVAL; + } +} + +static bool is_current_verified(void) { return current_verified; } @@ -255,7 +311,7 @@ void remove_pending_root(uid_t uid) } } -void add_pending_root(uid_t uid) +static void add_pending_root(uid_t uid) { if (pending_cnt >= MAX_PENDING) { pr_warn("pending_root: cache full\n"); diff --git a/kernel/manual_su.h b/kernel/manual_su.h index ac4e86ce..04290ba8 100644 --- a/kernel/manual_su.h +++ b/kernel/manual_su.h @@ -9,10 +9,30 @@ #define mmap_lock mmap_sem #endif +#define MAX_PENDING 16 +#define REMOVE_DELAY_CALLS 150 +#define MAX_TOKENS 10 + #define KSU_SU_VERIFIED_BIT (1UL << 0) #define KSU_TOKEN_LENGTH 32 #define KSU_TOKEN_ENV_NAME "KSU_AUTH_TOKEN" -#define KSU_TOKEN_EXPIRE_TIME 60 +#define KSU_TOKEN_EXPIRE_TIME 150 + +#define MANUAL_SU_OP_GENERATE_TOKEN 0 +#define MANUAL_SU_OP_ESCALATE 1 +#define MANUAL_SU_OP_ADD_PENDING 2 + +struct pending_uid { + uid_t uid; + int use_count; + int remove_calls; +}; + +struct manual_su_request { + uid_t target_uid; + pid_t target_pid; + char token_buffer[KSU_TOKEN_LENGTH + 1]; +}; struct ksu_token_entry { char token[KSU_TOKEN_LENGTH + 1]; @@ -20,13 +40,7 @@ struct ksu_token_entry { bool used; }; -int ksu_manual_su_escalate(uid_t target_uid, pid_t target_pid); +int ksu_handle_manual_su_request(int option, struct manual_su_request *request); bool is_pending_root(uid_t uid); void remove_pending_root(uid_t uid); -void add_pending_root(uid_t uid); -bool is_current_verified(void); -char* ksu_generate_auth_token(void); -bool ksu_verify_auth_token(const char *token); -void ksu_cleanup_expired_tokens(void); -extern bool current_verified; #endif