diff --git a/kernel/.clangd b/kernel/.clangd index 83860fae..5efbb7ef 100644 --- a/kernel/.clangd +++ b/kernel/.clangd @@ -1,4 +1,4 @@ Diagnostics: UnusedIncludes: Strict ClangTidy: - Remove: bugprone-sizeof-expression \ No newline at end of file + Remove: bugprone-sizeof-expression diff --git a/kernel/allowlist.c b/kernel/allowlist.c index 19eff4bb..420d23a4 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -29,6 +29,38 @@ static DEFINE_MUTEX(allowlist_mutex); static struct root_profile default_root_profile; static struct non_root_profile default_non_root_profile; +static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly __aligned(PAGE_SIZE); +static int allow_list_pointer __read_mostly = 0; + +static void remove_uid_from_arr(uid_t uid) +{ + int *temp_arr; + int i, j; + + if (allow_list_pointer == 0) + return; + + temp_arr = kmalloc(sizeof(allow_list_arr), GFP_KERNEL); + if (temp_arr == NULL) { + pr_err("%s: unable to allocate memory\n", __func__); + return; + } + + for (i = j = 0; i < allow_list_pointer; i++) { + if (allow_list_arr[i] == uid) + continue; + temp_arr[j++] = allow_list_arr[i]; + } + + allow_list_pointer = j; + + for (; j < ARRAY_SIZE(allow_list_arr); j++) + temp_arr[j] = -1; + + memcpy(&allow_list_arr, temp_arr, PAGE_SIZE); + kfree(temp_arr); +} + static void init_default_profiles() { default_root_profile.uid = 0; @@ -51,6 +83,9 @@ struct perm_data { static struct list_head allow_list; +static uint8_t allow_list_bitmap[PAGE_SIZE] __read_mostly __aligned(PAGE_SIZE); +#define BITMAP_UID_MAX ((sizeof(allow_list_bitmap) * BITS_PER_BYTE) - 1) + #define KERNEL_SU_ALLOWLIST "/data/adb/ksu/.allowlist" static struct work_struct ksu_save_work; @@ -110,6 +145,11 @@ static bool profile_valid(struct app_profile *profile) return false; } + if (profile->current_uid < 2000) { + pr_err("uid lower than 2000 is unsupported: %d\n", profile->current_uid); + return false; + } + if (profile->version < KSU_APP_PROFILE_VER) { pr_info("Unsupported profile version: %d\n", profile->version); return false; @@ -147,7 +187,7 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist) // found it, just override it all! memcpy(&p->profile, profile, sizeof(*profile)); result = true; - goto exit; + goto out; } } @@ -170,9 +210,31 @@ bool ksu_set_app_profile(struct app_profile *profile, bool persist) profile->nrp_config.profile.umount_modules); } list_add_tail(&p->list, &allow_list); + +out: + if (profile->current_uid <= BITMAP_UID_MAX) { + if (profile->allow_su) + allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |= 1 << (profile->current_uid % BITS_PER_BYTE); + else + allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &= ~(1 << (profile->current_uid % BITS_PER_BYTE)); + } else { + if (profile->allow_su) { + /* + * 1024 apps with uid higher than BITMAP_UID_MAX + * registered to request superuser? + */ + if (allow_list_pointer >= ARRAY_SIZE(allow_list_arr)) { + pr_err("too many apps registered\n"); + WARN_ON(1); + return false; + } + allow_list_arr[allow_list_pointer++] = profile->current_uid; + } else { + remove_uid_from_arr(profile->current_uid); + } + } result = true; -exit: // check if the default profiles is changed, cache it to a single struct to accelerate access. if (unlikely(!strcmp(profile->key, "$"))) { // set default non root profile @@ -192,21 +254,26 @@ exit: return result; } -bool ksu_is_allow_uid(uid_t uid) +bool __ksu_is_allow_uid(uid_t uid) { - struct perm_data *p = NULL; - struct list_head *pos = NULL; + int i; - if (uid == 0) { + if (unlikely(uid == 0)) { // already root, but only allow our domain. return is_ksu_domain(); } - list_for_each (pos, &allow_list) { - p = list_entry(pos, struct perm_data, list); - // pr_info("is_allow_uid uid :%d, allow: %d\n", p->uid, p->allow); - if (uid == p->profile.current_uid) { - return p->profile.allow_su; + if (uid < 2000) { + // do not bother going through the list if it's system + return false; + } + + if (likely(uid <= BITMAP_UID_MAX)) { + return !!(allow_list_bitmap[uid / BITS_PER_BYTE] & (1 << (uid % BITS_PER_BYTE))); + } else { + for (i = 0; i < allow_list_pointer; i++) { + if (allow_list_arr[i] == uid) + return true; } } @@ -386,6 +453,9 @@ void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data) modified = true; pr_info("prune uid: %d\n", uid); list_del(&np->list); + allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE)); + remove_uid_from_arr(uid); + smp_mb(); kfree(np); } } @@ -409,6 +479,14 @@ bool ksu_load_allow_list(void) void ksu_allowlist_init(void) { + int i; + + BUILD_BUG_ON(sizeof(allow_list_bitmap) != PAGE_SIZE); + BUILD_BUG_ON(sizeof(allow_list_arr) != PAGE_SIZE); + + for (i = 0; i < ARRAY_SIZE(allow_list_arr); i++) + allow_list_arr[i] = -1; + INIT_LIST_HEAD(&allow_list); INIT_WORK(&ksu_save_work, do_save_allow_list); diff --git a/kernel/allowlist.h b/kernel/allowlist.h index 63332268..04d47fb7 100644 --- a/kernel/allowlist.h +++ b/kernel/allowlist.h @@ -12,7 +12,8 @@ bool ksu_load_allow_list(void); void ksu_show_allow_list(void); -bool ksu_is_allow_uid(uid_t uid); +bool __ksu_is_allow_uid(uid_t uid); +#define ksu_is_allow_uid(uid) unlikely(__ksu_is_allow_uid(uid)) bool ksu_get_allow_list(int *array, int *length, bool allow); @@ -23,4 +24,4 @@ bool ksu_set_app_profile(struct app_profile *, bool persist); bool ksu_uid_should_umount(uid_t uid); struct root_profile *ksu_get_root_profile(uid_t uid); -#endif \ No newline at end of file +#endif diff --git a/kernel/apk_sign.h b/kernel/apk_sign.h index 033971f9..52cbc9d0 100644 --- a/kernel/apk_sign.h +++ b/kernel/apk_sign.h @@ -4,4 +4,4 @@ // return 0 if signature match int is_manager_apk(char *path); -#endif \ No newline at end of file +#endif diff --git a/kernel/embed_ksud.c b/kernel/embed_ksud.c index c82d9eee..24c40121 100644 --- a/kernel/embed_ksud.c +++ b/kernel/embed_ksud.c @@ -2,4 +2,4 @@ // This file will be regenerated by CI unsigned int ksud_size = 0; -const char ksud[0] = {}; \ No newline at end of file +const char ksud[0] = {}; diff --git a/kernel/export_symbol.txt b/kernel/export_symbol.txt index d476da16..1abd805e 100644 --- a/kernel/export_symbol.txt +++ b/kernel/export_symbol.txt @@ -1,2 +1,2 @@ register_kprobe -unregister_kprobe \ No newline at end of file +unregister_kprobe diff --git a/kernel/kernel_compat.c b/kernel/kernel_compat.c index 339650fe..591c31db 100644 --- a/kernel/kernel_compat.c +++ b/kernel/kernel_compat.c @@ -31,4 +31,4 @@ ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, l } return result; #endif -} \ No newline at end of file +} diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index 8daa4048..b5cc6c9a 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -39,4 +39,4 @@ static inline int install_session_keyring(struct key *keyring) #define KWORKER_INSTALL_KEYRING() #endif -#endif \ No newline at end of file +#endif diff --git a/kernel/klog.h b/kernel/klog.h index bda4f9cb..a934027f 100644 --- a/kernel/klog.h +++ b/kernel/klog.h @@ -8,4 +8,4 @@ #define pr_fmt(fmt) "KernelSU: " fmt #endif -#endif \ No newline at end of file +#endif diff --git a/kernel/ksud.c b/kernel/ksud.c index 66250ec6..bb4c038c 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -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 } diff --git a/kernel/ksud.h b/kernel/ksud.h index d5a35aec..5a32a527 100644 --- a/kernel/ksud.h +++ b/kernel/ksud.h @@ -7,4 +7,4 @@ void on_post_fs_data(void); bool ksu_is_safe_mode(void); -#endif \ No newline at end of file +#endif diff --git a/kernel/manager.h b/kernel/manager.h index aba3c479..9429d758 100644 --- a/kernel/manager.h +++ b/kernel/manager.h @@ -15,7 +15,7 @@ static inline bool ksu_is_manager_uid_valid() static inline bool is_manager() { - return ksu_manager_uid == current_uid().val; + return unlikely(ksu_manager_uid == current_uid().val); } static inline uid_t ksu_get_manager_uid() diff --git a/kernel/module_api.c b/kernel/module_api.c index 6a81351d..999d5102 100644 --- a/kernel/module_api.c +++ b/kernel/module_api.c @@ -30,4 +30,4 @@ RE_EXPORT_SYMBOL1(unsigned long, kallsyms_lookup_name, const char *, name) // int ksu_register_kretprobe(struct kretprobe *rp); // void unregister_kretprobe(struct kretprobe *rp); // int register_kretprobes(struct kretprobe **rps, int num); -// void unregister_kretprobes(struct kretprobe **rps, int num); \ No newline at end of file +// void unregister_kretprobes(struct kretprobe **rps, int num); diff --git a/kernel/selinux/selinux.h b/kernel/selinux/selinux.h index ce5a98e2..1ccc0d53 100644 --- a/kernel/selinux/selinux.h +++ b/kernel/selinux/selinux.h @@ -18,4 +18,4 @@ bool is_ksu_domain(); void apply_kernelsu_rules(); -#endif \ No newline at end of file +#endif diff --git a/kernel/sucompat.c b/kernel/sucompat.c index e3078df7..09e5f501 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -53,7 +53,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, if (IS_ERR(filename)) { return 0; } - if (!memcmp(filename->name, su, sizeof(su))) { + if (unlikely(!memcmp(filename->name, su, sizeof(su)))) { pr_info("faccessat su->sh!\n"); *filename_user = sh_user_path(); } @@ -73,7 +73,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) return 0; } - if (!filename_user) { + if (unlikely(!filename_user)) { return 0; } @@ -82,7 +82,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) if (IS_ERR(filename)) { return 0; } - if (!memcmp(filename->name, su, sizeof(su))) { + if (unlikely(!memcmp(filename->name, su, sizeof(su)))) { pr_info("newfstatat su->sh!\n"); *filename_user = sh_user_path(); } @@ -99,7 +99,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, const char sh[] = KSUD_PATH; const char su[] = SU_PATH; - if (!filename_ptr) + if (unlikely(!filename_ptr)) return 0; filename = *filename_ptr; @@ -107,16 +107,16 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, return 0; } - if (!ksu_is_allow_uid(current_uid().val)) { + if (likely(memcmp(filename->name, su, sizeof(su)))) return 0; - } - if (!memcmp(filename->name, su, sizeof(su))) { - pr_info("do_execveat_common su found\n"); - memcpy((void *)filename->name, sh, sizeof(sh)); + if (!ksu_is_allow_uid(current_uid().val)) + return 0; - escape_to_root(); - } + pr_info("do_execveat_common su found\n"); + memcpy((void *)filename->name, sh, sizeof(sh)); + + escape_to_root(); return 0; } diff --git a/kernel/uid_observer.h b/kernel/uid_observer.h index 5604b219..6d06fd6c 100644 --- a/kernel/uid_observer.h +++ b/kernel/uid_observer.h @@ -7,4 +7,4 @@ int ksu_uid_observer_exit(); void update_uid(); -#endif \ No newline at end of file +#endif diff --git a/website/docs/guide/how-to-integrate-for-non-gki.md b/website/docs/guide/how-to-integrate-for-non-gki.md index 7528fa32..a5319333 100644 --- a/website/docs/guide/how-to-integrate-for-non-gki.md +++ b/website/docs/guide/how-to-integrate-for-non-gki.md @@ -75,14 +75,20 @@ index ac59664eaecf..bdd585e1d2cc 100644 return retval; } ++extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); ++extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, ++ void *argv, void *envp, int *flags); static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { -+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ if (unlikely(ksu_execveat_hook)) ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ else ++ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); } @@ -115,14 +121,16 @@ index 650fc7e0f3a6..55be193913b6 100644 } EXPORT_SYMBOL(kernel_read); ++extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; -+ ksu_handle_vfs_read(&file, &buf, &count, &pos); -+ ++ if (unlikely(ksu_vfs_read_hook)) ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); ++ if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) @@ -222,19 +230,22 @@ index 45306f9ef247..815091ebfca4 100755 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, - return disposition; + return disposition; } - + ++extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); + static void input_handle_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) + unsigned int type, unsigned int code, int value) { - int disposition = input_get_disposition(dev, type, code, &value); -+ ksu_handle_input_handle_event(&type, &code, &value); - - if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) - add_input_randomness(type, code, value); + int disposition = input_get_disposition(dev, type, code, &value); ++ ++ if (unlikely(ksu_input_hook)) ++ ksu_handle_input_handle_event(&type, &code, &value); + + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + add_input_randomness(type, code, value); ``` Finally, build your kernel again, KernelSU should works well. diff --git a/website/docs/id_ID/guide/how-to-integrate-for-non-gki.md b/website/docs/id_ID/guide/how-to-integrate-for-non-gki.md index eba6d09e..8fcd3c9f 100644 --- a/website/docs/id_ID/guide/how-to-integrate-for-non-gki.md +++ b/website/docs/id_ID/guide/how-to-integrate-for-non-gki.md @@ -69,18 +69,24 @@ index ac59664eaecf..bdd585e1d2cc 100644 @@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename, return retval; } - + ++extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); ++extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, ++ void *argv, void *envp, int *flags); static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { -+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ if (unlikely(ksu_execveat_hook)) ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ else ++ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); } - + diff --git a/fs/open.c b/fs/open.c index 05036d819197..965b84d486b8 100644 --- a/fs/open.c @@ -88,7 +94,7 @@ index 05036d819197..965b84d486b8 100644 @@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) return ksys_fallocate(fd, mode, offset, len); } - + +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, + int *flags); /* @@ -109,14 +115,16 @@ index 650fc7e0f3a6..55be193913b6 100644 @@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) } EXPORT_SYMBOL(kernel_read); - + ++extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; - -+ ksu_handle_vfs_read(&file, &buf, &count, &pos); + ++ if (unlikely(ksu_vfs_read_hook)) ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); + if (!(file->f_mode & FMODE_READ)) return -EBADF; @@ -128,7 +136,7 @@ index 376543199b5a..82adcef03ecc 100644 @@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat, } EXPORT_SYMBOL(vfs_statx_fd); - + +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); + /** @@ -137,7 +145,7 @@ index 376543199b5a..82adcef03ecc 100644 @@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags, int error = -EINVAL; unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; - + + ksu_handle_stat(&dfd, &filename, &flags); if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0) @@ -217,19 +225,22 @@ index 45306f9ef247..815091ebfca4 100755 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, - return disposition; + return disposition; } - + ++extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); + static void input_handle_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) + unsigned int type, unsigned int code, int value) { - int disposition = input_get_disposition(dev, type, code, &value); -+ ksu_handle_input_handle_event(&type, &code, &value); - - if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) - add_input_randomness(type, code, value); + int disposition = input_get_disposition(dev, type, code, &value); ++ ++ if (unlikely(ksu_input_hook)) ++ ksu_handle_input_handle_event(&type, &code, &value); + + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + add_input_randomness(type, code, value); ``` Terakhir, edit `KernelSU/kernel/ksu.c` dan beri komentar pada `enable_sucompat()` lalu build kernel Anda lagi, KernelSU akan bekerja dengan baik. diff --git a/website/docs/vi_VN/guide/how-to-integrate-for-non-gki.md b/website/docs/vi_VN/guide/how-to-integrate-for-non-gki.md index d27c5ff0..c188b1f2 100644 --- a/website/docs/vi_VN/guide/how-to-integrate-for-non-gki.md +++ b/website/docs/vi_VN/guide/how-to-integrate-for-non-gki.md @@ -71,14 +71,20 @@ index ac59664eaecf..bdd585e1d2cc 100644 return retval; } ++extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); ++extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, ++ void *argv, void *envp, int *flags); static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { -+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ if (unlikely(ksu_execveat_hook)) ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ else ++ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); } @@ -111,14 +117,16 @@ index 650fc7e0f3a6..55be193913b6 100644 } EXPORT_SYMBOL(kernel_read); ++extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; -+ ksu_handle_vfs_read(&file, &buf, &count, &pos); -+ ++ if (unlikely(ksu_vfs_read_hook)) ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); ++ if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) diff --git a/website/docs/zh_CN/guide/how-to-integrate-for-non-gki.md b/website/docs/zh_CN/guide/how-to-integrate-for-non-gki.md index 4f652146..492bb349 100644 --- a/website/docs/zh_CN/guide/how-to-integrate-for-non-gki.md +++ b/website/docs/zh_CN/guide/how-to-integrate-for-non-gki.md @@ -75,14 +75,20 @@ index ac59664eaecf..bdd585e1d2cc 100644 return retval; } ++extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); ++extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, ++ void *argv, void *envp, int *flags); static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { -+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ if (unlikely(ksu_execveat_hook)) ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ else ++ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); } @@ -115,14 +121,16 @@ index 650fc7e0f3a6..55be193913b6 100644 } EXPORT_SYMBOL(kernel_read); ++extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; -+ ksu_handle_vfs_read(&file, &buf, &count, &pos); -+ ++ if (unlikely(ksu_vfs_read_hook)) ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); ++ if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) @@ -222,19 +230,22 @@ index 45306f9ef247..815091ebfca4 100755 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, - return disposition; + return disposition; } - + ++extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); + static void input_handle_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) + unsigned int type, unsigned int code, int value) { - int disposition = input_get_disposition(dev, type, code, &value); -+ ksu_handle_input_handle_event(&type, &code, &value); - - if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) - add_input_randomness(type, code, value); + int disposition = input_get_disposition(dev, type, code, &value); ++ ++ if (unlikely(ksu_input_hook)) ++ ksu_handle_input_handle_event(&type, &code, &value); + + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + add_input_randomness(type, code, value); ``` 改完之后重新编译内核即可。 diff --git a/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md b/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md index fe6fc72e..83ab5eb3 100644 --- a/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md +++ b/website/docs/zh_TW/guide/how-to-integrate-for-non-gki.md @@ -75,14 +75,20 @@ index ac59664eaecf..bdd585e1d2cc 100644 return retval; } ++extern bool ksu_execveat_hook __read_mostly; +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, + void *envp, int *flags); ++extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, ++ void *argv, void *envp, int *flags); static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { -+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ if (unlikely(ksu_execveat_hook)) ++ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); ++ else ++ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); } @@ -115,14 +121,16 @@ index 650fc7e0f3a6..55be193913b6 100644 } EXPORT_SYMBOL(kernel_read); ++extern bool ksu_vfs_read_hook __read_mostly; +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, + size_t *count_ptr, loff_t **pos); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; -+ ksu_handle_vfs_read(&file, &buf, &count, &pos); -+ ++ if (unlikely(ksu_vfs_read_hook)) ++ ksu_handle_vfs_read(&file, &buf, &count, &pos); ++ if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) @@ -222,19 +230,22 @@ index 45306f9ef247..815091ebfca4 100755 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, - return disposition; + return disposition; } - + ++extern bool ksu_input_hook __read_mostly; +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); + static void input_handle_event(struct input_dev *dev, - unsigned int type, unsigned int code, int value) + unsigned int type, unsigned int code, int value) { - int disposition = input_get_disposition(dev, type, code, &value); -+ ksu_handle_input_handle_event(&type, &code, &value); - - if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) - add_input_randomness(type, code, value); + int disposition = input_get_disposition(dev, type, code, &value); ++ ++ if (unlikely(ksu_input_hook)) ++ ksu_handle_input_handle_event(&type, &code, &value); + + if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) + add_input_randomness(type, code, value); ``` 最後,再次建置您的核心,KernelSU 將會如期運作。