Skip to content

Commit

Permalink
kernel: Implement SUSFS 1.5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
changhuapeng committed Dec 13, 2024
1 parent 833cdf6 commit 9360172
Show file tree
Hide file tree
Showing 11 changed files with 651 additions and 4 deletions.
140 changes: 140 additions & 0 deletions kernel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,144 @@ config KSU_DEBUG
help
Enable KernelSU debug mode.

menu "KernelSU - SUSFS"
config KSU_SUSFS
bool "KernelSU addon - SUSFS"
depends on KSU
default y
help
Patch and Enable SUSFS to kernel with KernelSU.

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.
- tmpfs filesystem is not allowed to be added.
- Effective on process with uid > 2000 only.
- 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 on all processes.

config KSU_SUSFS_SUS_OVERLAYFS
bool "Enable to automatically spoof kstat and kstatfs for overlayed files/directories"
depends on KSU_SUSFS
default y
help
- Automatically spoof the kstat and kstatfs for overlayed files/directories.
- No susfs command is needed in userspace.
- Effective on all processes.

config KSU_SUSFS_TRY_UMOUNT
bool "Enable to use ksu's try_umount"
depends on KSU_SUSFS
default y
help
- Allow using ksu's 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 try_umount automatically (experimental)"
depends on KSU_SUSFS_TRY_UMOUNT
default y
help
- Automatically add binded mounts to ksu's 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_PROC_CMDLINE
bool "Enable to spoof /proc/cmdline"
depends on KSU_SUSFS
default y
help
- Spoof the output of /proc/cmdline 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 modes for sus_su.
- Mode 1: when enabling sus_su, ksu kprobes will be disabled, and a fifo driver will be created in
/dev/[random_string] (for first time only), then user needs to mount the 'sus_su' to /system/bin/su using overlayfs or whatever
techniques, and run 'su' to get root shell from the fifo driver. Or, refer to the method in service.sh from module template.
** sus_su userspace tool and an overlay mount is required **
- Mode 2: When enabling sus_su, ksu kprobes will be disabled, and the kernel inline hooks will be enabled,
just same as the su implementaion of non-gki kernel without kprobe supported.
** Needs no extra userspace tools and mounts **
- When disabling sus_su, ksu kprobes will be enabled again, and the fifo driver will be deleted.
- Only apps with root access granted by ksu manager are allowed to get root.
- Also overlayfs is required.

endmenu

endmenu
104 changes: 100 additions & 4 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,110 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"

ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
#ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
#ccflags-y += -DKSU_UMOUNT
#else
#$(info -- Did you know you can backport path_umount to fs/namespace.c from 5.9?)
#$(info -- Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)
#endif

ccflags-y += -DKSU_UMOUNT
else
$(info -- Did you know you can backport path_umount to fs/namespace.c from 5.9?)
$(info -- Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)

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

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)
ifdef KSU_SUSFS
ccflags-y += -DKSU_SUSFS
endif
ifdef KSU_SUSFS_SUS_PATH
ccflags-y += -DKSU_SUSFS_SUS_PATH
endif
ifdef KSU_SUSFS_SUS_MOUNT
ccflags-y += -DKSU_SUSFS_SUS_MOUNT
endif
ifdef KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
ccflags-y += -DKSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
endif
ifdef KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
ccflags-y += -DKSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
endif
ifdef KSU_SUSFS_SUS_KSTAT
ccflags-y += -DKSU_SUSFS_SUS_KSTAT
endif
ifdef KSU_SUSFS_SUS_OVERLAYFS
ccflags-y += -DKSU_SUSFS_SUS_OVERLAYFS
endif
ifdef KSU_SUSFS_TRY_UMOUNT
ccflags-y += -DKSU_SUSFS_TRY_UMOUNT
endif
ifdef KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
ccflags-y += -DKSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
endif
ifdef KSU_SUSFS_SPOOF_UNAME
ccflags-y += -DKSU_SUSFS_SPOOF_UNAME
endif
ifdef KSU_SUSFS_ENABLE_LOG
ccflags-y += -DKSU_SUSFS_ENABLE_LOG
endif
ifdef KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS
ccflags-y += -DKSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS
endif
ifdef KSU_SUSFS_SPOOF_PROC_CMDLINE
ccflags-y += -DKSU_SUSFS_SPOOF_PROC_CMDLINE
endif
ifdef KSU_SUSFS_OPEN_REDIRECT
ccflags-y += -DKSU_SUSFS_OPEN_REDIRECT
endif
ifdef KSU_SUSFS_SUS_SU
ccflags-y += -DKSU_SUSFS_SUS_SU
endif
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
Loading

0 comments on commit 9360172

Please sign in to comment.