Clean up kernel code (#2898)

1) Fix memory leak of callback head in allowlist.c
2) Remove duplicated logic and incorrect log in kernel_umount.c
3) Prevent sleep in kprobe context in ksud.c
4) Remove useless is_unsupported_uid, use euid for security enhance,
   add FIXME in setuid_hook.c
5) Remove useless fd argument for execve hook, fix incorrent pointer
   usage in syscall_hook_manager.c and sucompat.c
6) Use correct errno in supercalls.c

---------

Co-authored-by: Ylarod <me@ylarod.cn>
This commit is contained in:
ShirkNeko
2025-11-09 19:20:30 +08:00
parent 0b63cc445c
commit cda7e4c6c0
8 changed files with 39 additions and 51 deletions

View File

@@ -399,6 +399,7 @@ close_file:
filp_close(fp, 0); filp_close(fp, 0);
unlock: unlock:
mutex_unlock(&allowlist_mutex); mutex_unlock(&allowlist_mutex);
kfree(_cb);
} }
void persistent_allow_list() void persistent_allow_list()

View File

@@ -135,8 +135,6 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid)
if (!ksu_uid_should_umount(new_uid)) { if (!ksu_uid_should_umount(new_uid)) {
return 0; return 0;
} else {
pr_info("uid: %d should not umount!\n", current_uid().val);
} }
// check old process's selinux context, if it is not zygote, ignore it! // check old process's selinux context, if it is not zygote, ignore it!

View File

@@ -195,7 +195,6 @@ static int __maybe_unused count(struct user_arg_ptr argv, int max)
if (fatal_signal_pending(current)) if (fatal_signal_pending(current))
return -ERESTARTNOHAND; return -ERESTARTNOHAND;
cond_resched();
} }
} }
return i; return i;

View File

@@ -43,6 +43,10 @@
#include "kernel_umount.h" #include "kernel_umount.h"
#include "app_profile.h" #include "app_profile.h"
#define PER_USER_RANGE 100000
#define FIRST_APPLICATION_UID 10000
#define LAST_APPLICATION_UID 19999
static bool ksu_enhanced_security_enabled = false; static bool ksu_enhanced_security_enabled = false;
static int enhanced_security_feature_get(u64 *value) static int enhanced_security_feature_get(u64 *value)
@@ -75,21 +79,8 @@ static inline bool is_allow_su()
return ksu_is_allow_uid_for_current(current_uid().val); return ksu_is_allow_uid_for_current(current_uid().val);
} }
static inline bool is_unsupported_uid(uid_t uid) static inline bool is_appuid(uid_t uid)
{ {
#define LAST_APPLICATION_UID 19999
uid_t appid = uid % 100000;
return appid > LAST_APPLICATION_UID;
}
// ksu_handle_prctl removed - now using ioctl via reboot hook
static bool is_appuid(uid_t uid)
{
#define PER_USER_RANGE 100000
#define FIRST_APPLICATION_UID 10000
#define LAST_APPLICATION_UID 19999
uid_t appid = uid % PER_USER_RANGE; uid_t appid = uid % PER_USER_RANGE;
return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID; return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID;
} }
@@ -98,28 +89,28 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{ {
uid_t new_uid = ruid; uid_t new_uid = ruid;
uid_t old_uid = current_uid().val; uid_t old_uid = current_uid().val;
pr_info("handle_setuid from %d to %d\n", old_uid, new_uid);
pr_info("handle_setresuid from %d to %d\n", old_uid, new_uid);
if (0 != old_uid) { // if old process is root, ignore it.
// old process is not root, ignore it. if (old_uid != 0 && ksu_enhanced_security_enabled) {
if (ksu_enhanced_security_enabled) { // disallow any non-ksu domain escalation from non-root to root!
// disallow any non-ksu domain escalation from non-root to root! // euid is what we care about here as it controls permission
if (unlikely(new_uid) == 0) { if (unlikely(euid == 0)) {
if (!is_ksu_domain()) { if (!is_ksu_domain()) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n", pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
current->pid, current->comm, old_uid, new_uid); current->pid, current->comm, old_uid, new_uid);
force_sig(SIGKILL); force_sig(SIGKILL);
return 0; return 0;
}
} }
// disallow appuid decrease to any other uid if it is allowed to su }
if (is_appuid(old_uid)) { // disallow appuid decrease to any other uid if it is not allowed to su
if (new_uid < old_uid && !ksu_is_allow_uid_for_current(old_uid)) { if (is_appuid(old_uid)) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n", if (euid < current_euid().val && !ksu_is_allow_uid_for_current(old_uid)) {
current->pid, current->comm, old_uid, new_uid); pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
force_sig(SIGKILL); current->pid, current->comm, old_uid, new_uid);
return 0; force_sig(SIGKILL);
} return 0;
} }
} }
return 0; return 0;
@@ -129,14 +120,15 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid)
ksu_set_task_tracepoint_flag(current); ksu_set_task_tracepoint_flag(current);
} }
if (!is_appuid(new_uid) || is_unsupported_uid(new_uid)) { // FIXME: isolated process which directly forks from zygote is not handled
pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid); if (!is_appuid(new_uid)) {
pr_info("handle setresuid ignore non application or isolated uid: %d\n", new_uid);
ksu_clear_task_tracepoint_flag(current); ksu_clear_task_tracepoint_flag(current);
return 0; return 0;
} }
// if on private space, see if its possibly the manager // if on private space, see if its possibly the manager
if (new_uid > 100000 && new_uid % 100000 == ksu_get_manager_uid()) { if (new_uid > PER_USER_RANGE && new_uid % PER_USER_RANGE == ksu_get_manager_uid()) {
ksu_set_manager_uid(new_uid); ksu_set_manager_uid(new_uid);
} }

