Kernel: Enhanced temporary record UID functionality and elevated privileges
This commit is contained in:
@@ -437,19 +437,10 @@ static inline void nuke_ext4_sysfs(void)
|
||||
|
||||
static bool is_system_bin_su()
|
||||
{
|
||||
// YES in_execve becomes 0 when it succeeds.
|
||||
if (!current->mm || current->in_execve)
|
||||
return false;
|
||||
|
||||
// quick af check
|
||||
return (current->mm->exe_file && !strcmp(current->mm->exe_file->f_path.dentry->d_name.name, "su"));
|
||||
}
|
||||
|
||||
int handle_cmd_su_escalation(uid_t uid, pid_t pid, const char __user *pwd)
|
||||
{
|
||||
return ksu_manual_su_escalate(uid, pid, pwd);
|
||||
}
|
||||
|
||||
static void init_uid_scanner(void)
|
||||
{
|
||||
ksu_uid_init();
|
||||
@@ -485,12 +476,23 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
bool from_root = 0 == current_uid().val;
|
||||
bool from_manager = is_manager();
|
||||
|
||||
if (!current->mm || current->in_execve) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg2 == CMD_SU_ESCALATION_REQUEST) {
|
||||
uid_t target_uid = (uid_t)arg3;
|
||||
pid_t target_pid = (pid_t)arg4;
|
||||
const char __user *user_password = (const char __user *)arg5;
|
||||
struct su_request_arg __user *user_req = (struct su_request_arg __user *)arg4;
|
||||
|
||||
int ret = handle_cmd_su_escalation(target_uid, target_pid, user_password);
|
||||
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))) {
|
||||
@@ -500,6 +502,23 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
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;
|
||||
}
|
||||
|
||||
if (!from_root && !from_manager
|
||||
&& !(is_allow_su() && is_system_bin_su())) {
|
||||
// only root or manager can access this interface
|
||||
@@ -1618,6 +1637,15 @@ int ksu_inode_permission(struct inode *inode, int mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ksu_try_escalate_for_uid(uid_t uid)
|
||||
{
|
||||
if (!is_pending_root(uid))
|
||||
return;
|
||||
|
||||
pr_info("pending_root: UID=%d temporarily allowed\n", uid);
|
||||
remove_pending_root(uid);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
bool ksu_is_compat __read_mostly = false;
|
||||
#endif
|
||||
@@ -1643,10 +1671,19 @@ int ksu_bprm_check(struct linux_binprm *bprm)
|
||||
|
||||
ksu_handle_pre_ksud(filename);
|
||||
|
||||
ksu_try_escalate_for_uid(current_uid().val);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int ksu_task_alloc(struct task_struct *task,
|
||||
unsigned long clone_flags)
|
||||
{
|
||||
ksu_try_escalate_for_uid(task_uid(task).val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
|
||||
struct inode *new_inode, struct dentry *new_dentry)
|
||||
{
|
||||
@@ -1665,6 +1702,7 @@ static struct security_hook_list ksu_hooks[] = {
|
||||
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
|
||||
LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid),
|
||||
LSM_HOOK_INIT(inode_permission, ksu_inode_permission),
|
||||
LSM_HOOK_INIT(task_alloc, ksu_task_alloc),
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
LSM_HOOK_INIT(bprm_check_security, ksu_bprm_check),
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user