kernel: Rearrange and eliminate potential call delays
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user