kernel, ksud, manager: New supercalls implementations

* This commit squashes new supercall impl:
3138651a38..562a3b9be7

Thanks to these people below:

Official KernelSU:
Co-authored-by: Wang Han <416810799@qq.com>
Co-authored-by: weishu <twsxtd@gmail.com>
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>

xxKSU maintainer:
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
MMRL maintainer:
Co-authored-by: Der_Googler <54764558+dergoogler@users.noreply.github.com>
KSUN maintainer:
Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
KOWSU maintainer:
Co-authored-by: KOWX712 <leecc0503@gmail.com>
This commit is contained in:
ShirkNeko
2025-11-06 03:54:44 +08:00
parent c55a918957
commit 68f3be2cbe
23 changed files with 1804 additions and 2218 deletions

View File

@@ -18,6 +18,7 @@
#include "objsec.h"
#include "allowlist.h"
#include "arch.h"
#include "feature.h"
#include "klog.h" // IWYU pragma: keep
#include "ksud.h"
#include "kernel_compat.h"
@@ -29,8 +30,44 @@ static const char su[] = SU_PATH;
static const char ksud_path[] = KSUD_PATH;
extern void escape_to_root(void);
void ksu_sucompat_enable(void);
void ksu_sucompat_disable(void);
bool ksu_sucompat_hook_state __read_mostly = true;
static bool ksu_su_compat_enabled __read_mostly = true;
static int su_compat_feature_get(u64 *value)
{
*value = ksu_su_compat_enabled ? 1 : 0;
return 0;
}
static int su_compat_feature_set(u64 value)
{
bool enable = value != 0;
if (enable == ksu_su_compat_enabled) {
pr_info("su_compat: no need to change\n");
return 0;
}
if (enable) {
ksu_sucompat_enable();
} else {
ksu_sucompat_disable();
}
ksu_su_compat_enabled = enable;
pr_info("su_compat: set to %d\n", enable);
return 0;
}
static const struct ksu_feature_handler su_compat_handler = {
.feature_id = KSU_FEATURE_SU_COMPAT,
.name = "su_compat",
.get_handler = su_compat_feature_get,
.set_handler = su_compat_feature_set,
};
static inline void __user *userspace_stack_buffer(const void *d, size_t len)
{
@@ -55,7 +92,7 @@ static inline char __user *ksud_user_path(void)
static inline bool __is_su_allowed(const void *ptr_to_check)
{
#ifndef CONFIG_KSU_KPROBES_HOOK
if (!ksu_sucompat_hook_state)
if (!ksu_su_compat_enabled)
return false;
#endif
if (likely(!ksu_is_allow_uid(current_uid().val)))
@@ -174,6 +211,7 @@ int __ksu_handle_devpts(struct inode *inode)
#else
struct inode_security_struct *sec = (struct inode_security_struct *)inode->i_security;
#endif
if (ksu_devpts_sid && sec)
sec->sid = ksu_devpts_sid;
@@ -214,7 +252,6 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
NULL);
}
static struct kprobe *su_kps[6];
static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs)
{
struct inode *inode;
@@ -228,6 +265,12 @@ static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs)
return ksu_handle_devpts(inode);
}
#ifdef CONFIG_COMPAT
static struct kprobe *su_kps[6];
#else
static struct kprobe *su_kps[4];
#endif
static struct kprobe *init_kprobe(const char *name,
kprobe_pre_handler_t handler)
{
@@ -259,31 +302,55 @@ static void destroy_kprobe(struct kprobe **kp_ptr)
}
#endif
// sucompat: permited process can execute 'su' to gain root access.
void ksu_sucompat_init(void)
void ksu_sucompat_enable(void)
{
#ifdef CONFIG_KSU_KPROBES_HOOK
su_kps[0] = init_kprobe(SYS_EXECVE_SYMBOL, execve_handler_pre);
su_kps[1] = init_kprobe(SYS_EXECVE_COMPAT_SYMBOL, execve_handler_pre);
su_kps[2] = init_kprobe(SYS_FACCESSAT_SYMBOL, faccessat_handler_pre);
su_kps[3] = init_kprobe(SYS_NEWFSTATAT_SYMBOL, newfstatat_handler_pre);
su_kps[4] = init_kprobe(SYS_FSTATAT64_SYMBOL, newfstatat_handler_pre);
su_kps[5] = init_kprobe("pts_unix98_lookup", pts_unix98_lookup_pre);
#else
ksu_sucompat_hook_state = true;
pr_info("ksu_sucompat init\n");
su_kps[1] = init_kprobe(SYS_FACCESSAT_SYMBOL, faccessat_handler_pre);
su_kps[2] = init_kprobe(SYS_NEWFSTATAT_SYMBOL, newfstatat_handler_pre);
su_kps[3] = init_kprobe("pts_unix98_lookup", pts_unix98_lookup_pre);
#ifdef CONFIG_COMPAT
su_kps[4] = init_kprobe(SYS_EXECVE_COMPAT_SYMBOL, execve_handler_pre);
su_kps[5] = init_kprobe(SYS_FSTATAT64_SYMBOL, newfstatat_handler_pre);
#endif
#endif
}
void ksu_sucompat_exit(void)
void ksu_sucompat_disable(void)
{
#ifdef CONFIG_KSU_KPROBES_HOOK
int i;
for (i = 0; i < ARRAY_SIZE(su_kps); i++) {
destroy_kprobe(&su_kps[i]);
}
#else
ksu_sucompat_hook_state = false;
pr_info("ksu_sucompat exit\n");
#endif
}
// sucompat: permited process can execute 'su' to gain root access.
void ksu_sucompat_init(void)
{
if (ksu_register_feature_handler(&su_compat_handler)) {
pr_err("Failed to register su_compat feature handler\n");
}
#ifdef CONFIG_KSU_KPROBES_HOOK
if (ksu_su_compat_enabled) {
ksu_sucompat_enable();
}
#else
ksu_su_compat_enabled = true;
pr_info("init sucompat\n");
#endif
}
void ksu_sucompat_exit(void)
{
#ifdef CONFIG_KSU_KPROBES_HOOK
if (ksu_su_compat_enabled) {
ksu_sucompat_disable();
}
#else
ksu_su_compat_enabled = false;
pr_info("deinit sucompat\n");
#endif
ksu_unregister_feature_handler(KSU_FEATURE_SU_COMPAT);
}