From 6aab856de72b770c35b76eabd888081f09824336 Mon Sep 17 00:00:00 2001 From: vvb2060 Date: Tue, 30 Jan 2024 02:58:56 +0800 Subject: [PATCH] Enhanced denylist app id tracking --- native/src/core/daemon.cpp | 1 + native/src/core/deny/utils.cpp | 116 ++++++++++++++++++------------- native/src/core/include/core.hpp | 2 +- native/src/core/package.cpp | 1 - native/src/core/su/su_daemon.cpp | 3 +- 5 files changed, 69 insertions(+), 54 deletions(-) diff --git a/native/src/core/daemon.cpp b/native/src/core/daemon.cpp index 3fbf32eb9..5d0e939d1 100644 --- a/native/src/core/daemon.cpp +++ b/native/src/core/daemon.cpp @@ -158,6 +158,7 @@ static void handle_request_async(int client, int code, const sock_cred &cred) { case +RequestCode::ZYGOTE_RESTART: LOGI("** zygote restarted\n"); prune_su_access(); + scan_deny_apps(); reset_zygisk(false); close(client); break; diff --git a/native/src/core/deny/utils.cpp b/native/src/core/deny/utils.cpp index 8268170cc..f8d3ed993 100644 --- a/native/src/core/deny/utils.cpp +++ b/native/src/core/deny/utils.cpp @@ -15,8 +15,6 @@ using namespace std; -atomic_flag skip_pkg_rescan; - // For the following data structures: // If package name == ISOLATED_MAGIC, or app ID == -1, it means isolated service @@ -33,59 +31,48 @@ static pthread_mutex_t data_lock = PTHREAD_MUTEX_INITIALIZER; atomic denylist_enforced = false; -static void rescan_apps() { - LOGD("denylist: rescanning apps\n"); - - app_id_to_pkgs.clear(); +static int get_app_id(const vector &users, const string &pkg) { + struct stat st{}; + char buf[PATH_MAX]; + for (const auto &user_id: users) { + ssprintf(buf, sizeof(buf), "%s/%d/%s", APP_DATA_DIR, user_id, pkg.data()); + if (stat(buf, &st) == 0) { + return to_app_id(st.st_uid); + } + } + return 0; +} +static void collect_users(vector &users) { auto data_dir = xopen_dir(APP_DATA_DIR); if (!data_dir) return; dirent *entry; while ((entry = xreaddir(data_dir.get()))) { - // For each user - int dfd = xopenat(dirfd(data_dir.get()), entry->d_name, O_RDONLY); - if (auto dir = xopen_dir(dfd)) { - while ((entry = xreaddir(dir.get()))) { - struct stat st{}; - // For each package - if (xfstatat(dfd, entry->d_name, &st, 0)) - continue; - int app_id = to_app_id(st.st_uid); - if (auto it = pkg_to_procs.find(entry->d_name); it != pkg_to_procs.end()) { - app_id_to_pkgs[app_id].insert(it->first); - } - } - } else { - close(dfd); - } + users.emplace_back(parse_int(entry->d_name)); } } -static void update_pkg_uid(const string &pkg, bool remove) { - auto data_dir = xopen_dir(APP_DATA_DIR); - if (!data_dir) +static int get_app_id(const string &pkg) { + if (pkg == ISOLATED_MAGIC) + return -1; + vector users; + collect_users(users); + return get_app_id(users, pkg); +} + +static void update_app_id(int app_id, const string &pkg, bool remove) { + if (app_id <= 0) return; - dirent *entry; - struct stat st{}; - char buf[PATH_MAX] = {0}; - // For each user - while ((entry = xreaddir(data_dir.get()))) { - ssprintf(buf, sizeof(buf), "%s/%s", entry->d_name, pkg.data()); - if (fstatat(dirfd(data_dir.get()), buf, &st, 0) == 0) { - int app_id = to_app_id(st.st_uid); - if (remove) { - if (auto it = app_id_to_pkgs.find(app_id); it != app_id_to_pkgs.end()) { - it->second.erase(pkg); - if (it->second.empty()) { - app_id_to_pkgs.erase(it); - } - } - } else { - app_id_to_pkgs[app_id].insert(pkg); + if (remove) { + if (auto it = app_id_to_pkgs.find(app_id); it != app_id_to_pkgs.end()) { + it->second.erase(pkg); + if (it->second.empty()) { + app_id_to_pkgs.erase(it); } - break; } + } else { + app_id_to_pkgs[app_id].emplace(pkg); } } @@ -195,6 +182,34 @@ static bool add_hide_set(const char *pkg, const char *proc) { return true; } +void scan_deny_apps() { + if (!app_id_to_pkgs_) + return; + + app_id_to_pkgs.clear(); + + char sql[4096]; + vector users; + collect_users(users); + for (auto it = pkg_to_procs.begin(); it != pkg_to_procs.end();) { + if (it->first == ISOLATED_MAGIC) { + it++; + continue; + } + int app_id = get_app_id(users, it->first); + if (app_id == 0) { + LOGI("denylist rm: [%s]\n", it->first.data()); + ssprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'", + it->first.data()); + db_err(db_exec(sql)); + it = pkg_to_procs.erase(it); + } else { + update_app_id(app_id, it->first, false); + it++; + } + } +} + static void clear_data() { pkg_to_procs_.reset(nullptr); app_id_to_pkgs_.reset(nullptr); @@ -214,7 +229,7 @@ static bool ensure_data() { db_err_cmd(err, goto error) default_new(app_id_to_pkgs_); - rescan_apps(); + scan_deny_apps(); return true; @@ -234,10 +249,13 @@ static int add_list(const char *pkg, const char *proc) { mutex_guard lock(data_lock); if (!ensure_data()) return DenyResponse::ERROR; + int app_id = get_app_id(pkg); + if (app_id == 0) + return DenyResponse::INVALID_PKG; if (!add_hide_set(pkg, proc)) return DenyResponse::ITEM_EXIST; auto it = pkg_to_procs.find(pkg); - update_pkg_uid(it->first, false); + update_app_id(app_id, it->first, false); } // Add to database @@ -266,7 +284,7 @@ static int rm_list(const char *pkg, const char *proc) { auto it = pkg_to_procs.find(pkg); if (it != pkg_to_procs.end()) { if (proc[0] == '\0') { - update_pkg_uid(it->first, true); + update_app_id(get_app_id(pkg), it->first, true); pkg_to_procs.erase(it); remove = true; LOGI("denylist rm: [%s]\n", pkg); @@ -274,7 +292,7 @@ static int rm_list(const char *pkg, const char *proc) { remove = true; LOGI("denylist rm: [%s/%s]\n", pkg, proc); if (it->second.empty()) { - update_pkg_uid(it->first, true); + update_app_id(get_app_id(pkg), it->first, true); pkg_to_procs.erase(it); } } @@ -309,6 +327,7 @@ void ls_list(int client) { return; } + scan_deny_apps(); write_int(client,static_cast(DenyResponse::OK)); for (const auto &[pkg, procs] : pkg_to_procs) { @@ -386,9 +405,6 @@ bool is_deny_target(int uid, string_view process) { if (!ensure_data()) return false; - if (!skip_pkg_rescan.test_and_set()) - rescan_apps(); - int app_id = to_app_id(uid); if (app_id >= 90000) { if (auto it = pkg_to_procs.find(ISOLATED_MAGIC); it != pkg_to_procs.end()) { diff --git a/native/src/core/include/core.hpp b/native/src/core/include/core.hpp index b6ac4ec24..09005df06 100644 --- a/native/src/core/include/core.hpp +++ b/native/src/core/include/core.hpp @@ -86,9 +86,9 @@ void clear_pkg(const char *pkg, int user_id); [[noreturn]] void install_module(const char *file); // Denylist -extern std::atomic_flag skip_pkg_rescan; extern std::atomic denylist_enforced; int denylist_cli(int argc, char **argv); void initialize_denylist(); +void scan_deny_apps(); bool is_deny_target(int uid, std::string_view process); void revert_unmount(int pid = -1) noexcept; diff --git a/native/src/core/package.cpp b/native/src/core/package.cpp index 70ab7e2d7..8aba61264 100644 --- a/native/src/core/package.cpp +++ b/native/src/core/package.cpp @@ -38,7 +38,6 @@ void check_pkg_refresh() { memcpy(app_ts, &st.st_mtim, sizeof(timespec)); } skip_mgr_check = false; - skip_pkg_rescan.clear(); } // app_id = app_no + AID_APP_START diff --git a/native/src/core/su/su_daemon.cpp b/native/src/core/su/su_daemon.cpp index 6334e75d6..8fe323842 100644 --- a/native/src/core/su/su_daemon.cpp +++ b/native/src/core/su/su_daemon.cpp @@ -159,8 +159,7 @@ void prune_su_access() { for (int uid : rm_uids) { ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid); - // Don't care about errors - db_exec(query); + db_err(db_exec(query)); } }