Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 7 additions & 23 deletions kernel/allowlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@ static uint8_t allow_list_bitmap[PAGE_SIZE] __read_mostly __aligned(PAGE_SIZE);

#define KERNEL_SU_ALLOWLIST "/data/adb/ksu/.allowlist"

static struct work_struct ksu_save_work;
static struct work_struct ksu_load_work;

bool persistent_allow_list(void);
void save_allow_list(void);

void ksu_show_allow_list(void)
{
Expand Down Expand Up @@ -253,7 +250,7 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist)
}

if (persist)
persistent_allow_list();
save_allow_list();

return result;
}
Expand Down Expand Up @@ -349,7 +346,8 @@ bool ksu_get_allow_list(int *array, int *length, bool allow)
return true;
}

void do_save_allow_list(struct work_struct *work)
// make sure allow list works cross boot
void save_allow_list(void)
{
u32 magic = FILE_MAGIC;
u32 version = FILE_FORMAT_VERSION;
Expand Down Expand Up @@ -391,7 +389,7 @@ void do_save_allow_list(struct work_struct *work)
filp_close(fp, 0);
}

void do_load_allow_list(struct work_struct *work)
void ksu_load_allow_list()
{
loff_t off = 0;
ssize_t ret = 0;
Expand Down Expand Up @@ -476,21 +474,10 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data
mutex_unlock(&allowlist_mutex);

if (modified) {
persistent_allow_list();
save_allow_list();
}
}

// make sure allow list works cross boot
bool persistent_allow_list(void)
{
return ksu_queue_work(&ksu_save_work);
}

bool ksu_load_allow_list(void)
{
return ksu_queue_work(&ksu_load_work);
}

void ksu_allowlist_init(void)
{
int i;
Expand All @@ -503,9 +490,6 @@ void ksu_allowlist_init(void)

INIT_LIST_HEAD(&allow_list);

INIT_WORK(&ksu_save_work, do_save_allow_list);
INIT_WORK(&ksu_load_work, do_load_allow_list);

init_default_profiles();
}

Expand All @@ -514,7 +498,7 @@ void ksu_allowlist_exit(void)
struct perm_data *np = NULL;
struct perm_data *n = NULL;

do_save_allow_list(NULL);
save_allow_list();

// free allowlist
mutex_lock(&allowlist_mutex);
Expand Down
2 changes: 1 addition & 1 deletion kernel/allowlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ void ksu_allowlist_init(void);

void ksu_allowlist_exit(void);

bool ksu_load_allow_list(void);
void ksu_load_allow_list(void);

void ksu_show_allow_list(void);

Expand Down
28 changes: 27 additions & 1 deletion kernel/core_hook.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "linux/compiler.h"
#include "linux/sched/signal.h"
#include <linux/slab.h>
#include <linux/task_work.h>
#include <linux/thread_info.h>
Expand Down Expand Up @@ -40,6 +42,7 @@
#include "supercalls.h"

bool ksu_module_mounted = false;
extern bool ksu_su_compat_enabled;

extern int handle_sepolicy(unsigned long arg3, void __user *arg4);

Expand Down Expand Up @@ -145,6 +148,8 @@ static void disable_seccomp()
void escape_to_root(void)
{
struct cred *cred;
struct task_struct *p = current;
struct task_struct *t;

cred = prepare_creds();
if (!cred) {
Expand Down Expand Up @@ -195,6 +200,10 @@ void escape_to_root(void)
spin_unlock_irq(&current->sighand->siglock);

setup_selinux(profile->selinux_domain);

for_each_thread(p, t){
set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
}
}

void nuke_ext4_sysfs(void)
Expand Down Expand Up @@ -326,6 +335,12 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
return 0;
}

if (new_uid.val == 2000) {
if (ksu_su_compat_enabled) {
set_tsk_thread_flag(current, TIF_SYSCALL_TRACEPOINT);
}
}

