From 308c9999fa6f608fc0add8c9dca85c698531af41 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 28 Jan 2024 00:42:43 -0800 Subject: [PATCH] Properly detect package changes --- native/src/core/daemon.cpp | 1 - native/src/core/include/core.hpp | 1 - native/src/core/package.cpp | 24 +++++++++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/native/src/core/daemon.cpp b/native/src/core/daemon.cpp index 6e739995f..a944cebd3 100644 --- a/native/src/core/daemon.cpp +++ b/native/src/core/daemon.cpp @@ -157,7 +157,6 @@ static void handle_request_async(int client, int code, const sock_cred &cred) { break; case +RequestCode::ZYGOTE_RESTART: LOGI("** zygote restarted\n"); - pkg_xml_ino = 0; prune_su_access(); reset_zygisk(false); close(client); diff --git a/native/src/core/include/core.hpp b/native/src/core/include/core.hpp index 3051c36c2..879d93825 100644 --- a/native/src/core/include/core.hpp +++ b/native/src/core/include/core.hpp @@ -62,7 +62,6 @@ void su_daemon_handler(int client, const sock_cred *cred); void zygisk_handler(int client, const sock_cred *cred); // Package -extern std::atomic pkg_xml_ino; void preserve_stub_apk(); void check_pkg_refresh(); std::vector get_app_no_list(); diff --git a/native/src/core/package.cpp b/native/src/core/package.cpp index 2db1c6f20..70ab7e2d7 100644 --- a/native/src/core/package.cpp +++ b/native/src/core/package.cpp @@ -13,12 +13,11 @@ using rust::Vec; // so performance is absolutely critical. Most operations should either have its result cached // or simply skipped unless necessary. -atomic pkg_xml_ino = 0; -static atomic_flag skip_mgr_check; - static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER; // pkg_lock protects all following variables static int mgr_app_id = -1; +static bool skip_mgr_check; +static timespec *app_ts; static string *mgr_pkg; static Vec *mgr_cert; static int stub_apk_fd = -1; @@ -29,12 +28,17 @@ static bool operator==(const Vec &a, const Vec &b) { } void check_pkg_refresh() { - struct stat st{}; - 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(); + mutex_guard g(pkg_lock); + if (app_ts == nullptr) + default_new(app_ts); + if (struct stat st{}; stat("/data/app", &st) == 0) { + if (memcmp(app_ts, &st.st_mtim, sizeof(timespec)) == 0) { + return; + } + memcpy(app_ts, &st.st_mtim, sizeof(timespec)); } + skip_mgr_check = false; + skip_pkg_rescan.clear(); } // app_id = app_no + AID_APP_START @@ -124,7 +128,7 @@ int get_manager(int user_id, string *pkg, bool install) { return true; }; - if (skip_mgr_check.test_and_set()) { + if (skip_mgr_check) { if (mgr_app_id >= 0) { // Just need to check whether the app is installed in the user const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data(); @@ -144,6 +148,8 @@ int get_manager(int user_id, string *pkg, bool install) { // This means that we check all users, not just the requested user. // Certificates are also verified to prevent manipulation. + skip_mgr_check = true; + db_strings str; get_db_strings(str, SU_MANAGER);