Distinguish different PT_REGS_PARM4 under x86 (#711)
1. `PT_REGS_CCALL_PARM4` 表示存放C调用约定的第4个参数的寄存器 2. `PT_REGS_SYSCALL_PARM4` 表示存放linux syscall调用约定的第4个参数的寄存器 3. 将原有 `PT_REGS_PARM4` 改为上述之一 4. 将原有 `ksu_handle_execveat_ksud` 和 `ksu_handle_execveat_sucompat` 可能被 kprobe 传递错误实参、且不使用的形参标记为 never_used 并传递 `NULL` 5. 为 `ksu_handle_execveat_ksud` 提供正确的 argv 参数用以在 x86 下也能正确识别 `init second_stage` --------- Co-authored-by: weishu <twsxtd@gmail.com>
This commit is contained in:
@@ -138,8 +138,9 @@ static int __maybe_unused count(struct user_arg_ptr argv, int max)
|
||||
return i;
|
||||
}
|
||||
|
||||
// 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_ksud(int *fd, struct filename **filename_ptr,
|
||||
void *argv, void *envp, int *flags)
|
||||
struct user_arg_ptr *argv, void *__never_use_envp, int *__never_use_flags)
|
||||
{
|
||||
#ifndef CONFIG_KPROBES
|
||||
if (!ksu_execveat_hook) {
|
||||
@@ -163,13 +164,11 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
|
||||
if (unlikely(!memcmp(filename->name, system_bin_init,
|
||||
sizeof(system_bin_init) - 1))) {
|
||||
#ifdef __aarch64__
|
||||
// /system/bin/init executed
|
||||
struct user_arg_ptr *ptr = (struct user_arg_ptr*) argv;
|
||||
int argc = count(*ptr, MAX_ARG_STRINGS);
|
||||
int argc = count(*argv, MAX_ARG_STRINGS);
|
||||
pr_info("/system/bin/init argc: %d\n", argc);
|
||||
if (argc > 1 && !init_second_stage_executed) {
|
||||
const char __user *p = get_user_arg_ptr(*ptr, 1);
|
||||
const char __user *p = get_user_arg_ptr(*argv, 1);
|
||||
if (p && !IS_ERR(p)) {
|
||||
char first_arg[16];
|
||||
ksu_strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
|
||||
@@ -184,20 +183,6 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
pr_err("/system/bin/init parse args err!\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
// The argument parse is incorrect becuase of the struct user_arg_ptr has 16bytes
|
||||
// and it is passed by value(not pointer), in arm64, it is correct becuase the register
|
||||
// is just arranged correct accidentally, but is not correct in x86_64
|
||||
// i have no device to test, so revert it for x86_64
|
||||
static int init_count = 0;
|
||||
if (++init_count == 2) {
|
||||
// 1: /system/bin/init selinux_setup
|
||||
// 2: /system/bin/init second_stage
|
||||
pr_info("/system/bin/init second_stage executed\n");
|
||||
apply_kernelsu_rules();
|
||||
ksu_android_ns_fs_check();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (unlikely(first_app_process &&
|
||||
@@ -394,11 +379,19 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
int *fd = (int *)&PT_REGS_PARM1(regs);
|
||||
struct filename **filename_ptr =
|
||||
(struct filename **)&PT_REGS_PARM2(regs);
|
||||
void *argv = (void *)&PT_REGS_PARM3(regs);
|
||||
void *envp = (void *)&PT_REGS_PARM4(regs);
|
||||
int *flags = (int *)&PT_REGS_PARM5(regs);
|
||||
struct user_arg_ptr argv;
|
||||
#ifdef CONFIG_COMPAT
|
||||
argv.is_compat = PT_REGS_PARM3(regs);
|
||||
if (unlikely(argv.is_compat)) {
|
||||
argv.ptr.compat = PT_REGS_CCALL_PARM4(regs);
|
||||
} else {
|
||||
argv.ptr.native = PT_REGS_CCALL_PARM4(regs);
|
||||
}
|
||||
#else
|
||||
argv.ptr.native = PT_REGS_PARM3(regs);
|
||||
#endif
|
||||
|
||||
return ksu_handle_execveat_ksud(fd, filename_ptr, argv, envp, flags);
|
||||
return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL);
|
||||
}
|
||||
|
||||
static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
@@ -406,7 +399,7 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
struct file **file_ptr = (struct file **)&PT_REGS_PARM1(regs);
|
||||
char __user **buf_ptr = (char **)&PT_REGS_PARM2(regs);
|
||||
size_t *count_ptr = (size_t *)&PT_REGS_PARM3(regs);
|
||||
loff_t **pos_ptr = (loff_t **)&PT_REGS_PARM4(regs);
|
||||
loff_t **pos_ptr = (loff_t **)&PT_REGS_CCALL_PARM4(regs);
|
||||
|
||||
return ksu_handle_vfs_read(file_ptr, buf_ptr, count_ptr, pos_ptr);
|
||||
}
|
||||
@@ -416,7 +409,7 @@ static int input_handle_event_handler_pre(struct kprobe *p,
|
||||
{
|
||||
unsigned int *type = (unsigned int *)&PT_REGS_PARM2(regs);
|
||||
unsigned int *code = (unsigned int *)&PT_REGS_PARM3(regs);
|
||||
int *value = (int *)&PT_REGS_PARM4(regs);
|
||||
int *value = (int *)&PT_REGS_CCALL_PARM4(regs);
|
||||
return ksu_handle_input_handle_event(type, code, value);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user