kernel: Rearrange and eliminate potential call delays

This commit is contained in:
ShirkNeko
2025-10-06 00:08:57 +08:00
parent 5779892bbc
commit 8489c442c9
2 changed files with 58 additions and 43 deletions

View File

@@ -511,12 +511,16 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) 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 #ifdef CONFIG_KSU_SUSFS
// - We straight up check if process is supposed to be umounted, return 0 if so // - 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 // - This is to prevent side channel attack as much as possible
#ifdef CONFIG_KSU_MANUAL_SU #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_manual_su_cmd) {
if (!is_system_uid()) if (!is_system_uid())
return 0; 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_root = 0 == current_uid().val;
bool from_manager = is_manager(); bool from_manager = is_manager();
#ifdef CONFIG_KSU_MANUAL_SU DONT_GET_SMART();
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
if (!from_root && !from_manager 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 // only root or manager can access this interface
return 0; return 0;
} }
@@ -915,6 +881,47 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; 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 #ifdef CONFIG_KSU_SUSFS
if (current_uid_val == 0) { if (current_uid_val == 0) {
#ifdef CONFIG_KSU_SUSFS_SUS_PATH #ifdef CONFIG_KSU_SUSFS_SUS_PATH

View File

@@ -7,6 +7,14 @@
#include "ss/policydb.h" #include "ss/policydb.h"
#include "linux/key.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 * list_count_nodes - count the number of nodes in a list
* @head: the head of the list * @head: the head of the list