Skip to content

Commit 2027ac3

Browse files
authored
Hook syscalls and stable symbols (#1657)
1. Replace `do_execveat_common` with `sys_execve` and `sys_execveat` 2. Replace `input_handle_event` with `input_event` and `input_inject_event` Tested on android12-5.10-2024-04, android13-5.15-2024-04. android14-6.1-2024-04
1 parent c8dd0b0 commit 2027ac3

File tree

3 files changed

+104
-6
lines changed

3 files changed

+104
-6
lines changed

kernel/arch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
#define SYS_READ_SYMBOL "__arm64_sys_read"
2424
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
2525
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
26+
#define SYS_EXECVE_SYMBOL "__arm64_sys_execve"
2627
#else
2728
#define PRCTL_SYMBOL "sys_prctl"
2829
#define SYS_READ_SYMBOL "sys_read"
2930
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
3031
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
32+
#define SYS_EXECVE_SYMBOL "sys_execve"
3133
#endif
3234

3335
#elif defined(__x86_64__)
@@ -50,11 +52,13 @@
5052
#define SYS_READ_SYMBOL "__x64_sys_read"
5153
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
5254
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
55+
#define SYS_EXECVE_SYMBOL "__x64_sys_execve"
5356
#else
5457
#define PRCTL_SYMBOL "sys_prctl"
5558
#define SYS_READ_SYMBOL "sys_read"
5659
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
5760
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
61+
#define SYS_EXECVE_SYMBOL "sys_execve"
5862
#endif
5963

6064
#else

kernel/ksud.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
176176
return 0;
177177
}
178178

