kernel: Rewrite the kernel source code (#554)
* clean unused header * on_module_mounted in ksud.c * refact: use app_profile * unified hook manager * add zygote to hook target * move reboot hook to supercall.c * refactor: kernel_umount setuid_hook * update mark rules, add init mark tracker * remove reboot from check_syscall_fastpath * update setuid_hook, remove uneeded sucompat enable * log freely * kernel: Migrate kprobe hook configuration items * kernel: fix build * cli: add ksud debug mark * Fix rustfmt warning --------- Co-authored-by: Ylarod <me@ylarod.cn> Co-authored-by: Wang Han <416810799@qq.com> Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "arch.h"
|
||||
#include "allowlist.h"
|
||||
#include "feature.h"
|
||||
#include "klog.h" // IWYU pragma: keep
|
||||
@@ -17,9 +18,9 @@
|
||||
#include "manager.h"
|
||||
#include "sulog.h"
|
||||
#include "selinux/selinux.h"
|
||||
#include "core_hook.h"
|
||||
#include "objsec.h"
|
||||
#include "file_wrapper.h"
|
||||
#include "syscall_hook_manager.h"
|
||||
#include "throne_comm.h"
|
||||
#include "dynamic_manager.h"
|
||||
|
||||
@@ -77,7 +78,7 @@ static int do_grant_root(void __user *arg)
|
||||
// we already check uid above on allowed_for_su()
|
||||
|
||||
pr_info("allow root for: %d\n", current_uid().val);
|
||||
escape_to_root();
|
||||
escape_with_root_profile();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -130,13 +131,13 @@ static int do_report_event(void __user *arg)
|
||||
if (!boot_complete_lock) {
|
||||
boot_complete_lock = true;
|
||||
pr_info("boot_complete triggered\n");
|
||||
on_boot_completed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_MODULE_MOUNTED: {
|
||||
ksu_module_mounted = true;
|
||||
pr_info("module mounted!\n");
|
||||
nuke_ext4_sysfs();
|
||||
on_module_mounted();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -408,6 +409,71 @@ put_orig_file:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_manage_mark(void __user *arg)
|
||||
{
|
||||
struct ksu_manage_mark_cmd cmd;
|
||||
int ret = 0;
|
||||
|
||||
if (copy_from_user(&cmd, arg, sizeof(cmd))) {
|
||||
pr_err("manage_mark: copy_from_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
switch (cmd.operation) {
|
||||
case KSU_MARK_GET: {
|
||||
// Get task mark status
|
||||
ret = ksu_get_task_mark(cmd.pid);
|
||||
if (ret < 0) {
|
||||
pr_err("manage_mark: get failed for pid %d: %d\n", cmd.pid, ret);
|
||||
return ret;
|
||||
}
|
||||
cmd.result = (u32)ret;
|
||||
break;
|
||||
}
|
||||
case KSU_MARK_MARK: {
|
||||
if (cmd.pid == 0) {
|
||||
ksu_mark_all_process();
|
||||
} else {
|
||||
ret = ksu_set_task_mark(cmd.pid, true);
|
||||
if (ret < 0) {
|
||||
pr_err("manage_mark: set_mark failed for pid %d: %d\n", cmd.pid,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KSU_MARK_UNMARK: {
|
||||
if (cmd.pid == 0) {
|
||||
ksu_unmark_all_process();
|
||||
} else {
|
||||
ret = ksu_set_task_mark(cmd.pid, false);
|
||||
if (ret < 0) {
|
||||
pr_err("manage_mark: set_unmark failed for pid %d: %d\n",
|
||||
cmd.pid, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KSU_MARK_REFRESH: {
|
||||
ksu_mark_running_process();
|
||||
pr_info("manage_mark: refreshed running processes\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
pr_err("manage_mark: invalid operation %u\n", cmd.operation);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (copy_to_user(arg, &cmd, sizeof(cmd))) {
|
||||
pr_err("manage_mark: copy_to_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 100. GET_FULL_VERSION - Get full version string
|
||||
static int do_get_full_version(void __user *arg)
|
||||
{
|
||||
@@ -626,6 +692,7 @@ static const struct ksu_ioctl_cmd_map ksu_ioctl_handlers[] = {
|
||||
{ .cmd = KSU_IOCTL_GET_FEATURE, .name = "GET_FEATURE", .handler = do_get_feature, .perm_check = manager_or_root },
|
||||
{ .cmd = KSU_IOCTL_SET_FEATURE, .name = "SET_FEATURE", .handler = do_set_feature, .perm_check = manager_or_root },
|
||||
{ .cmd = KSU_IOCTL_GET_WRAPPER_FD, .name = "GET_WRAPPER_FD", .handler = do_get_wrapper_fd, .perm_check = manager_or_root },
|
||||
{ .cmd = KSU_IOCTL_MANAGE_MARK, .name = "MANAGE_MARK", .handler = do_manage_mark, .perm_check = manager_or_root },
|
||||
{ .cmd = KSU_IOCTL_GET_FULL_VERSION,.name = "GET_FULL_VERSION", .handler = do_get_full_version, .perm_check = always_allow},
|
||||
{ .cmd = KSU_IOCTL_HOOK_TYPE,.name = "GET_HOOK_TYPE", .handler = do_get_hook_type, .perm_check = manager_or_root},
|
||||
{ .cmd = KSU_IOCTL_ENABLE_KPM, .name = "GET_ENABLE_KPM", .handler = do_enable_kpm, .perm_check = manager_or_root},
|
||||
@@ -641,6 +708,52 @@ static const struct ksu_ioctl_cmd_map ksu_ioctl_handlers[] = {
|
||||
{ .cmd = 0, .name = NULL, .handler = NULL, .perm_check = NULL} // Sentine
|
||||
};
|
||||
|
||||
// downstream: make sure to pass arg as reference, this can allow us to extend things.
|
||||
int ksu_handle_sys_reboot(int magic1, int magic2, unsigned int cmd, void __user **arg)
|
||||
{
|
||||
|
||||
if (magic1 != KSU_INSTALL_MAGIC1)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_KSU_DEBUG
|
||||
pr_info("sys_reboot: intercepted call! magic: 0x%x id: %d\n", magic1, magic2);
|
||||
#endif
|
||||
|
||||
// Check if this is a request to install KSU fd
|
||||
if (magic2 == KSU_INSTALL_MAGIC2) {
|
||||
int fd = ksu_install_fd();
|
||||
pr_info("[%d] install ksu fd: %d\n", current->pid, fd);
|
||||
|
||||
// downstream: dereference all arg usage!
|
||||
if (copy_to_user((void __user *)*arg, &fd, sizeof(fd))) {
|
||||
pr_err("install ksu fd reply err\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// extensions
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reboot hook for installing fd
|
||||
static int reboot_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = PT_REAL_REGS(regs);
|
||||
int magic1 = (int)PT_REGS_PARM1(real_regs);
|
||||
int magic2 = (int)PT_REGS_PARM2(real_regs);
|
||||
int cmd = (int)PT_REGS_PARM3(real_regs);
|
||||
void __user **arg = (void __user **)&PT_REGS_SYSCALL_PARM4(real_regs);
|
||||
|
||||
return ksu_handle_sys_reboot(magic1, magic2, cmd, arg);
|
||||
}
|
||||
|
||||
static struct kprobe reboot_kp = {
|
||||
.symbol_name = REBOOT_SYMBOL,
|
||||
.pre_handler = reboot_handler_pre,
|
||||
};
|
||||
|
||||
void ksu_supercalls_init(void)
|
||||
{
|
||||
int i;
|
||||
@@ -649,6 +762,17 @@ void ksu_supercalls_init(void)
|
||||
for (i = 0; ksu_ioctl_handlers[i].handler; i++) {
|
||||
pr_info(" %-18s = 0x%08x\n", ksu_ioctl_handlers[i].name, ksu_ioctl_handlers[i].cmd);
|
||||
}
|
||||
|
||||
int rc = register_kprobe(&reboot_kp);
|
||||
if (rc) {
|
||||
pr_err("reboot kprobe failed: %d\n", rc);
|
||||
} else {
|
||||
pr_info("reboot kprobe registered successfully\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ksu_supercalls_exit(void){
|
||||
unregister_kprobe(&reboot_kp);
|
||||
}
|
||||
|
||||
static inline void ksu_ioctl_audit(unsigned int cmd, const char *cmd_name, uid_t uid, int ret)
|
||||
|
||||
Reference in New Issue
Block a user