View File

@@ -48,8 +48,8 @@ static const struct ksu_feature_handler su_compat_handler = {
static void __user *userspace_stack_buffer(const void *d, size_t len) static void __user *userspace_stack_buffer(const void *d, size_t len)
{ {
/* To avoid having to mmap a page in userspace, just write below the stack // To avoid having to mmap a page in userspace, just write below the stack
* pointer. */ // pointer.
char __user *p = (void __user *)current_user_stack_pointer() - len; char __user *p = (void __user *)current_user_stack_pointer() - len;
return copy_to_user(p, d, len) ? NULL : p; return copy_to_user(p, d, len) ? NULL : p;
@@ -147,7 +147,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
return 0; return 0;
} }
int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, int ksu_handle_execve_sucompat(const char __user **filename_user,
void *__never_use_argv, void *__never_use_envp, void *__never_use_argv, void *__never_use_envp,
int *__never_use_flags) int *__never_use_flags)
{ {
@@ -219,7 +219,7 @@ int __ksu_handle_devpts(struct inode *inode)
return 0; return 0;
} }
// sucompat: permited process can execute 'su' to gain root access. // sucompat: permitted process can execute 'su' to gain root access.
void ksu_sucompat_init() void ksu_sucompat_init()
{ {
if (ksu_register_feature_handler(&su_compat_handler)) { if (ksu_register_feature_handler(&su_compat_handler)) {

View File

@@ -11,7 +11,7 @@ void ksu_sucompat_exit(void);
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int ksu_handle_faccessat(int *dfd, const char __user **filename_user,
int *mode, int *__unused_flags); int *mode, int *__unused_flags);
int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, int ksu_handle_execve_sucompat(const char __user **filename_user,
void *__never_use_argv, void *__never_use_envp, void *__never_use_argv, void *__never_use_envp,
int *__never_use_flags); int *__never_use_flags);

View File

@@ -361,7 +361,7 @@ static int do_set_feature(void __user *arg)
static int do_get_wrapper_fd(void __user *arg) { static int do_get_wrapper_fd(void __user *arg) {
if (!ksu_file_sid) { if (!ksu_file_sid) {
return -1; return -EINVAL;
} }
struct ksu_get_wrapper_fd_cmd cmd; struct ksu_get_wrapper_fd_cmd cmd;

View File

@@ -217,7 +217,7 @@ static inline bool check_syscall_fastpath(int nr)
} }
} }
int ksu_handle_init_mark_tracker(int *fd, const char __user **filename_user, int ksu_handle_init_mark_tracker(const char __user **filename_user,
void *__never_use_argv, void *__never_use_envp, void *__never_use_argv, void *__never_use_envp,
int *__never_use_flags) int *__never_use_flags)
{ {
@@ -300,11 +300,9 @@ static void ksu_sys_enter_handler(void *data, struct pt_regs *regs, long id)
const char __user **filename_user = const char __user **filename_user =
(const char __user **)&PT_REGS_PARM1(regs); (const char __user **)&PT_REGS_PARM1(regs);
if (current->pid == 1) { if (current->pid == 1) {
ksu_handle_init_mark_tracker(AT_FDCWD, filename_user, ksu_handle_init_mark_tracker(filename_user, NULL, NULL, NULL);
NULL, NULL, NULL);
} else { } else {
ksu_handle_execve_sucompat(AT_FDCWD, filename_user, NULL, ksu_handle_execve_sucompat(filename_user, NULL, NULL, NULL);
NULL, NULL);
} }
return; return;
} }