kernel: Add CONFIG_KSU_MANUAL_SU configuration
- Use random passphrase protection for manual su functionality
This commit is contained in:
@@ -31,6 +31,13 @@ config KSU_THRONE_TRACKER_LEGACY
|
||||
This is kept for Ultra-Legacy Linux 4.4-3.X kernels which are prone to deadlocks.
|
||||
Enable this if default scanning deadlocks/crashes on you.
|
||||
|
||||
config KSU_MANUAL_SU
|
||||
bool "Use manual su"
|
||||
depends on KSU
|
||||
default y
|
||||
help
|
||||
Use manual su and authorize the corresponding command line and application via prctl
|
||||
|
||||
config KSU_ALLOWLIST_WORKAROUND
|
||||
bool "KernelSU Session Keyring Init workaround"
|
||||
depends on KSU
|
||||
|
||||
@@ -8,7 +8,9 @@ kernelsu-objs += ksud.o
|
||||
kernelsu-objs += embed_ksud.o
|
||||
kernelsu-objs += kernel_compat.o
|
||||
kernelsu-objs += throne_comm.o
|
||||
ifeq ($(CONFIG_KSU_MANUAL_SU), y)
|
||||
kernelsu-objs += manual_su.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KSU_TRACEPOINT_HOOK), y)
|
||||
kernelsu-objs += ksu_trace.o
|
||||
@@ -114,6 +116,17 @@ else
|
||||
$(info -- KPM is disabled)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KSU_MANUAL_SU), y)
|
||||
KSU_PW_POOL := abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
|
||||
KSU_PW_LEN := $(shell awk 'BEGIN{srand(); print int(rand()*9)+8}')
|
||||
KSU_SU_PASSWORD := $(shell \
|
||||
tr -dc '$(KSU_PW_POOL)' </dev/urandom | head -c $(KSU_PW_LEN))
|
||||
|
||||
ccflags-y += -DKSU_SU_PASSWORD=\"$(KSU_SU_PASSWORD)\"
|
||||
|
||||
$(info -- KSU manual-su password : $(KSU_SU_PASSWORD))
|
||||
endif
|
||||
|
||||
# SELinux drivers check
|
||||
ifeq ($(shell grep -q "current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
|
||||
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
|
||||
|
||||
@@ -527,6 +527,7 @@ void ksu_allowlist_exit(void)
|
||||
mutex_unlock(&allowlist_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
bool ksu_temp_grant_root_once(uid_t uid)
|
||||
{
|
||||
struct app_profile profile = {
|
||||
@@ -602,3 +603,4 @@ void ksu_temp_revoke_root_once(uid_t uid)
|
||||
persistent_allow_list();
|
||||
pr_info("pending_root: UID=%d removed and persist updated\n", uid);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@ bool ksu_set_app_profile(struct app_profile *, bool persist);
|
||||
bool ksu_uid_should_umount(uid_t uid);
|
||||
struct root_profile *ksu_get_root_profile(uid_t uid);
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
bool ksu_temp_grant_root_once(uid_t uid);
|
||||
void ksu_temp_revoke_root_once(uid_t uid);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,10 @@
|
||||
#include "throne_comm.h"
|
||||
#include "kernel_compat.h"
|
||||
#include "dynamic_manager.h"
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
#include "manual_su.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KPM
|
||||
#include "kpm/kpm.h"
|
||||
@@ -285,6 +288,7 @@ void escape_to_root(void)
|
||||
setup_selinux(profile->selinux_domain);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid)
|
||||
{
|
||||
struct cred *newcreds;
|
||||
@@ -364,6 +368,7 @@ void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid)
|
||||
|
||||
pr_info("cmd_su: privilege escalation completed for UID: %d, PID: %d\n", target_uid, target_pid);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
|
||||
{
|
||||
@@ -479,7 +484,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
if (!current->mm || current->in_execve) {
|
||||
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;
|
||||
@@ -518,7 +523,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
pr_err("prctl: CMD_ADD_PENDING_ROOT reply error\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (!from_root && !from_manager
|
||||
&& !(is_allow_su() && is_system_bin_su())) {
|
||||
// only root or manager can access this interface
|
||||
@@ -1637,6 +1642,7 @@ int ksu_inode_permission(struct inode *inode, int mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
static void ksu_try_escalate_for_uid(uid_t uid)
|
||||
{
|
||||
if (!is_pending_root(uid))
|
||||
@@ -1645,6 +1651,7 @@ static void ksu_try_escalate_for_uid(uid_t uid)
|
||||
pr_info("pending_root: UID=%d temporarily allowed\n", uid);
|
||||
remove_pending_root(uid);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
bool ksu_is_compat __read_mostly = false;
|
||||
@@ -1671,18 +1678,22 @@ int ksu_bprm_check(struct linux_binprm *bprm)
|
||||
|
||||
ksu_handle_pre_ksud(filename);
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
ksu_try_escalate_for_uid(current_uid().val);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
static int ksu_task_alloc(struct task_struct *task,
|
||||
unsigned long clone_flags)
|
||||
{
|
||||
ksu_try_escalate_for_uid(task_uid(task).val);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
|
||||
struct inode *new_inode, struct dentry *new_dentry)
|
||||
@@ -1702,7 +1713,9 @@ 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),
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
LSM_HOOK_INIT(task_alloc, ksu_task_alloc),
|
||||
#endif
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
LSM_HOOK_INIT(bprm_check_security, ksu_bprm_check),
|
||||
#endif
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#define CMD_IS_SU_ENABLED 14
|
||||
#define CMD_ENABLE_SU 15
|
||||
|
||||
#ifdef CONFIG_KSU_MANUAL_SU
|
||||
#define CMD_SU_ESCALATION_REQUEST 50
|
||||
#define CMD_ADD_PENDING_ROOT 51
|
||||
#endif
|
||||
|
||||
#define CMD_GET_FULL_VERSION 0xC0FFEE1A
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "manager.h"
|
||||
#include "allowlist.h"
|
||||
|
||||
static const char *ksu_su_password = "zakozako";
|
||||
static const char *ksu_su_password = KSU_SU_PASSWORD;
|
||||
extern void escape_to_root_for_cmd_su(uid_t, pid_t);
|
||||
#define MAX_PENDING 16
|
||||
#define REMOVE_DELAY_CALLS 150
|
||||
@@ -42,12 +42,16 @@ int ksu_manual_su_escalate(uid_t target_uid, pid_t target_pid,
|
||||
return -EACCES;
|
||||
}
|
||||
char buf[64];
|
||||
if (strncpy_from_user(buf, user_password, sizeof(buf) - 1) < 0)
|
||||
long copied;
|
||||
|
||||
copied = ksu_strncpy_from_user_retry(buf, user_password, sizeof(buf) - 1);
|
||||
if (copied < 0)
|
||||
return -EFAULT;
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
buf[copied] = '\0';
|
||||
|
||||
if (strcmp(buf, ksu_su_password) != 0) {
|
||||
pr_warn("manual_su: wrong password\n");
|
||||
pr_warn("manual_su: wrong password (input=%s, expect=%s)\n", buf, ksu_su_password);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user