if (!is_appuid(new_uid) || is_unsupported_uid(new_uid.val)) {
// pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val);
return 0;
Expand All @@ -341,6 +356,9 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
ksu_install_fd();
spin_lock_irq(&current->sighand->siglock);
ksu_seccomp_allow_cache(current->seccomp.filter, __NR_reboot);
if (ksu_su_compat_enabled) {
set_tsk_thread_flag(current, TIF_SYSCALL_TRACEPOINT);
}
spin_unlock_irq(&current->sighand->siglock);
return 0;
}
Expand All @@ -352,6 +370,14 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
ksu_seccomp_allow_cache(current->seccomp.filter, __NR_reboot);
spin_unlock_irq(&current->sighand->siglock);
}
if (ksu_su_compat_enabled) {
set_tsk_thread_flag(current, TIF_SYSCALL_TRACEPOINT);
}
} else {
// Disable syscall tracepoint sucompat for non-allowed processes
if (ksu_su_compat_enabled) {
clear_tsk_thread_flag(current, TIF_SYSCALL_TRACEPOINT);
}
}

// this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it!
Expand All @@ -374,7 +400,7 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
// check old process's selinux context, if it is not zygote, ignore it!
// because some su apps may setuid to untrusted_app but they are in global mount namespace
// when we umount for such process, that is a disaster!
bool is_zygote_child = is_zygote(old->security);
bool is_zygote_child = is_zygote(old);
if (!is_zygote_child) {
pr_info("handle umount ignore non zygote child: %d\n", current->pid);
return 0;
Expand Down
4 changes: 3 additions & 1 deletion kernel/ksud.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ bool ksu_input_hook __read_mostly = true;
#endif

u32 ksu_devpts_sid;

void on_post_fs_data(void)
{
static bool done = false;
Expand All @@ -70,6 +69,9 @@ void on_post_fs_data(void)
done = true;
pr_info("on_post_fs_data!\n");
ksu_load_allow_list();
extern void ksu_mark_running_process(void);
pr_info("mark tif for running process\n");
ksu_mark_running_process();
ksu_observer_init();
// sanity check, this may influence the performance
stop_input_hook();
Expand Down
26 changes: 22 additions & 4 deletions kernel/selinux/selinux.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "selinux.h"
#include "linux/cred.h"
#include "linux/sched.h"
#include "objsec.h"
#include "linux/version.h"
#include "../klog.h" // IWYU pragma: keep
Expand Down Expand Up @@ -84,12 +86,19 @@ static inline u32 current_sid(void)
}
#endif

bool is_ksu_domain()
bool is_task_ksu_domain(const struct cred* cred)
{
char *domain;
u32 seclen;
bool result;
int err = security_secid_to_secctx(current_sid(), &domain, &seclen);
if (!cred) {
return false;
}
const struct task_security_struct *tsec = selinux_cred(cred);
if (!tsec) {
return false;
}
int err = security_secid_to_secctx(tsec->sid, &domain, &seclen);
if (err) {
return false;
}
Expand All @@ -98,9 +107,18 @@ bool is_ksu_domain()
return result;
}

bool is_zygote(void *sec)
bool is_ksu_domain()
{
current_sid();
return is_task_ksu_domain(current_cred());
}

bool is_zygote(const struct cred* cred)
{
struct task_security_struct *tsec = (struct task_security_struct *)sec;
if (!cred) {
return false;
}
const struct task_security_struct * tsec = selinux_cred(cred);
if (!tsec) {
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion kernel/selinux/selinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@

#include "linux/types.h"
#include "linux/version.h"
#include "linux/sched.h"

void setup_selinux(const char *);

void setenforce(bool);

bool getenforce();

bool is_task_ksu_domain(const struct cred* cred);

bool is_ksu_domain();

bool is_zygote(void *cred);
bool is_zygote(const struct cred* cred);

void apply_kernelsu_rules();

Expand Down
Loading