You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
kernel: susfs 1.5.9 a13-5.15 patch
This commit is contained in:
+92
-22
@@ -13,6 +13,9 @@
|
||||
#else
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
#include <linux/susfs_def.h>
|
||||
#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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user