mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Enhanced denylist app id tracking
This commit is contained in:
parent
94d1c66f8a
commit
6aab856de7
@ -158,6 +158,7 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
|
|||||||
case +RequestCode::ZYGOTE_RESTART:
|
case +RequestCode::ZYGOTE_RESTART:
|
||||||
LOGI("** zygote restarted\n");
|
LOGI("** zygote restarted\n");
|
||||||
prune_su_access();
|
prune_su_access();
|
||||||
|
scan_deny_apps();
|
||||||
reset_zygisk(false);
|
reset_zygisk(false);
|
||||||
close(client);
|
close(client);
|
||||||
break;
|
break;
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
atomic_flag skip_pkg_rescan;
|
|
||||||
|
|
||||||
// For the following data structures:
|
// For the following data structures:
|
||||||
// If package name == ISOLATED_MAGIC, or app ID == -1, it means isolated service
|
// If package name == ISOLATED_MAGIC, or app ID == -1, it means isolated service
|
||||||
|
|
||||||
@ -33,47 +31,39 @@ static pthread_mutex_t data_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
|
|
||||||
atomic<bool> denylist_enforced = false;
|
atomic<bool> denylist_enforced = false;
|
||||||
|
|
||||||
static void rescan_apps() {
|
static int get_app_id(const vector<int> &users, const string &pkg) {
|
||||||
LOGD("denylist: rescanning apps\n");
|
struct stat st{};
|
||||||
|
char buf[PATH_MAX];
|
||||||
app_id_to_pkgs.clear();
|
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<int> &users) {
|
||||||
auto data_dir = xopen_dir(APP_DATA_DIR);
|
auto data_dir = xopen_dir(APP_DATA_DIR);
|
||||||
if (!data_dir)
|
if (!data_dir)
|
||||||
return;
|
return;
|
||||||
dirent *entry;
|
dirent *entry;
|
||||||
while ((entry = xreaddir(data_dir.get()))) {
|
while ((entry = xreaddir(data_dir.get()))) {
|
||||||
// For each user
|
users.emplace_back(parse_int(entry->d_name));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_pkg_uid(const string &pkg, bool remove) {
|
static int get_app_id(const string &pkg) {
|
||||||
auto data_dir = xopen_dir(APP_DATA_DIR);
|
if (pkg == ISOLATED_MAGIC)
|
||||||
if (!data_dir)
|
return -1;
|
||||||
|
vector<int> 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;
|
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 (remove) {
|
||||||
if (auto it = app_id_to_pkgs.find(app_id); it != app_id_to_pkgs.end()) {
|
if (auto it = app_id_to_pkgs.find(app_id); it != app_id_to_pkgs.end()) {
|
||||||
it->second.erase(pkg);
|
it->second.erase(pkg);
|
||||||
@ -82,10 +72,7 @@ static void update_pkg_uid(const string &pkg, bool remove) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
app_id_to_pkgs[app_id].insert(pkg);
|
app_id_to_pkgs[app_id].emplace(pkg);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +182,34 @@ static bool add_hide_set(const char *pkg, const char *proc) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scan_deny_apps() {
|
||||||
|
if (!app_id_to_pkgs_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
app_id_to_pkgs.clear();
|
||||||
|
|
||||||
|
char sql[4096];
|
||||||
|
vector<int> 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() {
|
static void clear_data() {
|
||||||
pkg_to_procs_.reset(nullptr);
|
pkg_to_procs_.reset(nullptr);
|
||||||
app_id_to_pkgs_.reset(nullptr);
|
app_id_to_pkgs_.reset(nullptr);
|
||||||
@ -214,7 +229,7 @@ static bool ensure_data() {
|
|||||||
db_err_cmd(err, goto error)
|
db_err_cmd(err, goto error)
|
||||||
|
|
||||||
default_new(app_id_to_pkgs_);
|
default_new(app_id_to_pkgs_);
|
||||||
rescan_apps();
|
scan_deny_apps();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -234,10 +249,13 @@ static int add_list(const char *pkg, const char *proc) {
|
|||||||
mutex_guard lock(data_lock);
|
mutex_guard lock(data_lock);
|
||||||
if (!ensure_data())
|
if (!ensure_data())
|
||||||
return DenyResponse::ERROR;
|
return DenyResponse::ERROR;
|
||||||
|
int app_id = get_app_id(pkg);
|
||||||
|
if (app_id == 0)
|
||||||
|
return DenyResponse::INVALID_PKG;
|
||||||
if (!add_hide_set(pkg, proc))
|
if (!add_hide_set(pkg, proc))
|
||||||
return DenyResponse::ITEM_EXIST;
|
return DenyResponse::ITEM_EXIST;
|
||||||
auto it = pkg_to_procs.find(pkg);
|
auto it = pkg_to_procs.find(pkg);
|
||||||
update_pkg_uid(it->first, false);
|
update_app_id(app_id, it->first, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to database
|
// Add to database
|
||||||
@ -266,7 +284,7 @@ static int rm_list(const char *pkg, const char *proc) {
|
|||||||
auto it = pkg_to_procs.find(pkg);
|
auto it = pkg_to_procs.find(pkg);
|
||||||
if (it != pkg_to_procs.end()) {
|
if (it != pkg_to_procs.end()) {
|
||||||
if (proc[0] == '\0') {
|
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);
|
pkg_to_procs.erase(it);
|
||||||
remove = true;
|
remove = true;
|
||||||
LOGI("denylist rm: [%s]\n", pkg);
|
LOGI("denylist rm: [%s]\n", pkg);
|
||||||
@ -274,7 +292,7 @@ static int rm_list(const char *pkg, const char *proc) {
|
|||||||
remove = true;
|
remove = true;
|
||||||
LOGI("denylist rm: [%s/%s]\n", pkg, proc);
|
LOGI("denylist rm: [%s/%s]\n", pkg, proc);
|
||||||
if (it->second.empty()) {
|
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);
|
pkg_to_procs.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,6 +327,7 @@ void ls_list(int client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scan_deny_apps();
|
||||||
write_int(client,static_cast<int>(DenyResponse::OK));
|
write_int(client,static_cast<int>(DenyResponse::OK));
|
||||||
|
|
||||||
for (const auto &[pkg, procs] : pkg_to_procs) {
|
for (const auto &[pkg, procs] : pkg_to_procs) {
|
||||||
@ -386,9 +405,6 @@ bool is_deny_target(int uid, string_view process) {
|
|||||||
if (!ensure_data())
|
if (!ensure_data())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!skip_pkg_rescan.test_and_set())
|
|
||||||
rescan_apps();
|
|
||||||
|
|
||||||
int app_id = to_app_id(uid);
|
int app_id = to_app_id(uid);
|
||||||
if (app_id >= 90000) {
|
if (app_id >= 90000) {
|
||||||
if (auto it = pkg_to_procs.find(ISOLATED_MAGIC); it != pkg_to_procs.end()) {
|
if (auto it = pkg_to_procs.find(ISOLATED_MAGIC); it != pkg_to_procs.end()) {
|
||||||
|
@ -86,9 +86,9 @@ void clear_pkg(const char *pkg, int user_id);
|
|||||||
[[noreturn]] void install_module(const char *file);
|
[[noreturn]] void install_module(const char *file);
|
||||||
|
|
||||||
// Denylist
|
// Denylist
|
||||||
extern std::atomic_flag skip_pkg_rescan;
|
|
||||||
extern std::atomic<bool> denylist_enforced;
|
extern std::atomic<bool> denylist_enforced;
|
||||||
int denylist_cli(int argc, char **argv);
|
int denylist_cli(int argc, char **argv);
|
||||||
void initialize_denylist();
|
void initialize_denylist();
|
||||||
|
void scan_deny_apps();
|
||||||
bool is_deny_target(int uid, std::string_view process);
|
bool is_deny_target(int uid, std::string_view process);
|
||||||
void revert_unmount(int pid = -1) noexcept;
|
void revert_unmount(int pid = -1) noexcept;
|
||||||
|
@ -38,7 +38,6 @@ void check_pkg_refresh() {
|
|||||||
memcpy(app_ts, &st.st_mtim, sizeof(timespec));
|
memcpy(app_ts, &st.st_mtim, sizeof(timespec));
|
||||||
}
|
}
|
||||||
skip_mgr_check = false;
|
skip_mgr_check = false;
|
||||||
skip_pkg_rescan.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// app_id = app_no + AID_APP_START
|
// app_id = app_no + AID_APP_START
|
||||||
|
@ -159,8 +159,7 @@ void prune_su_access() {
|
|||||||
|
|
||||||
for (int uid : rm_uids) {
|
for (int uid : rm_uids) {
|
||||||
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
|
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
|
||||||
// Don't care about errors
|
db_err(db_exec(query));
|
||||||
db_exec(query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user