From 6fe4fcbce0099990a7ee6d8e9fd0b4fb6a015e30 Mon Sep 17 00:00:00 2001 From: Rifat Azad Date: Tue, 15 Jul 2025 22:23:43 +0600 Subject: [PATCH] kernel: susfs 1.5.9 a13-5.15 patch --- kernel/Kconfig | 135 +++++++++ kernel/Makefile | 79 +++++- kernel/allowlist.c | 10 +- kernel/apk_sign.c | 2 +- kernel/apk_sign.h | 2 +- kernel/core_hook.c | 586 +++++++++++++++++++++++++++++++++++++-- kernel/kernel_compat.c | 19 +- kernel/kernel_compat.h | 1 + kernel/ksu.c | 16 +- kernel/ksud.c | 21 +- kernel/ksud.h | 2 +- kernel/manager.h | 2 +- kernel/selinux/rules.c | 16 +- kernel/selinux/selinux.c | 95 ++++++- kernel/selinux/selinux.h | 24 +- kernel/setup.sh | 2 +- kernel/sucompat.c | 114 ++++++-- kernel/throne_tracker.c | 4 +- kernel/throne_tracker.h | 2 +- 19 files changed, 1037 insertions(+), 95 deletions(-) diff --git a/kernel/Kconfig b/kernel/Kconfig index ab6dd5c9..7ecf3b47 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -40,4 +40,139 @@ config KSU_LSM_SECURITY_HOOKS Disabling this is mostly only useful for kernel 4.1 and older. Make sure to implement manual hooks on security/security.c. +menu "KernelSU - SUSFS" +config KSU_SUSFS + bool "KernelSU addon - SUSFS" + depends on KSU + depends on THREAD_INFO_IN_TASK + default y + help + Patch and Enable SUSFS to kernel with KernelSU. + +config KSU_SUSFS_HAS_MAGIC_MOUNT + bool "Say yes if the current KernelSU repo has magic mount implemented (default y)" + depends on KSU + default y + help + - Enable to indicate that the current SUSFS kernel supports the auto hide features for 5ec1cff's Magic Mount KernelSU + - Every mounts from /debug_ramdisk/workdir will be treated as magic mount and processed differently by susfs + +config KSU_SUSFS_SUS_PATH + bool "Enable to hide suspicious path (NOT recommended)" + depends on KSU_SUSFS + default y + help + - Allow hiding the user-defined path and all its sub-paths from various system calls. + - Includes temp fix for the leaks of app path in /sdcard/Android/data directory. + - Effective only on zygote spawned user app process. + - Use with cautious as it may cause performance loss and will be vulnerable to side channel attacks, + just disable this feature if it doesn't work for you or you don't need it at all. + +config KSU_SUSFS_SUS_MOUNT + bool "Enable to hide suspicious mounts" + depends on KSU_SUSFS + default y + help + - Allow hiding the user-defined mount paths from /proc/self/[mounts|mountinfo|mountstat]. + - Effective on all processes for hiding mount entries. + - Mounts mounted by process with ksu domain will be forced to be assigned the dev name "KSU". + - mnt_id and mnt_group_id of the sus mount will be assigned to a much bigger number to solve the issue of id not being contiguous. + +config KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT + bool "Enable to hide KSU's default mounts automatically (experimental)" + depends on KSU_SUSFS_SUS_MOUNT + default y + help + - Automatically add KSU's default mounts to sus_mount. + - No susfs command is needed in userspace. + - Only mount operation from process with ksu domain will be checked. + +config KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT + bool "Enable to hide suspicious bind mounts automatically (experimental)" + depends on KSU_SUSFS_SUS_MOUNT + default y + help + - Automatically add binded mounts to sus_mount. + - No susfs command is needed in userspace. + - Only mount operation from process with ksu domain will be checked. + +config KSU_SUSFS_SUS_KSTAT + bool "Enable to spoof suspicious kstat" + depends on KSU_SUSFS + default y + help + - Allow spoofing the kstat of user-defined file/directory. + - Effective only on zygote spawned user app process. + +config KSU_SUSFS_TRY_UMOUNT + bool "Enable to use ksu's ksu_try_umount" + depends on KSU_SUSFS + default y + help + - Allow using ksu_try_umount to umount other user-defined mount paths prior to ksu's default umount paths. + - Effective on all NO-root-access-granted processes. + +config KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT + bool "Enable to add bind mounts to ksu's ksu_try_umount automatically (experimental)" + depends on KSU_SUSFS_TRY_UMOUNT + default y + help + - Automatically add binded mounts to ksu's ksu_try_umount. + - No susfs command is needed in userspace. + - Only mount operation from process with ksu domain will be checked. + +config KSU_SUSFS_SPOOF_UNAME + bool "Enable to spoof uname" + depends on KSU_SUSFS + default y + help + - Allow spoofing the string returned by uname syscall to user-defined string. + - Effective on all processes. + +config KSU_SUSFS_ENABLE_LOG + bool "Enable logging susfs log to kernel" + depends on KSU_SUSFS + default y + help + - Allow logging susfs log to kernel, uncheck it to completely disable all susfs log. + +config KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS + bool "Enable to automatically hide ksu and susfs symbols from /proc/kallsyms" + depends on KSU_SUSFS + default y + help + - Automatically hide ksu and susfs symbols from '/proc/kallsyms'. + - Effective on all processes. + +config KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG + bool "Enable to spoof /proc/bootconfig (gki) or /proc/cmdline (non-gki)" + depends on KSU_SUSFS + default y + help + - Spoof the output of /proc/bootconfig (gki) or /proc/cmdline (non-gki) with a user-defined file. + - Effective on all processes. + +config KSU_SUSFS_OPEN_REDIRECT + bool "Enable to redirect a path to be opened with another path (experimental)" + depends on KSU_SUSFS + default y + help + - Allow redirecting a target path to be opened with another user-defined path. + - Effective only on processes with uid < 2000. + - Please be reminded that process with open access to the target and redirected path can be detected. + +config KSU_SUSFS_SUS_SU + bool "Enable SUS-SU in runtime temporarily" + depends on KSU_SUSFS && KPROBES && HAVE_KPROBES && KPROBE_EVENTS + default y + help + - Allow user to enable or disable core ksu kprobes hooks temporarily in runtime. There are 2 working modes for sus_su. + - Mode 0 (default): Disable sus_su, and enable ksu kprobe hooks for su instead. + - Mode 1 (deprecated): + - Mode 2: Enable sus_su, and disable ksu kprobe hooks for su, which means the kernel inline hooks are enabled, + the same as the su implementaion of non-gki kernel without kprobe supported. + - Only apps with root access granted by ksu manager are allowed to get root. + +endmenu + endmenu diff --git a/kernel/Makefile b/kernel/Makefile index 6da2b6f0..fbbcef12 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -21,7 +21,7 @@ ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0) $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin [ -f ../.git/shallow ] && git fetch --unshallow) KSU_GIT_VERSION := $(shell cd $(srctree)/$(src); /usr/bin/env PATH="$$PATH":/usr/bin:/usr/local/bin git rev-list --count HEAD) # ksu_version: major * 10000 + git version + 200 for historical reasons -$(eval KSU_VERSION=$(shell expr 10000 + $(KSU_GIT_VERSION) + 200)) +$(eval KSU_VERSION=$(shell expr 10000 + $(KSU_GIT_VERSION) + 198)) $(info -- KernelSU-Next version: $(KSU_VERSION)) ccflags-y += -DKSU_VERSION=$(KSU_VERSION) else # If there is no .git file, the default version will be passed. @@ -116,4 +116,81 @@ 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 +## For non-gki compatiblity ## +ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0) +ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID +endif + +ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0) +ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE +endif + +ccflags-y += -DKSU_UMOUNT +ifneq ($(shell grep -Eq "get_cred_rcu" $(srctree)/include/linux/cred.h; echo $$?),0) +$(info -- KSU_SUSFS: adding function 'static inline const struct cred *get_cred_rcu();' to $(srctree)/include/linux/cred.h) +GET_CRED_RCU = static inline const struct cred *get_cred_rcu(const struct cred *cred)\n\ +{\n\t\ + struct cred *nonconst_cred = (struct cred *) cred;\n\t\ + if (!cred)\n\t\t\ + return NULL;\n\t\ + if (!atomic_inc_not_zero(&nonconst_cred->usage))\n\t\t\ + return NULL;\n\t\ + validate_creds(cred);\n\t\ + return cred;\n\ +}\n +$(shell sed -i '/^static inline void put_cred/i $(GET_CRED_RCU)' $(srctree)/include/linux/cred.h;) +endif + +ifneq ($(shell grep -Eq "^static int can_umount" $(srctree)/fs/namespace.c; echo $$?),0) +$(info -- KSU_SUSFS: adding function 'static int can_umount(const struct path *path, int flags);' to $(srctree)/fs/namespace.c) +CAN_UMOUNT = static int can_umount(const struct path *path, int flags)\n\ +{\n\t\ + struct mount *mnt = real_mount(path->mnt);\n\t\ + if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))\n\t\t\ + return -EINVAL;\n\t\ + if (!may_mount())\n\t\t\ + return -EPERM;\n\t\ + if (path->dentry != path->mnt->mnt_root)\n\t\t\ + return -EINVAL;\n\t\ + if (!check_mnt(mnt))\n\t\t\ + return -EINVAL;\n\t\ + if (mnt->mnt.mnt_flags & MNT_LOCKED)\n\t\t\ + return -EINVAL;\n\t\ + if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))\n\t\t\ + return -EPERM;\n\t\ + return 0;\n\ +}\n +$(shell sed -i '/^static bool is_mnt_ns_file/i $(CAN_UMOUNT)' $(srctree)/fs/namespace.c;) +endif + +ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/namespace.c; echo $$?),0) +$(info -- KSU_SUSFS: adding function 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/namespace.c) +PATH_UMOUNT = int path_umount(struct path *path, int flags)\n\ +{\n\t\ + struct mount *mnt = real_mount(path->mnt);\n\t\ + int ret;\n\t\ + ret = can_umount(path, flags);\n\t\ + if (!ret)\n\t\t\ + ret = do_umount(mnt, flags);\n\t\ + dput(path->dentry);\n\t\ + mntput_no_expire(mnt);\n\t\ + return ret;\n\ +}\n +$(shell sed -i '/^static bool is_mnt_ns_file/i $(PATH_UMOUNT)' $(srctree)/fs/namespace.c;) +endif + +ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/internal.h; echo $$?),0) +$(shell sed -i '/^extern void __init mnt_init/a int path_umount(struct path *path, int flags);' $(srctree)/fs/internal.h;) +$(info -- KSU_SUSFS: adding 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/internal.h) +endif + +## For susfs stuff ## +ifeq ($(shell test -e $(srctree)/fs/susfs.c; echo $$?),0) +$(eval SUSFS_VERSION=$(shell cat $(srctree)/include/linux/susfs.h | grep -E '^#define SUSFS_VERSION' | cut -d' ' -f3 | sed 's/"//g')) +$(info ) +$(info -- SUSFS_VERSION: $(SUSFS_VERSION)) +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 diff --git a/kernel/allowlist.c b/kernel/allowlist.c index bcdac3f0..6f2557c9 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -95,7 +95,7 @@ static uint8_t allow_list_bitmap[PAGE_SIZE] __read_mostly __aligned(PAGE_SIZE); static struct work_struct ksu_save_work; static struct work_struct ksu_load_work; -bool persistent_allow_list(void); +static bool persistent_allow_list(void); void ksu_show_allow_list(void) { @@ -266,7 +266,7 @@ bool __ksu_is_allow_uid(uid_t uid) if (unlikely(uid == 0)) { // already root, but only allow our domain. - return is_ksu_domain(); + return ksu_is_ksu_domain(); } if (forbid_system_uid(uid)) { @@ -351,7 +351,7 @@ bool ksu_get_allow_list(int *array, int *length, bool allow) return true; } -void do_save_allow_list(struct work_struct *work) +static void do_save_allow_list(struct work_struct *work) { u32 magic = FILE_MAGIC; u32 version = FILE_FORMAT_VERSION; @@ -393,7 +393,7 @@ exit: filp_close(fp, 0); } -void do_load_allow_list(struct work_struct *work) +static void do_load_allow_list(struct work_struct *work) { loff_t off = 0; ssize_t ret = 0; @@ -483,7 +483,7 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data } // make sure allow list works cross boot -bool persistent_allow_list(void) +static bool persistent_allow_list(void) { return ksu_queue_work(&ksu_save_work); } diff --git a/kernel/apk_sign.c b/kernel/apk_sign.c index c1e803d7..876dd648 100644 --- a/kernel/apk_sign.c +++ b/kernel/apk_sign.c @@ -315,7 +315,7 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops, #endif -bool is_manager_apk(char *path) +bool ksu_is_manager_apk(char *path) { int tries = 0; diff --git a/kernel/apk_sign.h b/kernel/apk_sign.h index bed501c4..e02aa514 100644 --- a/kernel/apk_sign.h +++ b/kernel/apk_sign.h @@ -3,6 +3,6 @@ #include -bool is_manager_apk(char *path); +bool ksu_is_manager_apk(char *path); #endif diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 6bbb350c..8a722c48 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -35,6 +35,10 @@ #include #endif +#ifdef CONFIG_KSU_SUSFS +#include +#endif // #ifdef CONFIG_KSU_SUSFS + #include "allowlist.h" #include "arch.h" #include "core_hook.h" @@ -44,20 +48,91 @@ #include "manager.h" #include "selinux/selinux.h" #include "throne_tracker.h" -#include "throne_tracker.h" #include "kernel_compat.h" +#ifdef CONFIG_KSU_SUSFS +bool susfs_is_allow_su(void) +{ + if (ksu_is_manager()) { + // we are manager, allow! + return true; + } + return ksu_is_allow_uid(current_uid().val); +} + +extern u32 susfs_zygote_sid; +extern bool susfs_is_mnt_devname_ksu(struct path *path); +#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG +extern bool susfs_is_log_enabled __read_mostly; +#endif +#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +extern void susfs_run_try_umount_for_current_mnt_ns(void); +#endif // #ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +static bool susfs_is_umount_for_zygote_system_process_enabled = false; +static bool susfs_is_umount_for_zygote_iso_service_enabled = false; +extern bool susfs_hide_sus_mnts_for_all_procs; +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT +extern bool susfs_is_auto_add_sus_bind_mount_enabled; +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT +extern bool susfs_is_auto_add_sus_ksu_default_mount_enabled; +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT +extern bool susfs_is_auto_add_try_umount_for_bind_mount_enabled; +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT +#ifdef CONFIG_KSU_SUSFS_SUS_SU +extern bool susfs_is_sus_su_ready; +extern int susfs_sus_su_working_mode; +extern bool susfs_is_sus_su_hooks_enabled __read_mostly; +extern bool ksu_devpts_hook; +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU + +static inline void susfs_on_post_fs_data(void) { + struct path path; +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + if (!kern_path(DATA_ADB_UMOUNT_FOR_ZYGOTE_SYSTEM_PROCESS, 0, &path)) { + susfs_is_umount_for_zygote_system_process_enabled = true; + path_put(&path); + } + pr_info("susfs_is_umount_for_zygote_system_process_enabled: %d\n", susfs_is_umount_for_zygote_system_process_enabled); +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT + if (!kern_path(DATA_ADB_NO_AUTO_ADD_SUS_BIND_MOUNT, 0, &path)) { + susfs_is_auto_add_sus_bind_mount_enabled = false; + path_put(&path); + } + pr_info("susfs_is_auto_add_sus_bind_mount_enabled: %d\n", susfs_is_auto_add_sus_bind_mount_enabled); +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT + if (!kern_path(DATA_ADB_NO_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT, 0, &path)) { + susfs_is_auto_add_sus_ksu_default_mount_enabled = false; + path_put(&path); + } + pr_info("susfs_is_auto_add_sus_ksu_default_mount_enabled: %d\n", susfs_is_auto_add_sus_ksu_default_mount_enabled); +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT + if (!kern_path(DATA_ADB_NO_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT, 0, &path)) { + susfs_is_auto_add_try_umount_for_bind_mount_enabled = false; + path_put(&path); + } + pr_info("susfs_is_auto_add_try_umount_for_bind_mount_enabled: %d\n", susfs_is_auto_add_try_umount_for_bind_mount_enabled); +#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT +} +#endif // #ifdef CONFIG_KSU_SUSFS + static bool ksu_module_mounted = false; -extern int handle_sepolicy(unsigned long arg3, void __user *arg4); +extern int ksu_handle_sepolicy(unsigned long arg3, void __user *arg4); -static bool ksu_su_compat_enabled = true; +bool ksu_su_compat_enabled = true; extern void ksu_sucompat_init(); extern void ksu_sucompat_exit(); static inline bool is_allow_su() { - if (is_manager()) { + if (ksu_is_manager()) { // we are manager, allow! return true; } @@ -135,7 +210,7 @@ static void disable_seccomp(void) #endif } -void escape_to_root(void) +void ksu_escape_to_root(void) { struct cred *cred; @@ -193,7 +268,7 @@ void escape_to_root(void) disable_seccomp(); spin_unlock_irq(¤t->sighand->siglock); - setup_selinux(profile->selinux_domain); + ksu_setup_selinux(profile->selinux_domain); } int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry) @@ -230,7 +305,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry) pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname, new_dentry->d_iname, buf); - track_throne(); + ksu_track_throne(); return 0; } @@ -275,7 +350,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } bool from_root = 0 == current_uid().val; - bool from_manager = is_manager(); + bool from_manager = ksu_is_manager(); if (!from_root && !from_manager) { // only root or manager can access this interface @@ -299,7 +374,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, if (arg2 == CMD_GRANT_ROOT) { if (is_allow_su()) { pr_info("allow root for: %d\n", current_uid().val); - escape_to_root(); + ksu_escape_to_root(); if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { pr_err("grant_root: prctl reply error\n"); } @@ -354,10 +429,13 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, switch (arg3) { case EVENT_POST_FS_DATA: { static bool post_fs_data_lock = false; +#ifdef CONFIG_KSU_SUSFS + susfs_on_post_fs_data(); +#endif if (!post_fs_data_lock) { post_fs_data_lock = true; pr_info("post-fs-data triggered\n"); - on_post_fs_data(); + ksu_on_post_fs_data(); } break; } @@ -385,7 +463,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, if (!from_root) { return 0; } - if (!handle_sepolicy(arg3, arg4)) { + if (!ksu_handle_sepolicy(arg3, arg4)) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { pr_err("sepolicy: prctl reply error\n"); } @@ -446,6 +524,352 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, return 0; } +#ifdef CONFIG_KSU_SUSFS + if (current_uid_val == 0) { +#ifdef CONFIG_KSU_SUSFS_SUS_PATH + if (arg2 == CMD_SUSFS_ADD_SUS_PATH) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, SUSFS_MAX_LEN_PATHNAME)) { + pr_err("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> arg5 is not accessible\n"); + return 0; + } + error = susfs_set_i_state_on_external_dir((char __user*)arg3, CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH); + pr_info("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_SET_SDCARD_ROOT_PATH) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, SUSFS_MAX_LEN_PATHNAME)) { + pr_err("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> arg5 is not accessible\n"); + return 0; + } + error = susfs_set_i_state_on_external_dir((char __user*)arg3, CMD_SUSFS_SET_SDCARD_ROOT_PATH); + pr_info("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SUS_PATH +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + if (arg2 == CMD_SUSFS_ADD_SUS_MOUNT) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS) { + int error = 0; + if (arg3 != 0 && arg3 != 1) { + pr_err("susfs: CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS -> arg3 can only be 0 or 1\n"); + return 0; + } + susfs_hide_sus_mnts_for_all_procs = arg3; + pr_info("susfs: CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS -> susfs_hide_sus_mnts_for_all_procs: %lu\n", arg3); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE) { + int error = 0; + if (arg3 != 0 && arg3 != 1) { + pr_err("susfs: CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE -> arg3 can only be 0 or 1\n"); + return 0; + } + susfs_is_umount_for_zygote_iso_service_enabled = arg3; + pr_info("susfs: CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE -> susfs_is_umount_for_zygote_iso_service_enabled: %lu\n", arg3); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT + if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_UPDATE_SUS_KSTAT) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT +#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT + if (arg2 == CMD_SUSFS_ADD_TRY_UMOUNT) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_RUN_UMOUNT_FOR_CURRENT_MNT_NS) { + int error = 0; + susfs_run_try_umount_for_current_mnt_ns(); + pr_info("susfs: CMD_SUSFS_RUN_UMOUNT_FOR_CURRENT_MNT_NS -> ret: %d\n", error); + } +#endif //#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME + if (arg2 == CMD_SUSFS_SET_UNAME) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME +#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG + if (arg2 == CMD_SUSFS_ENABLE_LOG) { + int error = 0; + 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); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG +#ifdef CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG + if (arg2 == CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, SUSFS_FAKE_CMDLINE_OR_BOOTCONFIG_SIZE)) { + pr_err("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> arg5 is not accessible\n"); + return 0; + } + error = susfs_set_cmdline_or_bootconfig((char __user*)arg3); + pr_info("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG +#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT + if (arg2 == CMD_SUSFS_ADD_OPEN_REDIRECT) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_open_redirect))) { + pr_err("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> arg5 is not accessible\n"); + return 0; + } + error = susfs_add_open_redirect((struct st_susfs_open_redirect __user*)arg3); + pr_info("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT +#ifdef CONFIG_KSU_SUSFS_SUS_SU + if (arg2 == CMD_SUSFS_SUS_SU) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_sus_su))) { + pr_err("susfs: CMD_SUSFS_SUS_SU -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SUS_SU -> arg5 is not accessible\n"); + return 0; + } + error = susfs_sus_su((struct st_sus_su __user*)arg3); + pr_info("susfs: CMD_SUSFS_SUS_SU -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif //#ifdef CONFIG_KSU_SUSFS_SUS_SU + if (arg2 == CMD_SUSFS_SHOW_VERSION) { + int error = 0; + int len_of_susfs_version = strlen(SUSFS_VERSION); + char *susfs_version = SUSFS_VERSION; + if (!ksu_access_ok((void __user*)arg3, len_of_susfs_version+1)) { + pr_err("susfs: CMD_SUSFS_SHOW_VERSION -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SHOW_VERSION -> arg5 is not accessible\n"); + return 0; + } + error = copy_to_user((void __user*)arg3, (void*)susfs_version, len_of_susfs_version+1); + pr_info("susfs: CMD_SUSFS_SHOW_VERSION -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_SHOW_ENABLED_FEATURES) { + int error = 0; + if (arg4 <= 0) { + pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg4 cannot be <= 0\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg3, arg4)) { + pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg5 is not accessible\n"); + return 0; + } + error = susfs_get_enabled_features((char __user*)arg3, arg4); + pr_info("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_SHOW_VARIANT) { + int error = 0; + int len_of_variant = strlen(SUSFS_VARIANT); + char *susfs_variant = SUSFS_VARIANT; + if (!ksu_access_ok((void __user*)arg3, len_of_variant+1)) { + pr_err("susfs: CMD_SUSFS_SHOW_VARIANT -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SHOW_VARIANT -> arg5 is not accessible\n"); + return 0; + } + error = copy_to_user((void __user*)arg3, (void*)susfs_variant, len_of_variant+1); + pr_info("susfs: CMD_SUSFS_SHOW_VARIANT -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#ifdef CONFIG_KSU_SUSFS_SUS_SU + if (arg2 == CMD_SUSFS_IS_SUS_SU_READY) { + int error = 0; + if (!ksu_access_ok((void __user*)arg3, sizeof(susfs_is_sus_su_ready))) { + pr_err("susfs: CMD_SUSFS_IS_SUS_SU_READY -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_IS_SUS_SU_READY -> arg5 is not accessible\n"); + return 0; + } + error = copy_to_user((void __user*)arg3, (void*)&susfs_is_sus_su_ready, sizeof(susfs_is_sus_su_ready)); + pr_info("susfs: CMD_SUSFS_IS_SUS_SU_READY -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } + if (arg2 == CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE) { + int error = 0; + int working_mode = susfs_get_sus_su_working_mode(); + if (!ksu_access_ok((void __user*)arg3, sizeof(working_mode))) { + pr_err("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> arg3 is not accessible\n"); + return 0; + } + if (!ksu_access_ok((void __user*)arg5, sizeof(error))) { + pr_err("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> arg5 is not accessible\n"); + return 0; + } + error = copy_to_user((void __user*)arg3, (void*)&working_mode, sizeof(working_mode)); + pr_info("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> ret: %d\n", error); + if (copy_to_user((void __user*)arg5, &error, sizeof(error))) + pr_info("susfs: copy_to_user() failed\n"); + return 0; + } +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU + } +#endif //#ifdef CONFIG_KSU_SUSFS + // all other cmds are for 'root manager' if (!from_manager) { return 0; @@ -511,6 +935,12 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } if (enabled) { +#ifdef CONFIG_KSU_SUSFS_SUS_SU + // We disable all sus_su hook whenever user toggle on su_kps + susfs_is_sus_su_hooks_enabled = false; + ksu_devpts_hook = false; + susfs_sus_su_working_mode = SUS_SU_DISABLED; +#endif ksu_sucompat_init(); } else { ksu_sucompat_exit(); @@ -549,11 +979,15 @@ static bool should_umount(struct path *path) return false; } +#ifdef CONFIG_KSU_SUSFS + return susfs_is_mnt_devname_ksu(path); +#else if (path->mnt && path->mnt->mnt_sb && path->mnt->mnt_sb->s_type) { const char *fstype = path->mnt->mnt_sb->s_type->name; return strcmp(fstype, "overlay") == 0; } return false; +#endif } static int ksu_umount_mnt(struct path *path, int flags) @@ -566,7 +1000,11 @@ static int ksu_umount_mnt(struct path *path, int flags) #endif } -static void try_umount(const char *mnt, bool check_mnt, int flags) +#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +void ksu_try_umount(const char *mnt, bool check_mnt, int flags, uid_t uid) +#else +static void ksu_try_umount(const char *mnt, bool check_mnt, int flags) +#endif { struct path path; int err = kern_path(mnt, 0, &path); @@ -586,12 +1024,45 @@ static void try_umount(const char *mnt, bool check_mnt, int flags) return; } +#if defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) && defined(CONFIG_KSU_SUSFS_ENABLE_LOG) + if (susfs_is_log_enabled) { + pr_info("susfs: umounting '%s' for uid: %d\n", mnt, uid); + } +#endif + err = ksu_umount_mnt(&path, flags); if (err) { pr_warn("umount %s failed: %d\n", mnt, err); } } +#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +void susfs_try_umount_all(uid_t uid) { + susfs_try_umount(uid); + /* For Legacy KSU only */ + ksu_try_umount("/system", true, 0, uid); + ksu_try_umount("/system_ext", true, 0, uid); + ksu_try_umount("/vendor", true, 0, uid); + ksu_try_umount("/product", true, 0, uid); + ksu_try_umount("/odm", true, 0, uid); + // - For '/data/adb/modules' we pass 'false' here because it is a loop device that we can't determine whether + // its dev_name is KSU or not, and it is safe to just umount it if it is really a mountpoint + ksu_try_umount("/data/adb/modules", false, MNT_DETACH, uid); + /* For both Legacy KSU and Magic Mount KSU */ + ksu_try_umount("/debug_ramdisk", true, MNT_DETACH, uid); + // try umount ksu temp path + ksu_try_umount("/sbin", true, MNT_DETACH, uid); + + // try umount hosts file + ksu_try_umount("/system/etc/hosts", false, MNT_DETACH, uid); + + // try umount lsposed dex2oat bins + ksu_try_umount("/apex/com.android.art/bin/dex2oat64", false, MNT_DETACH, uid); + ksu_try_umount("/apex/com.android.art/bin/dex2oat32", false, MNT_DETACH, uid); +} +#endif + + int ksu_handle_setuid(struct cred *new, const struct cred *old) { // this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it! @@ -611,6 +1082,52 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) return 0; } +#ifdef CONFIG_KSU_SUSFS + // check if current process is zygote + bool is_zygote_child = susfs_is_sid_equal(old->security, susfs_zygote_sid); +#endif // #ifdef CONFIG_KSU_SUSFS + if (likely(is_zygote_child)) { + // if spawned process is non user app process + if (unlikely(new_uid.val < 10000 && new_uid.val >= 1000)) { +#ifdef CONFIG_KSU_SUSFS_SUS_SU + // set flag if zygote spawned system process is allowed for root access + if (!ksu_is_allow_uid(new_uid.val)) { + task_lock(current); + susfs_set_current_proc_su_not_allowed(); + task_unlock(current); + } +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + // umount for the system process if path DATA_ADB_UMOUNT_FOR_ZYGOTE_SYSTEM_PROCESS exists + if (susfs_is_umount_for_zygote_system_process_enabled) { + goto out_ksu_try_umount; + } +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + } +#ifdef CONFIG_KSU_SUSFS + // - here we check if uid is a isolated service spawned by zygote directly + // - Apps that do not use "useAppZyogte" to start a isolated service will be directly + // spawned by zygote which KSU will ignore it by default, the only fix for now is to + // force a umount for those uid + // - Therefore make sure your root app doesn't use isolated service for root access + // - Kudos to ThePedroo, the author and maintainer of Rezygisk for finding and reporting + // the detection, really big helps here! + else if (new_uid.val >= 90000 && new_uid.val < 1000000) { + task_lock(current); + susfs_set_current_non_root_user_app_proc(); +#ifdef CONFIG_KSU_SUSFS_SUS_SU + susfs_set_current_proc_su_not_allowed(); +#endif + task_unlock(current); +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + if (susfs_is_umount_for_zygote_iso_service_enabled) { + goto out_susfs_try_umount_all; + } +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + } + } +#endif // #ifdef CONFIG_KSU_SUSFS + 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; @@ -620,7 +1137,20 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) // pr_info("handle setuid ignore allowed application: %d\n", new_uid.val); return 0; } +#ifdef CONFIG_KSU_SUSFS + else { + task_lock(current); + susfs_set_current_non_root_user_app_proc(); +#ifdef CONFIG_KSU_SUSFS_SUS_SU + susfs_set_current_proc_su_not_allowed(); +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU + task_unlock(current); + } +#endif // #ifdef CONFIG_KSU_SUSFS +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +out_ksu_try_umount: +#endif if (!ksu_uid_should_umount(new_uid.val)) { return 0; } else { @@ -629,10 +1159,12 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) #endif } +#ifndef CONFIG_KSU_SUSFS // 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 = ksu_is_zygote(old->security); +#endif if (!is_zygote_child) { pr_info("handle umount ignore non zygote child: %d\n", current->pid); @@ -644,25 +1176,31 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old) current->pid); #endif +#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT +out_susfs_try_umount_all: + // susfs come first, and lastly umount by ksu, make sure umount in reversed order + susfs_try_umount_all(new_uid.val); +#else // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and // filter the mountpoint whose target is `/data/adb` - try_umount("/odm", true, 0); - try_umount("/system", true, 0); - try_umount("/system_ext", true, 0); - try_umount("/vendor", true, 0); - try_umount("/product", true, 0); - try_umount("/data/adb/modules", false, MNT_DETACH); + ksu_try_umount("/odm", true, 0); + ksu_try_umount("/system", true, 0); + ksu_try_umount("/system_ext", true, 0); + ksu_try_umount("/vendor", true, 0); + ksu_try_umount("/product", true, 0); + ksu_try_umount("/data/adb/modules", false, MNT_DETACH); // try umount ksu temp path - try_umount("/debug_ramdisk", false, MNT_DETACH); - try_umount("/sbin", false, MNT_DETACH); + ksu_try_umount("/debug_ramdisk", false, MNT_DETACH); + ksu_try_umount("/sbin", false, MNT_DETACH); // try umount hosts file - try_umount("/system/etc/hosts", false, MNT_DETACH); + ksu_try_umount("/system/etc/hosts", false, MNT_DETACH); // try umount lsposed dex2oat bins - try_umount("/apex/com.android.art/bin/dex2oat64", false, MNT_DETACH); - try_umount("/apex/com.android.art/bin/dex2oat32", false, MNT_DETACH); + ksu_try_umount("/apex/com.android.art/bin/dex2oat64", false, MNT_DETACH); + ksu_try_umount("/apex/com.android.art/bin/dex2oat32", false, MNT_DETACH); +#endif return 0; } diff --git a/kernel/kernel_compat.c b/kernel/kernel_compat.c index db47f8eb..267d150c 100644 --- a/kernel/kernel_compat.c +++ b/kernel/kernel_compat.c @@ -76,6 +76,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) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) @@ -174,15 +184,6 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, } #endif -static inline int ksu_access_ok(const void *addr, unsigned long size) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) - return access_ok(addr, size); -#else - return access_ok(VERIFY_READ, addr, size); -#endif -} - long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr, long count) { diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index c85e9e2c..cad307a0 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -32,6 +32,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, diff --git a/kernel/ksu.c b/kernel/ksu.c index 11864141..a8a02c2f 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -11,6 +11,10 @@ #include "ksu.h" #include "throne_tracker.h" +#ifdef CONFIG_KSU_SUSFS +#include +#endif + static struct workqueue_struct *ksu_workqueue; bool ksu_queue_work(struct work_struct *work) @@ -37,7 +41,7 @@ extern void ksu_sucompat_exit(); extern void ksu_ksud_init(); extern void ksu_ksud_exit(); -int __init kernelsu_init(void) +int __init ksu_kernelsu_init(void) { #ifdef CONFIG_KSU_DEBUG pr_alert("*************************************************************"); @@ -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); @@ -72,7 +80,7 @@ int __init kernelsu_init(void) return 0; } -void kernelsu_exit(void) +void ksu_kernelsu_exit(void) { ksu_allowlist_exit(); @@ -88,8 +96,8 @@ void kernelsu_exit(void) ksu_core_exit(); } -module_init(kernelsu_init); -module_exit(kernelsu_exit); +module_init(ksu_kernelsu_init); +module_exit(ksu_kernelsu_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("weishu"); diff --git a/kernel/ksud.c b/kernel/ksud.c index 2543239d..adb2e0d4 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -64,6 +64,9 @@ bool ksu_vfs_read_hook __read_mostly = true; bool ksu_execveat_hook __read_mostly = true; bool ksu_input_hook __read_mostly = true; +#ifdef CONFIG_KSU_SUSFS_SUS_SU +bool susfs_is_sus_su_ready = false; +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU u32 ksu_devpts_sid; @@ -71,15 +74,15 @@ u32 ksu_devpts_sid; bool ksu_is_compat __read_mostly = false; #endif -void on_post_fs_data(void) +void ksu_on_post_fs_data(void) { static bool done = false; if (done) { - pr_info("on_post_fs_data already done\n"); + pr_info("ksu_on_post_fs_data already done\n"); return; } done = true; - pr_info("on_post_fs_data!\n"); + pr_info("ksu_on_post_fs_data!\n"); ksu_load_allow_list(); // sanity check, this may influence the performance stop_input_hook(); @@ -203,7 +206,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, first_arg); if (!strcmp(first_arg, "second_stage")) { pr_info("/system/bin/init second_stage executed\n"); - apply_kernelsu_rules(); + ksu_apply_kernelsu_rules(); init_second_stage_executed = true; ksu_android_ns_fs_check(); } @@ -227,7 +230,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, pr_info("/init first arg: %s\n", first_arg); if (!strcmp(first_arg, "--second-stage")) { pr_info("/init second_stage executed\n"); - apply_kernelsu_rules(); + ksu_apply_kernelsu_rules(); init_second_stage_executed = true; ksu_android_ns_fs_check(); } @@ -264,7 +267,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { pr_info("/init second_stage executed\n"); - apply_kernelsu_rules(); + ksu_apply_kernelsu_rules(); init_second_stage_executed = true; ksu_android_ns_fs_check(); @@ -279,7 +282,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, first_app_process = false; pr_info("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); - on_post_fs_data(); // we keep this for old ksud + ksu_on_post_fs_data(); // we keep this for old ksud stop_execve_hook(); } @@ -677,6 +680,10 @@ static void stop_execve_hook() ksu_execveat_hook = false; pr_info("stop execve_hook\n"); #endif +#ifdef CONFIG_KSU_SUSFS_SUS_SU + susfs_is_sus_su_ready = true; + pr_info("susfs: sus_su is ready\n"); +#endif } static void stop_input_hook() diff --git a/kernel/ksud.h b/kernel/ksud.h index cc2df243..26974c9c 100644 --- a/kernel/ksud.h +++ b/kernel/ksud.h @@ -5,7 +5,7 @@ #define KSUD_PATH "/data/adb/ksud" -void on_post_fs_data(void); +void ksu_on_post_fs_data(void); bool ksu_is_safe_mode(void); diff --git a/kernel/manager.h b/kernel/manager.h index be5bbced..93fa2678 100644 --- a/kernel/manager.h +++ b/kernel/manager.h @@ -13,7 +13,7 @@ static inline bool ksu_is_manager_uid_valid() return ksu_manager_uid != KSU_INVALID_UID; } -static inline bool is_manager() +static inline bool ksu_is_manager() { return unlikely(ksu_manager_uid == current_uid().val); } diff --git a/kernel/selinux/rules.c b/kernel/selinux/rules.c index 38390b37..5d832686 100644 --- a/kernel/selinux/rules.c +++ b/kernel/selinux/rules.c @@ -38,11 +38,11 @@ static struct policydb *get_policydb(void) static DEFINE_MUTEX(ksu_rules); -void apply_kernelsu_rules() +void ksu_apply_kernelsu_rules() { struct policydb *db; - if (!getenforce()) { + if (!ksu_getenforce()) { pr_info("SELinux permissive or disabled, apply rules!\n"); } @@ -139,6 +139,14 @@ 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"); + susfs_set_init_sid(); + susfs_set_ksu_sid(); + susfs_set_zygote_sid(); +#endif + mutex_unlock(&ksu_rules); } @@ -228,13 +236,13 @@ static void reset_avc_cache() selinux_xfrm_notify_policyload(); } -int handle_sepolicy(unsigned long arg3, void __user *arg4) +int ksu_handle_sepolicy(unsigned long arg3, void __user *arg4) { if (!arg4) { return -1; } - if (!getenforce()) { + if (!ksu_getenforce()) { pr_info("SELinux permissive or disabled when handle policy!\n"); } diff --git a/kernel/selinux/selinux.c b/kernel/selinux/selinux.c index 4ba20b04..e171e010 100644 --- a/kernel/selinux/selinux.c +++ b/kernel/selinux/selinux.c @@ -8,6 +8,14 @@ #define KERNEL_SU_DOMAIN "u:r:su:s0" +#ifdef CONFIG_KSU_SUSFS +#define KERNEL_INIT_DOMAIN "u:r:init:s0" +#define KERNEL_ZYGOTE_DOMAIN "u:r:zygote:s0" +u32 susfs_ksu_sid = 0; +u32 susfs_init_sid = 0; +u32 susfs_zygote_sid = 0; +#endif + static int transive_to_domain(const char *domain) { struct cred *cred; @@ -37,7 +45,7 @@ static int transive_to_domain(const char *domain) return error; } -void setup_selinux(const char *domain) +void ksu_setup_selinux(const char *domain) { if (transive_to_domain(domain)) { pr_err("transive domain failed.\n"); @@ -52,7 +60,7 @@ if (!is_domain_permissive) { }*/ } -void setenforce(bool enforce) +void ksu_setenforce(bool enforce) { #ifdef CONFIG_SECURITY_SELINUX_DEVELOP #ifdef KSU_COMPAT_USE_SELINUX_STATE @@ -63,7 +71,7 @@ void setenforce(bool enforce) #endif } -bool getenforce() +bool ksu_getenforce() { #ifdef CONFIG_SECURITY_SELINUX_DISABLE #ifdef KSU_COMPAT_USE_SELINUX_STATE @@ -99,7 +107,7 @@ static inline u32 current_sid(void) } #endif -bool is_ksu_domain() +bool ksu_is_ksu_domain() { char *domain; u32 seclen; @@ -113,7 +121,7 @@ bool is_ksu_domain() return result; } -bool is_zygote(void *sec) +bool ksu_is_zygote(void *sec) { struct task_security_struct *tsec = (struct task_security_struct *)sec; if (!tsec) { @@ -131,6 +139,83 @@ bool is_zygote(void *sec) return result; } +#ifdef CONFIG_KSU_SUSFS +static inline void susfs_set_sid(const char *secctx_name, u32 *out_sid) +{ + int err; + + if (!secctx_name || !out_sid) { + pr_err("secctx_name || out_sid is NULL\n"); + return; + } + + err = security_secctx_to_secid(secctx_name, strlen(secctx_name), + out_sid); + if (err) { + pr_err("failed setting sid for '%s', err: %d\n", secctx_name, err); + return; + } + pr_info("sid '%u' is set for secctx_name '%s'\n", *out_sid, secctx_name); +} + +bool susfs_is_sid_equal(void *sec, u32 sid2) { + struct task_security_struct *tsec = (struct task_security_struct *)sec; + if (!tsec) { + return false; + } + return tsec->sid == sid2; +} + +u32 susfs_get_sid_from_name(const char *secctx_name) +{ + u32 out_sid = 0; + int err; + + if (!secctx_name) { + pr_err("secctx_name is NULL\n"); + return 0; + } + err = security_secctx_to_secid(secctx_name, strlen(secctx_name), + &out_sid); + if (err) { + pr_err("failed getting sid from secctx_name: %s, err: %d\n", secctx_name, err); + return 0; + } + return out_sid; +} + +u32 susfs_get_current_sid(void) { + return current_sid(); +} + +void susfs_set_zygote_sid(void) +{ + susfs_set_sid(KERNEL_ZYGOTE_DOMAIN, &susfs_zygote_sid); +} + +bool susfs_is_current_zygote_domain(void) { + return unlikely(current_sid() == susfs_zygote_sid); +} + +void susfs_set_ksu_sid(void) +{ + susfs_set_sid(KERNEL_SU_DOMAIN, &susfs_ksu_sid); +} + +bool susfs_is_current_ksu_domain(void) { + return unlikely(current_sid() == susfs_ksu_sid); +} + +void susfs_set_init_sid(void) +{ + susfs_set_sid(KERNEL_INIT_DOMAIN, &susfs_init_sid); +} + +bool susfs_is_current_init_domain(void) { + return unlikely(current_sid() == susfs_init_sid); +} +#endif + #define DEVPTS_DOMAIN "u:object_r:ksu_file:s0" u32 ksu_get_devpts_sid() diff --git a/kernel/selinux/selinux.h b/kernel/selinux/selinux.h index 07120c25..d0dfdf9c 100644 --- a/kernel/selinux/selinux.h +++ b/kernel/selinux/selinux.h @@ -8,17 +8,29 @@ #define KSU_COMPAT_USE_SELINUX_STATE #endif -void setup_selinux(const char *); +void ksu_setup_selinux(const char *); -void setenforce(bool); +void ksu_setenforce(bool); -bool getenforce(); +bool ksu_getenforce(); -bool is_ksu_domain(); +bool ksu_is_ksu_domain(); -bool is_zygote(void *cred); +bool ksu_is_zygote(void *cred); -void apply_kernelsu_rules(); +void ksu_apply_kernelsu_rules(); + +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +bool susfs_is_sid_equal(void *sec, u32 sid2); +u32 susfs_get_sid_from_name(const char *secctx_name); +u32 susfs_get_current_sid(void); +void susfs_set_zygote_sid(void); +bool susfs_is_current_zygote_domain(void); +void susfs_set_ksu_sid(void); +bool susfs_is_current_ksu_domain(void); +void susfs_set_init_sid(void); +bool susfs_is_current_init_domain(void); +#endif u32 ksu_get_devpts_sid(); diff --git a/kernel/setup.sh b/kernel/setup.sh index aadc1adb..cac376d5 100755 --- a/kernel/setup.sh +++ b/kernel/setup.sh @@ -43,7 +43,7 @@ setup_kernelsu() { cd "$GKI_ROOT/KernelSU-Next" git stash && echo "[-] Stashed current changes." if [ "$(git status | grep -Po 'v\d+(\.\d+)*' | head -n1)" ]; then - git checkout next && echo "[-] Switched to next branch." + git checkout next-susfs-a13-5.15-dev && echo "[-] Switched to next-susfs-a13-5.15-dev branch." fi git pull && echo "[+] Repository updated." if [ -z "${1-}" ]; then diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 11b2a551..35847bed 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -13,6 +13,9 @@ #else #include #endif +#ifdef CONFIG_KSU_SUSFS_SUS_SU +#include +#endif #include "objsec.h" #include "allowlist.h" @@ -28,9 +31,13 @@ static bool ksu_sucompat_non_kp __read_mostly = true; #endif -extern void escape_to_root(); +extern void ksu_escape_to_root(); -static void __user *userspace_stack_buffer(const void *d, size_t len) +static const char sh_path[] = "/system/bin/sh"; +static const char ksud_path[] = KSUD_PATH; +static const char su[] = SU_PATH; + +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 * pointer. */ @@ -39,37 +46,37 @@ static void __user *userspace_stack_buffer(const void *d, size_t len) return copy_to_user(p, d, len) ? NULL : p; } -static char __user *sh_user_path(void) +static inline char __user *sh_user_path(void) { - static const char sh_path[] = "/system/bin/sh"; - return userspace_stack_buffer(sh_path, sizeof(sh_path)); } -static char __user *ksud_user_path(void) +static inline char __user *ksud_user_path(void) { - static const char ksud_path[] = KSUD_PATH; - return userspace_stack_buffer(ksud_path, sizeof(ksud_path)); } int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int *__unused_flags) { - const char su[] = SU_PATH; - #ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_non_kp) { return 0; } #endif - if (!ksu_is_allow_uid(current_uid().val)) { - return 0; - } +#ifndef CONFIG_KSU_SUSFS_SUS_SU + if (!ksu_is_allow_uid(current_uid().val)) { + return 0; + } +#endif +#ifdef CONFIG_KSU_SUSFS_SUS_SU + char path[sizeof(su)] = {0}; +#else char path[sizeof(su) + 1]; memset(path, 0, sizeof(path)); +#endif ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path)); if (unlikely(!memcmp(path, su, sizeof(su)))) { @@ -80,27 +87,49 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) && defined(CONFIG_KSU_SUSFS_SUS_SU) +struct filename* susfs_ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) { + struct filename *name = getname_flags(*filename_user, getname_statx_lookup_flags(*flags), NULL); + + if (unlikely(IS_ERR(name) || name->name == NULL)) { + return name; + } + + if (likely(memcmp(name->name, su, sizeof(su)))) { + return name; + } + + const char sh[] = SH_PATH; + pr_info("vfs_fstatat su->sh!\n"); + memcpy((void *)name->name, sh, sizeof(sh)); + return name; +} +#endif + int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) { - // const char sh[] = SH_PATH; - const char su[] = SU_PATH; - #ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_non_kp){ return 0; } #endif +#ifndef CONFIG_KSU_SUSFS_SUS_SU if (!ksu_is_allow_uid(current_uid().val)) { return 0; } +#endif if (unlikely(!filename_user)) { return 0; } +#ifdef CONFIG_KSU_SUSFS_SUS_SU + char path[sizeof(su)] = {0}; +#else char path[sizeof(su) + 1]; memset(path, 0, sizeof(path)); +#endif // Remove this later!! we use syscall hook, so this will never happen!!!!! #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) && 0 // it becomes a `struct filename *` after 5.18 @@ -132,8 +161,6 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, int *__never_use_flags) { struct filename *filename; - const char sh[] = KSUD_PATH; - const char su[] = SU_PATH; #ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_non_kp) { @@ -152,13 +179,15 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, if (likely(memcmp(filename->name, su, sizeof(su)))) return 0; +#ifndef CONFIG_KSU_SUSFS_SUS_SU if (!ksu_is_allow_uid(current_uid().val)) return 0; +#endif pr_info("do_execveat_common su found\n"); - memcpy((void *)filename->name, sh, sizeof(sh)); + memcpy((void *)filename->name, ksud_path, sizeof(ksud_path)); - escape_to_root(); + ksu_escape_to_root(); return 0; } @@ -167,8 +196,11 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, void *__never_use_argv, void *__never_use_envp, int *__never_use_flags) { - const char su[] = SU_PATH; +#ifdef CONFIG_KSU_SUSFS_SUS_SU + char path[sizeof(su)] = {0}; +#else char path[sizeof(su) + 1]; +#endif #ifndef CONFIG_KSU_KPROBES_HOOK if (!ksu_sucompat_non_kp) { @@ -206,7 +238,7 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, pr_info("sys_execve su found\n"); *filename_user = ksud_user_path(); - escape_to_root(); + ksu_escape_to_root(); return 0; } @@ -352,3 +384,41 @@ void ksu_sucompat_exit() pr_info("ksu_sucompat_exit: hooks disabled: execve/execveat_su, faccessat, stat, devpts\n"); #endif } + +#ifdef CONFIG_KSU_SUSFS_SUS_SU +extern bool ksu_su_compat_enabled; +bool ksu_devpts_hook = false; +bool susfs_is_sus_su_hooks_enabled __read_mostly = false; +int susfs_sus_su_working_mode = 0; + +static bool ksu_is_su_kps_enabled(void) { + for (int i = 0; i < ARRAY_SIZE(su_kps); i++) { + if (su_kps[i]) { + return true; + } + } + return false; +} + +void ksu_susfs_disable_sus_su(void) { + susfs_is_sus_su_hooks_enabled = false; + ksu_devpts_hook = false; + susfs_sus_su_working_mode = SUS_SU_DISABLED; + // Re-enable the su_kps for user, users need to toggle off the kprobe hooks again in ksu manager if they want it disabled. + if (!ksu_is_su_kps_enabled()) { + ksu_sucompat_init(); + ksu_su_compat_enabled = true; + } +} + +void ksu_susfs_enable_sus_su(void) { + if (ksu_is_su_kps_enabled()) { + ksu_sucompat_exit(); + ksu_su_compat_enabled = false; + } + susfs_is_sus_su_hooks_enabled = true; + ksu_devpts_hook = true; + susfs_sus_su_working_mode = SUS_SU_WITH_HOOKS; +} +#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU + diff --git a/kernel/throne_tracker.c b/kernel/throne_tracker.c index dc1f7ee7..bfd33717 100644 --- a/kernel/throne_tracker.c +++ b/kernel/throne_tracker.c @@ -192,7 +192,7 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, } } - bool is_manager = is_manager_apk(dirpath); + bool is_manager = ksu_is_manager_apk(dirpath); pr_info("Found new base.apk at path: %s, is_manager: %d\n", dirpath, is_manager); if (is_manager) { @@ -351,7 +351,7 @@ static bool is_uid_exist(uid_t uid, char *package, void *data) return exist; } -void track_throne() +void ksu_track_throne() { struct file *fp; int tries = 0; diff --git a/kernel/throne_tracker.h b/kernel/throne_tracker.h index f33e4cb9..98bb9d59 100644 --- a/kernel/throne_tracker.h +++ b/kernel/throne_tracker.h @@ -5,7 +5,7 @@ void ksu_throne_tracker_init(); void ksu_throne_tracker_exit(); -void track_throne(); +void ksu_track_throne(); bool is_lock_held(const char *path);