Kernel: Enhanced temporary record UID functionality and elevated privileges

This commit is contained in:
ShirkNeko
2025-09-29 04:28:31 +08:00
parent 65d5d6a494
commit a9a10466b3
6 changed files with 210 additions and 13 deletions

View File

@@ -343,19 +343,10 @@ static inline void nuke_ext4_sysfs() { }
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();
@@ -392,12 +383,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))) {
@@ -407,6 +409,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
@@ -1005,6 +1024,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
@@ -1030,6 +1058,8 @@ int ksu_bprm_check(struct linux_binprm *bprm)
ksu_handle_pre_ksud(filename);
ksu_try_escalate_for_uid(current_uid().val);
return 0;
}
@@ -1041,6 +1071,13 @@ static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3,
return -ENOSYS;
}
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)
{
@@ -1059,6 +1096,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