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:
@@ -399,6 +399,7 @@ close_file:
|
||||
filp_close(fp, 0);
|
||||
unlock:
|
||||
mutex_unlock(&allowlist_mutex);
|
||||
kfree(_cb);
|
||||
}
|
||||
|
||||
void persistent_allow_list()
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
pr_info("handle_setresuid from %d to %d\n", old_uid, new_uid);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user