From e69c25d4b2269a63a4746edfe387cae15bbab82c Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Sun, 26 Jan 2025 08:46:38 -0300 Subject: [PATCH] update: susfs to 4a2aeafed0387550cd7e22bbd2566bcf2df58e8c This commit updates susfs in the kernel to the latest currently available by the time of this commit. --- fs/inode.c | 20 ---------- fs/namei.c | 4 -- fs/namespace.c | 88 +++++++++++++++++++++---------------------- fs/stat.c | 9 ++++- include/linux/mount.h | 4 +- include/linux/sched.h | 4 +- 6 files changed, 54 insertions(+), 75 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 5fc597847..e3eab6809 100755 --- a/fs/inode.c +++ b/fs/inode.c @@ -24,10 +24,6 @@ #include #include "internal.h" -#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT -extern bool susfs_is_current_ksu_domain(void); -#endif - /* * Inode locking rules: * @@ -1829,11 +1825,6 @@ int generic_update_time(struct inode *inode, struct timespec64 *time, int flags) int iflags = I_DIRTY_TIME; bool dirty = false; -#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT - if (susfs_is_current_ksu_domain()) { - return 0; - } -#endif if (flags & S_ATIME) inode->i_atime = *time; if (flags & S_VERSION) @@ -1859,11 +1850,6 @@ EXPORT_SYMBOL(generic_update_time); */ int inode_update_time(struct inode *inode, struct timespec64 *time, int flags) { -#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT - if (susfs_is_current_ksu_domain()) { - return 0; - } -#endif if (inode->i_op->update_time) return inode->i_op->update_time(inode, time, flags); return generic_update_time(inode, time, flags); @@ -1920,12 +1906,6 @@ void touch_atime(const struct path *path) struct inode *inode = d_inode(path->dentry); struct timespec64 now; -#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT - if (susfs_is_current_ksu_domain()) { - return; - } -#endif - if (!atime_needs_update(path, inode)) return; diff --git a/fs/namei.c b/fs/namei.c index d5ffab76a..6ba2c9019 100755 --- a/fs/namei.c +++ b/fs/namei.c @@ -43,10 +43,6 @@ #include #endif -#if defined(CONFIG_KSU_SUSFS_SUS_PATH) || defined(CONFIG_KSU_SUSFS_OPEN_REDIRECT) -#include -#endif - #ifdef CONFIG_FSCRYPT_SDP #include #endif diff --git a/fs/namespace.c b/fs/namespace.c index 7a3824e22..26a482544 100755 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -45,18 +45,25 @@ #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT extern bool susfs_is_current_ksu_domain(void); extern bool susfs_is_current_zygote_domain(void); -#define CL_SUSFS_COPY_MNT_NS 0x1000000 -#define DEFAULT_SUS_MNT_GROUP_ID 1000 + +static DEFINE_IDA(susfs_mnt_id_ida); +static DEFINE_IDA(susfs_mnt_group_ida); + +#define CL_ZYGOTE_COPY_MNT_NS BIT(24) /* used by copy_mnt_ns() */ +#define CL_COPY_MNT_NS BIT(25) /* used by copy_mnt_ns() */ #endif +#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT +extern void susfs_auto_add_sus_ksu_default_mount(const char __user *to_pathname); +bool susfs_is_auto_add_sus_ksu_default_mount_enabled = true; +#endif #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT extern int susfs_auto_add_sus_bind_mount(const char *pathname, struct path *path_target); +bool susfs_is_auto_add_sus_bind_mount_enabled = true; #endif #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT extern void susfs_auto_add_try_umount_for_bind_mount(struct path *path); -#endif -#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT -extern void susfs_auto_add_sus_ksu_default_mount(const char __user *to_pathname); +bool susfs_is_auto_add_try_umount_for_bind_mount_enabled = true; #endif /* Maximum number of mounts in a mount namespace */ @@ -215,24 +222,28 @@ static int mnt_alloc_id(struct mount *mnt) static void mnt_free_id(struct mount *mnt) { #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT - // If mnt->mnt.susfs_orig_mnt_id is not zero, it means mnt->mnt_id is spoofed, - // so here we return the original mnt_id for being freed. - if (unlikely(mnt->mnt.susfs_orig_mnt_id)) { - ida_free(&mnt_id_ida, mnt->mnt.susfs_orig_mnt_id); + // We should first check the 'mnt->mnt.susfs_mnt_id_backup', see if it is DEFAULT_SUS_MNT_ID_FOR_KSU_PROC_UNSHARE + // if so, these mnt_id were not assigned by mnt_alloc_id() so we don't need to free it. + if (unlikely(mnt->mnt.susfs_mnt_id_backup == DEFAULT_SUS_MNT_ID_FOR_KSU_PROC_UNSHARE)) { + return; + } + // Now we can check if its mnt_id is sus + if (unlikely(mnt->mnt_id >= DEFAULT_SUS_MNT_ID)) { + ida_free(&susfs_mnt_id_ida, mnt->mnt_id); + return; + } + // Lastly if 'mnt->mnt.susfs_mnt_id_backup' is not 0, then it contains a backup origin mnt_id + // so we free it in the original way + if (likely(mnt->mnt.susfs_mnt_id_backup)) { + // If mnt->mnt.susfs_mnt_id_backup is not zero, it means mnt->mnt_id is spoofed, + // so here we return the original mnt_id for being freed. + ida_free(&mnt_id_ida, mnt->mnt.susfs_mnt_id_backup); return; } #endif ida_free(&mnt_id_ida, mnt->mnt_id); } -#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT -static void susfs_mnt_alloc_group_id(struct mount *mnt) -{ - // Just assign the same default sus mount_group_id to mnt->mnt_group_id - mnt->mnt_group_id = DEFAULT_SUS_MNT_GROUP_ID; -} -#endif - /* * Allocate a new peer group ID */ @@ -250,7 +261,7 @@ static int mnt_alloc_group_id(struct mount *mnt) res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL); bypass_orig_flow: #else - int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL); + int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL); #endif if (res < 0) @@ -265,9 +276,10 @@ bypass_orig_flow: void mnt_release_group_id(struct mount *mnt) { #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT - // If mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID, it means 'mnt' is sus mount, - // here we don't need to free the mnt_group_id and just simply return and do nothing. - if (unlikely(mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID)) { + // If mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID, it means 'mnt' is also sus mount, + // then we free the mnt->mnt_group_id from susfs_mnt_group_ida + if (mnt->mnt_group_id >= DEFAULT_SUS_MNT_GROUP_ID) { + ida_free(&susfs_mnt_group_ida, mnt->mnt_group_id); mnt->mnt_group_id = 0; return; } @@ -1372,7 +1384,8 @@ bypass_orig_flow: mnt->mnt_parent = mnt; #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT - if (susfs_is_current_zygote_domain() && !(flag & CL_SUSFS_COPY_MNT_NS)) { + // If caller process is zygote and not doing unshare, so we just reorder the mnt_id + if (likely(is_current_zygote_domain) && !(flag & CL_ZYGOTE_COPY_MNT_NS)) { mnt->mnt.susfs_orig_mnt_id = mnt->mnt_id; mnt->mnt_id = current->susfs_last_fake_mnt_id++; } @@ -2481,17 +2494,6 @@ static int invent_group_ids(struct mount *mnt, bool recurse) { struct mount *p; -#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT - if (susfs_is_current_ksu_domain()) { - for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) { - if (!p->mnt_group_id && !IS_MNT_SHARED(p)) { - susfs_mnt_alloc_group_id(p); - } - } - return 0; - } -#endif - for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) { if (!p->mnt_group_id && !IS_MNT_SHARED(p)) { int err = mnt_alloc_group_id(p); @@ -3946,9 +3948,11 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, copy_flags |= CL_SHARED_TO_SLAVE; #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + // Always let clone_mnt() in copy_tree() know it is from copy_mnt_ns() + copy_flags |= CL_COPY_MNT_NS; if (is_zygote_pid) { - // Let clone_mnt() in copy_tree() know we only interested in function called by copy_mnt_ns() - copy_flags |= CL_SUSFS_COPY_MNT_NS; + // Let clone_mnt() in copy_tree() know copy_mnt_ns() is run by zygote process + copy_flags |= CL_ZYGOTE_COPY_MNT_NS; } #endif #ifdef CONFIG_KDP_NS @@ -4014,7 +4018,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, } #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT // current->susfs_last_fake_mnt_id -> to record last valid fake mnt_id to zygote pid - // q->mnt.susfs_orig_mnt_id -> original mnt_id + // q->mnt.susfs_mnt_id_backup -> original mnt_id // q->mnt_id -> will be modified to the fake mnt_id // Here We are only interested in processes of which original mnt namespace belongs to zygote @@ -4025,7 +4029,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, if (unlikely(q->mnt.mnt_root->d_inode->i_state & INODE_STATE_SUS_MOUNT)) { continue; } - q->mnt.susfs_orig_mnt_id = q->mnt_id; + q->mnt.susfs_mnt_id_backup = q->mnt_id; q->mnt_id = last_entry_mnt_id++; } } @@ -4106,13 +4110,6 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, goto out_data; ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options); -#if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT) && defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT) - // Just for the compatibility of Magic Mount KernelSU - if (!ret && susfs_is_current_ksu_domain()) { - susfs_auto_add_sus_ksu_default_mount(dir_name); - } -#endif - #if defined(CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT) && defined(CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT) // Just for the compatibility of Magic Mount KernelSU if (!ret && susfs_is_auto_add_sus_ksu_default_mount_enabled && susfs_is_current_ksu_domain()) { @@ -4325,7 +4322,8 @@ out_to: out_from: path_put(&from_path); #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT - if (!ret && susfs_is_current_ksu_domain()) { + // For Legacy KSU mount scheme + if (!ret && susfs_is_auto_add_sus_ksu_default_mount_enabled && susfs_is_current_ksu_domain()) { susfs_auto_add_sus_ksu_default_mount(to_pathname); } #endif diff --git a/fs/stat.c b/fs/stat.c index d22e63fa3..747873659 100755 --- a/fs/stat.c +++ b/fs/stat.c @@ -17,7 +17,7 @@ #include #include #include -#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT +#if defined(CONFIG_KSU_SUSFS_SUS_KSTAT) || defined(CONFIG_KSU_SUSFS_SUS_MOUNT) #include #endif @@ -47,7 +47,8 @@ extern void susfs_sus_ino_for_generic_fillattr(unsigned long ino, struct kstat * void generic_fillattr(struct inode *inode, struct kstat *stat) { #ifdef CONFIG_KSU_SUSFS_SUS_KSTAT - if (unlikely(inode->i_state & INODE_STATE_SUS_KSTAT)) { + if (likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC) && + unlikely(inode->i_state & INODE_STATE_SUS_KSTAT)) { susfs_sus_ino_for_generic_fillattr(inode->i_ino, stat); stat->mode = inode->i_mode; stat->rdev = inode->i_rdev; @@ -205,6 +206,10 @@ static int vfs_statx(int dfd, const char __user *filename, int flags, unsigned lookup_flags = 0; int error; +#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT + struct mount *mnt; +#endif + #ifdef CONFIG_KSU_SUSFS_SUS_SU if (susfs_is_sus_su_hooks_enabled) { ksu_handle_stat(&dfd, &filename, &flags); diff --git a/include/linux/mount.h b/include/linux/mount.h index 0dd1b1ff7..0230a699d 100755 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -77,8 +77,8 @@ struct vfsmount { ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); -#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT - ANDROID_KABI_USE(4, u64 susfs_orig_mnt_id); +#ifdef CONFIG_KSU_SUSFS + ANDROID_KABI_USE(4, u64 susfs_mnt_id_backup); #else ANDROID_KABI_RESERVE(4); #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 297886eed..f8407fa3b 100755 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1398,12 +1398,12 @@ struct task_struct { ANDROID_KABI_RESERVE(4); ANDROID_KABI_RESERVE(5); ANDROID_KABI_RESERVE(6); -#ifdef CONFIG_KSU_SUSFS_SUS_PATH +#ifdef CONFIG_KSU_SUSFS ANDROID_KABI_USE(7, u64 susfs_task_state); #else ANDROID_KABI_RESERVE(7); #endif -#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT +#ifdef CONFIG_KSU_SUSFS ANDROID_KABI_USE(8, u64 susfs_last_fake_mnt_id); #else ANDROID_KABI_RESERVE(8);