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:
@@ -402,6 +402,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()
|
||||||
|
|||||||
@@ -439,8 +439,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!
|
||||||
|
|||||||
@@ -209,7 +209,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;
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
|
|
||||||
#include "sulog.h"
|
#include "sulog.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)
|
||||||
@@ -119,19 +123,8 @@ static inline bool is_allow_su(void)
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -434,28 +427,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);
|
|
||||||
|
|
||||||
if (0 != old_uid) {
|
pr_info("handle_setresuid from %d to %d\n", old_uid, new_uid);
|
||||||
// old process is not root, ignore it.
|
|
||||||
if (ksu_enhanced_security_enabled) {
|
// if old process is root, ignore it.
|
||||||
// disallow any non-ksu domain escalation from non-root to root!
|
if (old_uid != 0 && ksu_enhanced_security_enabled) {
|
||||||
if (unlikely(new_uid) == 0) {
|
// disallow any non-ksu domain escalation from non-root to root!
|
||||||
if (!is_ksu_domain()) {
|
// euid is what we care about here as it controls permission
|
||||||
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
|
if (unlikely(euid == 0)) {
|
||||||
current->pid, current->comm, old_uid, new_uid);
|
if (!is_ksu_domain()) {
|
||||||
force_sig(SIGKILL);
|
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
|
||||||
return 0;
|
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)) {
|
// 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;
|
||||||
@@ -465,14 +458,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ bool ksu_sucompat_hook_state __read_mostly = true;
|
|||||||
|
|
||||||
static inline void __user *userspace_stack_buffer(const void *d, size_t len)
|
static inline 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;
|
||||||
@@ -190,7 +190,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)
|
||||||
{
|
{
|
||||||
@@ -282,7 +282,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)) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -360,7 +360,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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user