From d0c4226997eea7ab925a70cc96847c05c418110e Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 29 May 2022 23:31:57 -0700 Subject: [PATCH] Proper package state management --- native/build.gradle.kts | 3 +-- native/jni/core/bootstages.cpp | 2 +- native/jni/core/package.cpp | 18 +++++++----------- native/jni/include/daemon.hpp | 5 ++++- native/jni/su/su_daemon.cpp | 9 ++++----- native/jni/zygisk/deny/utils.cpp | 8 ++++---- native/jni/zygisk/entry.cpp | 1 + 7 files changed, 22 insertions(+), 24 deletions(-) diff --git a/native/build.gradle.kts b/native/build.gradle.kts index 50ac4a1fe..caf3fdc3a 100644 --- a/native/build.gradle.kts +++ b/native/build.gradle.kts @@ -18,8 +18,7 @@ android { ndkBuild { // Pass arguments to ndk-build. arguments( - "B_MAGISK=1", "B_INIT=1", "B_BOOT=1", "B_TEST=1", "B_POLICY=1", "B_PRELOAD=1", - "MAGISK_DEBUG=1", "MAGISK_VERSION=debug", "MAGISK_VER_CODE=INT_MAX" + "B_MAGISK=1", "B_INIT=1", "B_BOOT=1", "B_TEST=1", "B_POLICY=1", "B_PRELOAD=1" ) } } diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 5cc305a2c..668ca926a 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -366,7 +366,7 @@ void boot_complete(int client) { xmkdir(SECURE_DIR, 0700); // Ensure manager exists - need_pkg_refresh(); + check_pkg_refresh(); get_manager(0, nullptr, true); } diff --git a/native/jni/core/package.cpp b/native/jni/core/package.cpp index adc65e898..8fa0c28f7 100644 --- a/native/jni/core/package.cpp +++ b/native/jni/core/package.cpp @@ -15,7 +15,7 @@ using namespace std; // or simply skipped unless necessary. atomic pkg_xml_ino = 0; -static atomic_flag skip_check; +static atomic_flag skip_mgr_check; static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER; // pkg_lock protects all following variables @@ -25,16 +25,12 @@ static string *mgr_cert; static int stub_apk_fd = -1; static const string *default_cert; -bool need_pkg_refresh() { +void check_pkg_refresh() { struct stat st{}; - stat("/data/system/packages.xml", &st); - ino_t ino = pkg_xml_ino.exchange(st.st_ino); - if (ino == st.st_ino) { - // Packages have not changed - return false; - } else { - skip_check.clear(); - return true; + if (stat("/data/system/packages.xml", &st) == 0 && + pkg_xml_ino.exchange(st.st_ino) != st.st_ino) { + skip_mgr_check.clear(); + skip_pkg_rescan.clear(); } } @@ -120,7 +116,7 @@ int get_manager(int user_id, string *pkg, bool install) { return true; }; - if (skip_check.test_and_set()) { + if (skip_mgr_check.test_and_set()) { if (mgr_app_id < 0) { goto not_found; } diff --git a/native/jni/include/daemon.hpp b/native/jni/include/daemon.hpp index 4dccb75a4..2e2654acf 100644 --- a/native/jni/include/daemon.hpp +++ b/native/jni/include/daemon.hpp @@ -89,11 +89,14 @@ void zygisk_handler(int client, const sock_cred *cred); // Package void preserve_stub_apk(); -bool need_pkg_refresh(); +void check_pkg_refresh(); std::vector get_app_no_list(); +// Call check_pkg_refresh() before calling get_manager(...) +// to make sure the package state is invalidated! int get_manager(int user_id = 0, std::string *pkg = nullptr, bool install = false); void prune_su_access(); // Denylist +extern std::atomic_flag skip_pkg_rescan; void initialize_denylist(); int denylist_cli(int argc, char **argv); diff --git a/native/jni/su/su_daemon.cpp b/native/jni/su/su_daemon.cpp index f9411b3c0..b98b2dc6d 100644 --- a/native/jni/su/su_daemon.cpp +++ b/native/jni/su/su_daemon.cpp @@ -81,8 +81,10 @@ void su_info::check_db() { } // We need to check our manager - if (access.log || access.notify) + if (access.log || access.notify) { + check_pkg_refresh(); mgr_uid = get_manager(to_user_id(eval_uid), &mgr_pkg, true); + } } bool uid_granted_root(int uid) { @@ -138,6 +140,7 @@ bool uid_granted_root(int uid) { } void prune_su_access() { + cached.reset(); vector app_no_list = get_app_no_list(); vector rm_uids; char query[256], *err; @@ -170,10 +173,6 @@ static shared_ptr get_su_info(unsigned uid) { { mutex_guard lock(cache_lock); - if (need_pkg_refresh()) { - cached.reset(); - prune_su_access(); - } if (!cached || cached->uid != uid || !cached->is_fresh()) cached = make_shared(uid); cached->refresh(); diff --git a/native/jni/zygisk/deny/utils.cpp b/native/jni/zygisk/deny/utils.cpp index f36f94837..dd9aff847 100644 --- a/native/jni/zygisk/deny/utils.cpp +++ b/native/jni/zygisk/deny/utils.cpp @@ -14,6 +14,8 @@ 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,9 +35,6 @@ atomic denylist_enforced = false; #define do_kill (zygisk_enabled && denylist_enforced) static void rescan_apps() { - if (!need_pkg_refresh()) - return; - LOGD("denylist: rescanning apps\n"); app_id_to_pkgs.clear(); @@ -386,7 +385,8 @@ bool is_deny_target(int uid, string_view process) { if (!ensure_data()) return false; - rescan_apps(); + if (!skip_pkg_rescan.test_and_set()) + rescan_apps(); int app_id = to_app_id(uid); if (app_id >= 90000) { diff --git a/native/jni/zygisk/entry.cpp b/native/jni/zygisk/entry.cpp index 1c9d447a2..5f9135d3e 100644 --- a/native/jni/zygisk/entry.cpp +++ b/native/jni/zygisk/entry.cpp @@ -319,6 +319,7 @@ static void get_process_info(int client, const sock_cred *cred) { uint32_t flags = 0; + check_pkg_refresh(); if (is_deny_target(uid, process)) { flags |= PROCESS_ON_DENYLIST; }