Hook improvements (take 2) (#563)
Hi @tiann. Thanks for the great project, I had great fun playing around with it. This PR mainly tries to further minimize the possible delays caused by KernelSU hooking. There are 3 major changes: - Processes with 0 < UID < 2000 are blocked straight-up before going through the allow_list. I don't see any need for such processes to be interested in root, and this allows returning early before going through a more expensive lookup. If there's an expected breakage due to this change, I'll remove it. Let me know. - A page-sized (4K) bitmap is added. This allows O(1) lookup for UID <= 32767. This speeds up `ksu_is_allow_uid()` by about 4.8x by sacrificing a 4K memory. IMHO, a good trade-off. Most notably, this reduces the 99.999% result previously from worrying milliseconds scale to microseconds scale. For UID > 32767, another page-sized (4K) sequential array is used to cache allow_list. Compared to the previous PR #557, this new approach gives another nice 25% performance boost in average, 63-96% boost in worst cases. Benchmark results are available at https://docs.google.com/spreadsheets/d/1w_tO1zRLPNMFRer49pL1TQfL6ndEhilRrDU1XFIcWXY/edit?usp=sharing Thanks! --------- Signed-off-by: Juhyung Park <qkrwngud825@gmail.com>
This commit is contained in:
@@ -52,9 +52,9 @@ static struct work_struct stop_vfs_read_work;
|
||||
static struct work_struct stop_execve_hook_work;
|
||||
static struct work_struct stop_input_hook_work;
|
||||
#else
|
||||
static bool vfs_read_hook = true;
|
||||
static bool execveat_hook = true;
|
||||
static bool input_hook = true;
|
||||
bool ksu_vfs_read_hook __read_mostly = true;
|
||||
bool ksu_execveat_hook __read_mostly = true;
|
||||
bool ksu_input_hook __read_mostly = true;
|
||||
#endif
|
||||
|
||||
void on_post_fs_data(void)
|
||||
@@ -138,7 +138,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
void *argv, void *envp, int *flags)
|
||||
{
|
||||
#ifndef CONFIG_KPROBES
|
||||
if (!execveat_hook) {
|
||||
if (!ksu_execveat_hook) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -157,8 +157,8 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!memcmp(filename->name, system_bin_init,
|
||||
sizeof(system_bin_init) - 1)) {
|
||||
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;
|
||||
@@ -200,8 +200,8 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
#endif
|
||||
}
|
||||
|
||||
if (first_app_process &&
|
||||
!memcmp(filename->name, app_process, sizeof(app_process) - 1)) {
|
||||
if (unlikely(first_app_process &&
|
||||
!memcmp(filename->name, app_process, sizeof(app_process) - 1))) {
|
||||
first_app_process = false;
|
||||
pr_info("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed);
|
||||
on_post_fs_data(); // we keep this for old ksud
|
||||
@@ -244,7 +244,7 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
size_t *count_ptr, loff_t **pos)
|
||||
{
|
||||
#ifndef CONFIG_KPROBES
|
||||
if (!vfs_read_hook) {
|
||||
if (!ksu_vfs_read_hook) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -345,7 +345,7 @@ int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code,
|
||||
int *value)
|
||||
{
|
||||
#ifndef CONFIG_KPROBES
|
||||
if (!input_hook) {
|
||||
if (!ksu_input_hook) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -463,7 +463,7 @@ static void stop_vfs_read_hook()
|
||||
bool ret = schedule_work(&stop_vfs_read_work);
|
||||
pr_info("unregister vfs_read kprobe: %d!\n", ret);
|
||||
#else
|
||||
vfs_read_hook = false;
|
||||
ksu_vfs_read_hook = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ static void stop_execve_hook()
|
||||
bool ret = schedule_work(&stop_execve_hook_work);
|
||||
pr_info("unregister execve kprobe: %d!\n", ret);
|
||||
#else
|
||||
execveat_hook = false;
|
||||
ksu_execveat_hook = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ static void stop_input_hook()
|
||||
bool ret = schedule_work(&stop_input_hook_work);
|
||||
pr_info("unregister input kprobe: %d!\n", ret);
|
||||
#else
|
||||
input_hook = false;
|
||||
ksu_input_hook = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user