Skip to content

Commit

Permalink
Import KSU_SUSFS patches from simonpunk
Browse files Browse the repository at this point in the history
Taken from: https://gitlab.com/simonpunk/susfs4ksu

Co-Authored-By: simonpunk <[email protected]>
  • Loading branch information
natsumerinchan and simonpunk committed May 16, 2024
1 parent d36e365 commit e281b77
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 0 deletions.
6 changes: 6 additions & 0 deletions kernel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ config KSU_DEBUG
help
Enable KernelSU debug mode.

config KSU_SUSFS
bool "KernelSU addon - SUSFS"
depends on KSU
default n
help
Patch SUSFS to kernel and KernelSU
endmenu
7 changes: 7 additions & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ endif
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function

ifeq ($(shell test -e $(srctree)/fs/susfs.c; echo $$?),0)
ccflags-y += -DKSU_SUSFS
$(info -- KSU_SUSFS is enabled.)
else
$(info -- You have not integrate susfs in your kernel.)
$(info -- Read: https://gitlab.com/simonpunk/susfs4ksu)
endif
# Keep a new line here!! Because someone may append config
169 changes: 169 additions & 0 deletions kernel/core_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
#include "throne_tracker.h"
#include "kernel_compat.h"

#ifdef CONFIG_KSU_SUSFS
#include "linux/susfs.h"
#endif

static bool ksu_module_mounted = false;

extern int handle_sepolicy(unsigned long arg3, void __user *arg4);
Expand Down Expand Up @@ -380,6 +384,165 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}

#ifdef CONFIG_KSU_SUSFS
if (current_uid().val == 0) {
int error = 0;
if (arg2 == CMD_SUSFS_ADD_SUS_PATH) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_path))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_path((struct st_susfs_sus_path __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_PATH -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_MOUNT) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_mount))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_mount((struct st_susfs_sus_mount __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_UPDATE_SUS_KSTAT) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> arg5 is not accessible\n");
return 0;
}
error = susfs_update_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
pr_info("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_MAPS) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_maps))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MAPS -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MAPS -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_maps((struct st_susfs_sus_maps __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_MAPS -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_UPDATE_SUS_MAPS) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_maps))) {
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_MAPS -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_MAPS -> arg5 is not accessible\n");
return 0;
}
error = susfs_update_sus_maps((struct st_susfs_sus_maps __user*)arg3);
pr_info("susfs: CMD_SUSFS_UPDATE_SUS_MAPS -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_MAPS_STATICALLY) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_maps))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MAPS_STATICALLY -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_MAPS_STATICALLY -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_maps((struct st_susfs_sus_maps __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_MAPS_STATICALLY -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_SUS_PROC_FD_LINK) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_proc_fd_link))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_PROC_FD_LINK -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_SUS_PROC_FD_LINK -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_sus_proc_fd_link((struct st_susfs_sus_proc_fd_link __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_SUS_PROC_FD_LINK -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ADD_TRY_UMOUNT) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_try_umount))) {
pr_err("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> arg5 is not accessible\n");
return 0;
}
error = susfs_add_try_umount((struct st_susfs_try_umount __user*)arg3);
pr_info("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_SET_UNAME) {
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_uname))) {
pr_err("susfs: CMD_SUSFS_SET_UNAME -> arg3 is not accessible\n");
return 0;
}
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
pr_err("susfs: CMD_SUSFS_SET_UNAME -> arg5 is not accessible\n");
return 0;
}
error = susfs_set_uname((struct st_susfs_uname __user*)arg3);
pr_info("susfs: CMD_SUSFS_SET_UNAME -> ret: %d\n", error);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
} else if (arg2 == CMD_SUSFS_ENABLE_LOG) {
if (arg3 != 0 && arg3 != 1) {
pr_err("susfs: CMD_SUSFS_ENABLE_LOG -> arg3 can only be 0 or 1\n");
return 0;
}
susfs_set_log(arg3);
copy_to_user((void __user*)arg5, &error, sizeof(error));
return 0;
}
return 0;
}
#endif

// we are already manager
if (arg2 == CMD_GET_APP_PROFILE) {
struct app_profile profile;
Expand Down Expand Up @@ -480,6 +643,8 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
err = ksu_umount_mnt(&path, flags);
if (err) {
pr_warn("umount %s failed: %d\n", mnt, err);
} else {
pr_info("umount %s successed", mnt);
}
}

Expand Down Expand Up @@ -546,6 +711,10 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
try_umount("/debug_ramdisk", false, MNT_DETACH);
try_umount("/sbin", false, MNT_DETACH);

#ifdef CONFIG_KSU_SUSFS
susfs_try_umount(new_uid.val);
#endif

return 0;
}

Expand Down
10 changes: 10 additions & 0 deletions kernel/kernel_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ void ksu_android_ns_fs_check()
task_unlock(current);
}

int ksu_access_ok(const void *addr, unsigned long size) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
/* For kernels before 5.0.0, pass the type argument to access_ok. */
return access_ok(VERIFY_READ, addr, size);
#else
/* For kernels 5.0.0 and later, ignore the type argument. */
return access_ok(addr, size);
#endif
}

struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
Expand Down
1 change: 1 addition & 0 deletions kernel/kernel_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern struct key *init_session_keyring;
#endif

extern void ksu_android_ns_fs_check();
extern int ksu_access_ok(const void *addr, unsigned long size);
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
umode_t mode);
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
Expand Down
8 changes: 8 additions & 0 deletions kernel/ksu.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "ksu.h"
#include "throne_tracker.h"

#ifdef CONFIG_KSU_SUSFS
#include "linux/susfs.h"
#endif

static struct workqueue_struct *ksu_workqueue;

bool ksu_queue_work(struct work_struct *work)
Expand Down Expand Up @@ -49,6 +53,10 @@ int __init kernelsu_init(void)
pr_alert("*************************************************************");
#endif

#ifdef CONFIG_KSU_SUSFS
susfs_init();
#endif

ksu_core_init();

ksu_workqueue = alloc_ordered_workqueue("kernelsu_work_queue", 0);
Expand Down
5 changes: 5 additions & 0 deletions kernel/selinux/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ void apply_kernelsu_rules()
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");

#ifdef CONFIG_KSU_SUSFS
// Allow umount in zygote process without installing zygisk
ksu_allow(db, "zygote", "labeledfs", "filesystem", "unmount");
#endif

rcu_read_unlock();
}

Expand Down

0 comments on commit e281b77

Please sign in to comment.