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)
|
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user