From f37092e2f0d546981c1438fe06a542b83bee10a6 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Sun, 3 Aug 2025 23:19:35 +0800 Subject: [PATCH] kernel: increase reliability, add ksu_access_ok to simplify Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com> Signed-off-by: rsuntk --- kernel/kernel_compat.c | 18 +++++++++--------- kernel/kernel_compat.h | 3 +-- kernel/ksud.c | 8 ++++++-- kernel/sucompat.c | 8 ++------ 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/kernel/kernel_compat.c b/kernel/kernel_compat.c index 46772c66..50d0feb1 100644 --- a/kernel/kernel_compat.c +++ b/kernel/kernel_compat.c @@ -79,15 +79,6 @@ 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) { @@ -188,3 +179,12 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, return ret; } #endif + +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 +} diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index 36501246..1a80a3ea 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -58,12 +58,11 @@ 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, loff_t *pos); extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos); - +extern int ksu_access_ok(const void *addr, unsigned long size); #endif diff --git a/kernel/ksud.c b/kernel/ksud.c index 9e91117b..cdf5583b 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -586,6 +586,7 @@ static int ksu_execve_ksud_common(const char __user *filename_user, { struct filename filename_in, *filename_p; char path[32]; + long len; // return early if disabled. if (!ksu_execveat_hook) { @@ -595,8 +596,11 @@ static int ksu_execve_ksud_common(const char __user *filename_user, if (!filename_user) return 0; - memset(path, 0, sizeof(path)); - ksu_strncpy_from_user_nofault(path, filename_user, 32); + len = ksu_strncpy_from_user_nofault(path, filename_user, 32); + if (len <= 0) + return 0; + + path[sizeof(path) - 1] = '\0'; // this is because ksu_handle_execveat_ksud calls it filename->name filename_in.name = path; diff --git a/kernel/sucompat.c b/kernel/sucompat.c index df204589..28a73b52 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -218,13 +218,9 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user, * some cpus dont really have that good speculative execution * access_ok to substitute set_fs, we check if pointer is accessible */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) - if (!access_ok(VERIFY_READ, *filename_user, sizeof(path))) + if (!ksu_access_ok((const void *)filename_user, sizeof(path))) return 0; -#else - if (!access_ok(*filename_user, sizeof(path))) - return 0; -#endif + // success = returns number of bytes and should be less than path long len = strncpy_from_user(path, *filename_user, sizeof(path)); if (len <= 0 || len > sizeof(path))