Properly detect package changes

This commit is contained in:
topjohnwu 2024-01-28 00:42:43 -08:00
parent 930bb8687f
commit 308c9999fa
3 changed files with 15 additions and 11 deletions

View File

@ -157,7 +157,6 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
break; break;
case +RequestCode::ZYGOTE_RESTART: case +RequestCode::ZYGOTE_RESTART:
LOGI("** zygote restarted\n"); LOGI("** zygote restarted\n");
pkg_xml_ino = 0;
prune_su_access(); prune_su_access();
reset_zygisk(false); reset_zygisk(false);
close(client); close(client);

View File

@ -62,7 +62,6 @@ void su_daemon_handler(int client, const sock_cred *cred);
void zygisk_handler(int client, const sock_cred *cred); void zygisk_handler(int client, const sock_cred *cred);
// Package // Package
extern std::atomic<ino_t> pkg_xml_ino;
void preserve_stub_apk(); void preserve_stub_apk();
void check_pkg_refresh(); void check_pkg_refresh();
std::vector<bool> get_app_no_list(); std::vector<bool> get_app_no_list();

View File

@ -13,12 +13,11 @@ using rust::Vec;
// so performance is absolutely critical. Most operations should either have its result cached // so performance is absolutely critical. Most operations should either have its result cached
// or simply skipped unless necessary. // or simply skipped unless necessary.
atomic<ino_t> pkg_xml_ino = 0;
static atomic_flag skip_mgr_check;
static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t pkg_lock = PTHREAD_MUTEX_INITIALIZER;
// pkg_lock protects all following variables // pkg_lock protects all following variables
static int mgr_app_id = -1; static int mgr_app_id = -1;
static bool skip_mgr_check;
static timespec *app_ts;
static string *mgr_pkg; static string *mgr_pkg;
static Vec<uint8_t> *mgr_cert; static Vec<uint8_t> *mgr_cert;
static int stub_apk_fd = -1; static int stub_apk_fd = -1;
@ -29,12 +28,17 @@ static bool operator==(const Vec<uint8_t> &a, const Vec<uint8_t> &b) {
} }
void check_pkg_refresh() { void check_pkg_refresh() {
struct stat st{}; mutex_guard g(pkg_lock);
if (stat("/data/system/packages.xml", &st) == 0 && if (app_ts == nullptr)
pkg_xml_ino.exchange(st.st_ino) != st.st_ino) { default_new(app_ts);
skip_mgr_check.clear(); if (struct stat st{}; stat("/data/app", &st) == 0) {
skip_pkg_rescan.clear(); 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 // app_id = app_no + AID_APP_START
@ -124,7 +128,7 @@ int get_manager(int user_id, string *pkg, bool install) {
return true; return true;
}; };
if (skip_mgr_check.test_and_set()) { if (skip_mgr_check) {
if (mgr_app_id >= 0) { if (mgr_app_id >= 0) {
// Just need to check whether the app is installed in the user // Just need to check whether the app is installed in the user
const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data(); 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. // This means that we check all users, not just the requested user.
// Certificates are also verified to prevent manipulation. // Certificates are also verified to prevent manipulation.
skip_mgr_check = true;
db_strings str; db_strings str;
get_db_strings(str, SU_MANAGER); get_db_strings(str, SU_MANAGER);