diff --git a/kernel/allowlist.c b/kernel/allowlist.c index c540af4a..fb8d7901 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -399,6 +399,7 @@ close_file: filp_close(fp, 0); unlock: mutex_unlock(&allowlist_mutex); + kfree(_cb); } void persistent_allow_list() diff --git a/kernel/kernel_umount.c b/kernel/kernel_umount.c index cce74584..32acf7e5 100644 --- a/kernel/kernel_umount.c +++ b/kernel/kernel_umount.c @@ -135,8 +135,6 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid) if (!ksu_uid_should_umount(new_uid)) { 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! diff --git a/kernel/ksud.c b/kernel/ksud.c index b8852a4a..e8885ef5 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -195,7 +195,6 @@ static int __maybe_unused count(struct user_arg_ptr argv, int max) if (fatal_signal_pending(current)) return -ERESTARTNOHAND; - cond_resched(); } } return i; diff --git a/kernel/setuid_hook.c b/kernel/setuid_hook.c index d46fceaf..880dd5a3 100644 --- a/kernel/setuid_hook.c +++ b/kernel/setuid_hook.c @@ -43,6 +43,10 @@ #include "kernel_umount.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 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); } -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; 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 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) { - // old process is not root, ignore it. - if (ksu_enhanced_security_enabled) { - // disallow any non-ksu domain escalation from non-root to root! - if (unlikely(new_uid) == 0) { - if (!is_ksu_domain()) { - pr_warn("find suspicious EoP: %d %s, from %d to %d\n", - current->pid, current->comm, old_uid, new_uid); - force_sig(SIGKILL); - return 0; - } + // if old process is root, ignore it. + if (old_uid != 0 && ksu_enhanced_security_enabled) { + // disallow any non-ksu domain escalation from non-root to root! + // euid is what we care about here as it controls permission + if (unlikely(euid == 0)) { + if (!is_ksu_domain()) { + pr_warn("find suspicious EoP: %d %s, from %d to %d\n", + current->pid, current->comm, old_uid, new_uid); + force_sig(SIGKILL); + return 0; } - // disallow appuid decrease to any other uid if it is allowed to su - if (is_appuid(old_uid)) { - if (new_uid < old_uid && !ksu_is_allow_uid_for_current(old_uid)) { - pr_warn("find suspicious EoP: %d %s, from %d to %d\n", - current->pid, current->comm, old_uid, new_uid); - force_sig(SIGKILL); - return 0; - } + } + // disallow appuid decrease to any other uid if it is not allowed to su + if (is_appuid(old_uid)) { + if (euid < current_euid().val && !ksu_is_allow_uid_for_current(old_uid)) { + pr_warn("find suspicious EoP: %d %s, from %d to %d\n", + current->pid, current->comm, old_uid, new_uid); + force_sig(SIGKILL); + 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); } - if (!is_appuid(new_uid) || is_unsupported_uid(new_uid)) { - pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid); + // FIXME: isolated process which directly forks from zygote is not handled + 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); return 0; } // 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); } diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 713743bb..7a283ec9 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -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) { - /* To avoid having to mmap a page in userspace, just write below the stack - * pointer. */ + // To avoid having to mmap a page in userspace, just write below the stack + // pointer. char __user *p = (void __user *)current_user_stack_pointer() - len; 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; } -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, int *__never_use_flags) { @@ -219,7 +219,7 @@ int __ksu_handle_devpts(struct inode *inode) 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() { if (ksu_register_feature_handler(&su_compat_handler)) { diff --git a/kernel/sucompat.h b/kernel/sucompat.h index d78d0c57..82161f7f 100644 --- a/kernel/sucompat.h +++ b/kernel/sucompat.h @@ -11,7 +11,7 @@ void ksu_sucompat_exit(void); int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int *__unused_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, int *__never_use_flags); diff --git a/kernel/supercalls.c b/kernel/supercalls.c index d6ee1063..36d45a57 100644 --- a/kernel/supercalls.c +++ b/kernel/supercalls.c @@ -361,7 +361,7 @@ static int do_set_feature(void __user *arg) static int do_get_wrapper_fd(void __user *arg) { if (!ksu_file_sid) { - return -1; + return -EINVAL; } struct ksu_get_wrapper_fd_cmd cmd; diff --git a/kernel/syscall_hook_manager.c b/kernel/syscall_hook_manager.c index fa196126..9eba26e2 100644 --- a/kernel/syscall_hook_manager.c +++ b/kernel/syscall_hook_manager.c @@ -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, 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 **)&PT_REGS_PARM1(regs); if (current->pid == 1) { - ksu_handle_init_mark_tracker(AT_FDCWD, filename_user, - NULL, NULL, NULL); + ksu_handle_init_mark_tracker(filename_user, NULL, NULL, NULL); } else { - ksu_handle_execve_sucompat(AT_FDCWD, filename_user, NULL, - NULL, NULL); + ksu_handle_execve_sucompat(filename_user, NULL, NULL, NULL); } return; }