From b1830049f12a5b8c35d5fc3a27cd4afc3d24663c Mon Sep 17 00:00:00 2001 From: weishu Date: Thu, 12 Oct 2023 15:44:43 +0800 Subject: [PATCH] kernel: prune allowlist with package name and uid --- kernel/allowlist.c | 7 ++++--- kernel/allowlist.h | 2 +- kernel/uid_observer.c | 16 ++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/kernel/allowlist.c b/kernel/allowlist.c index 4a23e401..f1115eb5 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -441,7 +441,7 @@ exit: filp_close(fp, 0); } -void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data) +void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data) { struct perm_data *np = NULL; struct perm_data *n = NULL; @@ -451,11 +451,12 @@ void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data) mutex_lock(&allowlist_mutex); list_for_each_entry_safe (np, n, &allow_list, list) { uid_t uid = np->profile.current_uid; + char *package = np->profile.key; // we use this uid for special cases, don't prune it! bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID; - if (!is_preserved_uid && !is_uid_exist(uid, data)) { + if (!is_preserved_uid && !is_uid_valid(uid, package, data)) { modified = true; - pr_info("prune uid: %d\n", uid); + pr_info("prune uid: %d, package: %s\n", uid, package); list_del(&np->list); allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE)); remove_uid_from_arr(uid); diff --git a/kernel/allowlist.h b/kernel/allowlist.h index 04d47fb7..298624bc 100644 --- a/kernel/allowlist.h +++ b/kernel/allowlist.h @@ -17,7 +17,7 @@ bool __ksu_is_allow_uid(uid_t uid); bool ksu_get_allow_list(int *array, int *length, bool allow); -void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data); +void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *), void *data); bool ksu_get_app_profile(struct app_profile *); bool ksu_set_app_profile(struct app_profile *, bool persist); diff --git a/kernel/uid_observer.c b/kernel/uid_observer.c index b12eff11..155c5fcc 100644 --- a/kernel/uid_observer.c +++ b/kernel/uid_observer.c @@ -20,16 +20,18 @@ static struct work_struct ksu_update_uid_work; struct uid_data { struct list_head list; u32 uid; + char package[KSU_MAX_PACKAGE_NAME]; }; -static bool is_uid_exist(uid_t uid, void *data) +static bool is_uid_exist(uid_t uid, char *package, void *data) { struct list_head *list = (struct list_head *)data; struct uid_data *np; bool exist = false; list_for_each_entry (np, list, list) { - if (np->uid == uid % 100000) { + if (np->uid == uid % 100000 && + strcmp(np->package, package) == 0) { exist = true; break; } @@ -39,7 +41,8 @@ static bool is_uid_exist(uid_t uid, void *data) static void do_update_uid(struct work_struct *work) { - struct file *fp = ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0); + struct file *fp = + ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0); if (IS_ERR(fp)) { pr_err("do_update_uid, open " SYSTEM_PACKAGES_LIST_PATH " failed: %d\n", @@ -73,10 +76,10 @@ static void do_update_uid(struct work_struct *work) char *tmp = buf; const char *delim = " "; - strsep(&tmp, delim); // skip package + char *package = strsep(&tmp, delim); char *uid = strsep(&tmp, delim); - if (!uid) { - pr_err("update_uid: uid is NULL!\n"); + if (!uid || !package) { + pr_err("update_uid: package or uid is NULL!\n"); continue; } @@ -86,6 +89,7 @@ static void do_update_uid(struct work_struct *work) continue; } data->uid = res; + strcpy(data->package, package); list_add_tail(&data->list, &uid_list); // reset line start line_start = pos;