From dc5f911e43b52f204462b27934d65d2cb97ea9c0 Mon Sep 17 00:00:00 2001 From: weishu Date: Sun, 24 Mar 2024 11:20:34 +0800 Subject: [PATCH] kernel: remove become_manager and minor refactors --- kernel/Makefile | 3 +- kernel/core_hook.c | 5 +- kernel/ksu.c | 6 +- kernel/manager.c | 102 -------------------- kernel/manager.h | 2 - kernel/{uid_observer.c => throne_tracker.c} | 18 +++- kernel/throne_tracker.h | 10 ++ kernel/uid_observer.h | 10 -- 8 files changed, 31 insertions(+), 125 deletions(-) delete mode 100644 kernel/manager.c rename kernel/{uid_observer.c => throne_tracker.c} (95%) create mode 100644 kernel/throne_tracker.h delete mode 100644 kernel/uid_observer.h diff --git a/kernel/Makefile b/kernel/Makefile index a45f6f5b8b2c..be5e21c80bf4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,8 +2,7 @@ kernelsu-objs := ksu.o kernelsu-objs += allowlist.o kernelsu-objs += apk_sign.o kernelsu-objs += sucompat.o -kernelsu-objs += uid_observer.o -kernelsu-objs += manager.o +kernelsu-objs += throne_tracker.o kernelsu-objs += core_hook.o kernelsu-objs += ksud.o kernelsu-objs += embed_ksud.o diff --git a/kernel/core_hook.c b/kernel/core_hook.c index cdb2e427a1ac..bdcc01afeb25 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -37,7 +37,8 @@ #include "linux/vmalloc.h" #include "manager.h" #include "selinux/selinux.h" -#include "uid_observer.h" +#include "throne_tracker.h" +#include "throne_tracker.h" #include "kernel_compat.h" static bool ksu_module_mounted = false; @@ -199,7 +200,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry) pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname, new_dentry->d_iname, buf); - update_uid(); + track_throne(); return 0; } diff --git a/kernel/ksu.c b/kernel/ksu.c index 6389f24e2851..3a84e5561378 100644 --- a/kernel/ksu.c +++ b/kernel/ksu.c @@ -9,7 +9,7 @@ #include "core_hook.h" #include "klog.h" // IWYU pragma: keep #include "ksu.h" -#include "uid_observer.h" +#include "throne_tracker.h" static struct workqueue_struct *ksu_workqueue; @@ -53,7 +53,7 @@ int __init kernelsu_init(void) ksu_allowlist_init(); - ksu_uid_observer_init(); + ksu_throne_tracker_init(); #ifdef CONFIG_KPROBES ksu_enable_sucompat(); @@ -74,7 +74,7 @@ void kernelsu_exit(void) { ksu_allowlist_exit(); - ksu_uid_observer_exit(); + ksu_throne_tracker_exit(); destroy_workqueue(ksu_workqueue); diff --git a/kernel/manager.c b/kernel/manager.c deleted file mode 100644 index 15258832ce22..000000000000 --- a/kernel/manager.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "linux/cred.h" -#include "linux/gfp.h" -#include "linux/slab.h" -#include "linux/uidgid.h" -#include "linux/version.h" - -#include "linux/fdtable.h" -#include "linux/fs.h" -#include "linux/rcupdate.h" - -#include "apk_sign.h" -#include "klog.h" // IWYU pragma: keep -#include "ksu.h" -#include "manager.h" - -uid_t ksu_manager_uid = KSU_INVALID_UID; - -bool become_manager(char *pkg) -{ - struct fdtable *files_table; - int i = 0; - struct path files_path; - char *cwd; - char *buf; - bool result = false; - -#ifdef KSU_MANAGER_PACKAGE - // pkg is `/` - if (strncmp(pkg + 1, KSU_MANAGER_PACKAGE, - sizeof(KSU_MANAGER_PACKAGE)) != 0) { - pr_info("manager package is inconsistent with kernel build: %s\n", - KSU_MANAGER_PACKAGE); - return false; - } -#endif - // must be zygote's direct child, otherwise any app can fork a new process and - // open manager's apk - if (task_uid(current->real_parent).val != 0) { - pr_info("parent is not zygote!\n"); - return false; - } - - buf = (char *)kmalloc(PATH_MAX, GFP_ATOMIC); - if (!buf) { - pr_err("kalloc path failed.\n"); - return false; - } - - files_table = files_fdtable(current->files); - - int pkg_len = strlen(pkg); - // todo: use iterate_fd - for (i = 0; files_table->fd[i] != NULL; i++) { - files_path = files_table->fd[i]->f_path; - if (!d_is_reg(files_path.dentry)) { - continue; - } - cwd = d_path(&files_path, buf, PATH_MAX); - if (startswith(cwd, "/data/app/") != 0 || - endswith(cwd, "==/base.apk") != 0) { - // AOSP generate ramdom base64 with 16bit, without NO_PADDING, so it must have two "=" - continue; - } - // we have found the apk! - pr_info("found apk: %s\n", cwd); - char *pkg_index = strstr(cwd, pkg); - if (!pkg_index) { - pr_info("apk path not match package name!\n"); - continue; - } - char *next_char = pkg_index + pkg_len; - // because we ensure the cwd must startswith `/data/app` and endswith `base.apk` - // we don't need to check if the pointer is out of bounds - if (*next_char != '-') { - // from android 8.1: http://aospxref.com/android-8.1.0_r81/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#17612 - // to android 13: http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java#1208 - // /data/app/~~[randomStringA]/[packageName]-[randomStringB] - // the previous char must be `/` and the next char must be `-` - // because we use strstr instead of equals, this is a strong verfication. - pr_info("invalid pkg: %s\n", pkg); - continue; - } - if (is_manager_apk(cwd)) { - // check passed - uid_t uid = current_uid().val; - pr_info("manager uid: %d\n", uid); - - ksu_set_manager_uid(uid); - - result = true; - goto clean; - } else { - pr_info("manager signature invalid!\n"); - } - - break; - } - -clean: - kfree(buf); - return result; -} diff --git a/kernel/manager.h b/kernel/manager.h index 9429d758f89d..6f9151080218 100644 --- a/kernel/manager.h +++ b/kernel/manager.h @@ -33,6 +33,4 @@ static inline void ksu_invalidate_manager_uid() ksu_manager_uid = KSU_INVALID_UID; } -bool become_manager(char *pkg); - #endif diff --git a/kernel/uid_observer.c b/kernel/throne_tracker.c similarity index 95% rename from kernel/uid_observer.c rename to kernel/throne_tracker.c index 60bb3b104f72..2429c6ac7b61 100644 --- a/kernel/uid_observer.c +++ b/kernel/throne_tracker.c @@ -11,9 +11,11 @@ #include "klog.h" // IWYU pragma: keep #include "ksu.h" #include "manager.h" -#include "uid_observer.h" +#include "throne_tracker.h" #include "kernel_compat.h" +uid_t ksu_manager_uid = KSU_INVALID_UID; + #define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list" static struct work_struct ksu_update_uid_work; @@ -71,6 +73,14 @@ static void crown_manager(const char *apk, struct list_head *uid_data) pr_info("manager pkg: %s\n", pkg); +#ifdef KSU_MANAGER_PACKAGE + // pkg is `/` + if (strncmp(pkg, KSU_MANAGER_PACKAGE, sizeof(KSU_MANAGER_PACKAGE))) { + pr_info("manager package is inconsistent with kernel build: %s\n", + KSU_MANAGER_PACKAGE); + return; + } +#endif struct list_head *list = (struct list_head *)uid_data; struct uid_data *np; @@ -292,18 +302,18 @@ static void do_update_uid(struct work_struct *work) filp_close(fp, 0); } -void update_uid() +void track_throne() { ksu_queue_work(&ksu_update_uid_work); } -int ksu_uid_observer_init() +int ksu_throne_tracker_init() { INIT_WORK(&ksu_update_uid_work, do_update_uid); return 0; } -int ksu_uid_observer_exit() +int ksu_throne_tracker_exit() { return 0; } diff --git a/kernel/throne_tracker.h b/kernel/throne_tracker.h new file mode 100644 index 000000000000..ff5770adf076 --- /dev/null +++ b/kernel/throne_tracker.h @@ -0,0 +1,10 @@ +#ifndef __KSU_H_UID_OBSERVER +#define __KSU_H_UID_OBSERVER + +int ksu_throne_tracker_init(); + +int ksu_throne_tracker_exit(); + +void track_throne(); + +#endif diff --git a/kernel/uid_observer.h b/kernel/uid_observer.h deleted file mode 100644 index 6d06fd6ce192..000000000000 --- a/kernel/uid_observer.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __KSU_H_UID_OBSERVER -#define __KSU_H_UID_OBSERVER - -int ksu_uid_observer_init(); - -int ksu_uid_observer_exit(); - -void update_uid(); - -#endif