From f8ea36639f785302a744387017f37a498052ec6b Mon Sep 17 00:00:00 2001 From: backslashxx <118538522+backslashxx@users.noreply.github.com> Date: Sun, 18 May 2025 17:11:45 +0800 Subject: [PATCH] kernel: ksud: Use char filename instead of struct filename for < k3.14 struct filename isn't in do_execve in kernels older than kernel 3.14. Co-Authored-By: backslashxx <118538522+backslashxx@users.noreply.github.com> --- kernel/ksu.c | 6 ++++-- kernel/ksud.c | 30 +++++++++++++++++++++++++++++- kernel/sucompat.c | 2 ++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/kernel/ksu.c b/kernel/ksu.c index ff89d435..76d8f3a7 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -18,19 +18,21 @@ bool ksu_queue_work(struct work_struct *work) return queue_work(ksu_workqueue, work); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); extern int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, - void *argv, void *envp, int *flags); + void *argv, void *envp, int *flags); int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags) { ksu_handle_execveat_ksud(fd, filename_ptr, argv, envp, flags); return ksu_handle_execveat_sucompat(fd, filename_ptr, argv, envp, - flags); + flags); } +#endif extern void ksu_sucompat_init(); extern void ksu_sucompat_exit(); diff --git a/kernel/ksud.c b/kernel/ksud.c index 24a81cbb..f90748d7 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -159,16 +159,22 @@ static int __maybe_unused count(struct user_arg_ptr argv, int max) } // IMPORTANT NOTE: the call from execve_handler_pre WON'T provided correct value for envp and flags in GKI version +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, +#else +int ksu_handle_execveat_ksud(int *fd, char *filename, +#endif struct user_arg_ptr *argv, struct user_arg_ptr *envp, int *flags) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) #ifndef CONFIG_KSU_WITH_KPROBES if (!ksu_execveat_hook) { return 0; } #endif struct filename *filename; +#endif static const char app_process[] = "/system/bin/app_process"; static bool first_app_process = true; @@ -179,15 +185,23 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, static const char old_system_init[] = "/init"; static bool init_second_stage_executed = false; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (!filename_ptr) +#else + if (!filename) +#endif return 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) filename = *filename_ptr; if (IS_ERR(filename)) { return 0; } if (unlikely(!memcmp(filename->name, system_bin_init, +#else + if (unlikely(!memcmp(filename, system_bin_init, +#endif sizeof(system_bin_init) - 1) && argv)) { // /system/bin/init executed @@ -211,7 +225,11 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, pr_err("/system/bin/init parse args err!\n"); } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) } else if (unlikely(!memcmp(filename->name, old_system_init, +#else + } else if (unlikely(!memcmp(filename, old_system_init, +#endif sizeof(old_system_init) - 1) && argv)) { // /init executed @@ -274,7 +292,11 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr, } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) if (unlikely(first_app_process && !memcmp(filename->name, app_process, +#else + if (unlikely(first_app_process && !memcmp(filename, app_process, +#endif sizeof(app_process) - 1))) { first_app_process = false; pr_info("exec app_process, /data prepared, second_stage: %d\n", @@ -483,7 +505,9 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user, const char __user *const __user *__argv) { struct user_arg_ptr argv = { .ptr.native = __argv }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) struct filename filename_in, *filename_p; +#endif char path[32]; // return early if disabled. @@ -497,11 +521,15 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user, memset(path, 0, sizeof(path)); ksu_strncpy_from_user_nofault(path, filename_user, 32); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) // this is because ksu_handle_execveat_ksud calls it filename->name filename_in.name = path; filename_p = &filename_in; - + return ksu_handle_execveat_ksud(AT_FDCWD, &filename_p, &argv, NULL, NULL); +#else + return ksu_handle_execveat_ksud(AT_FDCWD, path, &argv, NULL, NULL); +#endif } #ifdef CONFIG_KSU_WITH_KPROBES diff --git a/kernel/sucompat.c b/kernel/sucompat.c index d8c02641..a90d10b2 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -134,6 +134,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) // the call from execve_handler_pre won't provided correct value for __never_use_argument, use them after fix execve_handler_pre, keeping them for consistence for manually patched code int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void *__never_use_argv, void *__never_use_envp, @@ -174,6 +175,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, return 0; } +#endif int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, void *__never_use_argv, void *__never_use_envp,