179-
if (unlikely(!memcmp(filename->name, system_bin_init,
179+
if (unlikely(!memcmp(filename->name, system_bin_init,
180180
sizeof(system_bin_init) - 1) && argv)) {
181181
// /system/bin/init executed
182182
int argc = count(*argv, MAX_ARG_STRINGS);
@@ -472,6 +472,32 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
472472
return ksu_handle_execveat_ksud(fd, filename_ptr, &argv, NULL, NULL);
473473
}
474474

475+
static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
476+
{
477+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
478+
struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs);
479+
#else
480+
struct pt_regs *real_regs = regs;
481+
#endif
482+
const char __user **filename_user = (const char **)&PT_REGS_PARM1(real_regs);
483+
const char __user *const __user *__argv =
484+
(const char __user *const __user *)PT_REGS_PARM2(real_regs);
485+
struct user_arg_ptr argv = { .ptr.native = __argv };
486+
struct filename filename_in, *filename_p;
487+
char path[32];
488+
489+
if (!filename_user)
490+
return 0;
491+
492+
memset(path, 0, sizeof(path));
493+
ksu_strncpy_from_user_nofault(path, *filename_user, 32);
494+
filename_in.name = path;
495+
496+
filename_p = &filename_in;
497+
return ksu_handle_execveat_ksud(AT_FDCWD, &filename_p, &argv, NULL,
498+
NULL);
499+
}
500+
475501
// remove this later!
476502
__maybe_unused static int vfs_read_handler_pre(struct kprobe *p, struct pt_regs *regs)
477503
{
@@ -506,6 +532,12 @@ static int input_handle_event_handler_pre(struct kprobe *p,
506532
return ksu_handle_input_handle_event(type, code, value);
507533
}
508534

535+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
536+
static struct kprobe execve_kp = {
537+
.symbol_name = SYS_EXECVE_SYMBOL,
538+
.pre_handler = sys_execve_handler_pre,
539+
};
540+
#else
509541
static struct kprobe execve_kp = {
510542
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
511543
.symbol_name = "do_execveat_common",
@@ -516,6 +548,7 @@ static struct kprobe execve_kp = {
516548
#endif
517549
.pre_handler = execve_handler_pre,
518550
};
551+
#endif
519552

520553
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
521554
static struct kprobe vfs_read_kp = {
@@ -529,11 +562,20 @@ static struct kprobe vfs_read_kp = {
529562
};
530563
#endif
531564

532-
static struct kprobe input_handle_event_kp = {
533-
.symbol_name = "input_handle_event",
565+
static struct kprobe input_event_kp = {
566+
.symbol_name = "input_event",
534567
.pre_handler = input_handle_event_handler_pre,
535568
};
536569

570+
static struct kprobe input_inject_event_kp = {
571+
.symbol_name = "input_inject_event",
572+
.pre_handler = input_handle_event_handler_pre,
573+
};
574+
575+
static struct kprobe *input_event_kps[] = {
576+
&input_event_kp, &input_inject_event_kp
577+
};
578+
537579
static void do_stop_vfs_read_hook(struct work_struct *work)
538580
{
539581
unregister_kprobe(&vfs_read_kp);
@@ -546,7 +588,7 @@ static void do_stop_execve_hook(struct work_struct *work)
546588

547589
static void do_stop_input_hook(struct work_struct *work)
548590
{
549-
unregister_kprobe(&input_handle_event_kp);
591+
unregister_kprobes(input_event_kps, 2);
550592
}
551593
#endif
552594

@@ -600,7 +642,7 @@ void ksu_ksud_init()
600642
ret = register_kprobe(&vfs_read_kp);
601643
pr_info("ksud: vfs_read_kp: %d\n", ret);
602644

603-
ret = register_kprobe(&input_handle_event_kp);
645+
ret = register_kprobes(input_event_kps, 2);
604646
pr_info("ksud: input_handle_event_kp: %d\n", ret);
605647

606648
INIT_WORK(&stop_vfs_read_work, do_stop_vfs_read_hook);
@@ -614,6 +656,6 @@ void ksu_ksud_exit() {
614656
unregister_kprobe(&execve_kp);
615657
// this should be done before unregister vfs_read_kp
616658
// unregister_kprobe(&vfs_read_kp);
617-
unregister_kprobe(&input_handle_event_kp);
659+
unregister_kprobes(input_event_kps, 2);
618660
#endif
619661
}

kernel/sucompat.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ static char __user *sh_user_path(void)
3939
return userspace_stack_buffer(sh_path, sizeof(sh_path));
4040
}
4141

42+
static char __user *ksud_user_path(void)
43+
{
44+
static const char ksud_path[] = KSUD_PATH;
45+
46+
return userspace_stack_buffer(ksud_path, sizeof(ksud_path));
47+
}
48+
4249
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
4350
int * __unused_flags)
4451
{
@@ -130,6 +137,32 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
130137
return 0;
131138
}
132139

140+
int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
141+
void *__never_use_argv, void *__never_use_envp, int *__never_use_flags)
142+
{
143+
const char su[] = SU_PATH;
144+
char path[sizeof(su) + 1];
145+
146+
if (unlikely(!filename_user))
147+
return 0;
148+
149+
memset(path, 0, sizeof(path));
150+
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
151+
152+
if (likely(memcmp(path, su, sizeof(su))))
153+
return 0;
154+
155+
if (!ksu_is_allow_uid(current_uid().val))
156+
return 0;
157+
158+
pr_info("sys_execve su found\n");
159+
*filename_user = ksud_user_path();
160+
161+
escape_to_root();
162+
163+
return 0;
164+
}
165+
133166
#ifdef CONFIG_KPROBES
134167

135168
__maybe_unused static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
@@ -196,6 +229,18 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
196229
return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL);
197230
}
198231

232+
static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
233+
{
234+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
235+
struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs);
236+
#else
237+
struct pt_regs *real_regs = regs;
238+
#endif
239+
const char __user **filename_user = (const char **)&PT_REGS_PARM1(real_regs);
240+
241+
return ksu_handle_execve_sucompat(AT_FDCWD, filename_user, NULL, NULL, NULL);
242+
}
243+
199244
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
200245
static struct kprobe faccessat_kp = {
201246
.symbol_name = SYS_FACCESSAT_SYMBOL,
@@ -228,6 +273,12 @@ static struct kprobe newfstatat_kp = {
228273
};
229274
#endif
230275

276+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
277+
static struct kprobe execve_kp = {
278+
.symbol_name = SYS_EXECVE_SYMBOL,
279+
.pre_handler = sys_execve_handler_pre,
280+
};
281+
#else
231282
static struct kprobe execve_kp = {
232283
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
233284
.symbol_name = "do_execveat_common",
@@ -238,6 +289,7 @@ static struct kprobe execve_kp = {
238289
#endif
239290
.pre_handler = execve_handler_pre,
240291
};
292+
#endif
241293

242294
#endif
243295

0 commit comments

Comments
 (0)