From c228c23ae4cc0d9f91638229f351499734c387a3 Mon Sep 17 00:00:00 2001 From: hamjin Date: Sun, 22 Sep 2024 03:21:57 +0800 Subject: [PATCH] kernel: Fix compatibility with old and 32bit programs In v0.9.3 and v0.9.4, we replaced `vfs_statx` and `do_execveat_common` with syscall hooks. But we missed `fstatat64` and `compat_execve` and break compatibility with old and 32bit programs. In NetHunter Terminal compat_execve is directly called, but `fstatat64` is called before it in JuiceSSH bash-4.2. So add these two hooks back to fix them. Signed-off-by: hamjin --- kernel/arch.h | 4 ++++ kernel/sucompat.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/kernel/arch.h b/kernel/arch.h index eec38c289e71..c68d2095ffd9 100644 --- a/kernel/arch.h +++ b/kernel/arch.h @@ -21,8 +21,10 @@ #define PRCTL_SYMBOL "__arm64_sys_prctl" #define SYS_READ_SYMBOL "__arm64_sys_read" #define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat" +#define SYS_FSTATAT64_SYMBOL "__arm64_sys_fstatat64" #define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat" #define SYS_EXECVE_SYMBOL "__arm64_sys_execve" +#define SYS_EXECVE_COMPAT_SYMBOL "__arm64_compat_sys_execve" #elif defined(__x86_64__) @@ -42,8 +44,10 @@ #define PRCTL_SYMBOL "__x64_sys_prctl" #define SYS_READ_SYMBOL "__x64_sys_read" #define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat" +#define SYS_FSTATAT64_SYMBOL "__x64_sys_fstatat64" #define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat" #define SYS_EXECVE_SYMBOL "__x64_sys_execve" +#define SYS_EXECVE_COMPAT_SYMBOL "__x64_compat_sys_execve" #else #error "Unsupported arch" diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 966cbf8fa854..51429bea0110 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -232,11 +232,21 @@ static struct kprobe newfstatat_kp = { .pre_handler = sys_newfstatat_handler_pre, }; +static struct kprobe fstatat64_kp = { + .symbol_name = SYS_FSTATAT64_SYMBOL, + .pre_handler = sys_newfstatat_handler_pre, +}; + static struct kprobe execve_kp = { .symbol_name = SYS_EXECVE_SYMBOL, .pre_handler = sys_execve_handler_pre, }; +static struct kprobe execve_compat_kp = { + .symbol_name = SYS_EXECVE_COMPAT_SYMBOL, + .pre_handler = sys_execve_handler_pre, +}; + static int pts_unix98_lookup_pre(struct kprobe *p, struct pt_regs *regs) { struct inode *inode; @@ -260,8 +270,12 @@ void ksu_sucompat_init() int ret; ret = register_kprobe(&execve_kp); pr_info("sucompat: execve_kp: %d\n", ret); + ret = register_kprobe(&execve_compat_kp); + pr_info("sucompat: execve_compat_kp: %d\n", ret); ret = register_kprobe(&newfstatat_kp); pr_info("sucompat: newfstatat_kp: %d\n", ret); + ret = register_kprobe(&fstatat64_kp); + pr_info("sucompat: fstatat64_kp: %d\n", ret); ret = register_kprobe(&faccessat_kp); pr_info("sucompat: faccessat_kp: %d\n", ret); ret = register_kprobe(&pts_unix98_lookup_kp); @@ -273,7 +287,9 @@ void ksu_sucompat_exit() { #ifdef CONFIG_KPROBES unregister_kprobe(&execve_kp); + unregister_kprobe(&execve_compat_kp); unregister_kprobe(&newfstatat_kp); + unregister_kprobe(&fstatat64_kp); unregister_kprobe(&faccessat_kp); unregister_kprobe(&pts_unix98_lookup_kp); #endif