Commit 4e53ebfe authored by topjohnwu's avatar topjohnwu

Use both package name and process name as key

Different packages could potentially use the same process name,
and they shouldn't conflict with each other.
parent 04ef1e64
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <db.h> #include <db.h>
#include <daemon.h> #include <daemon.h>
#define DB_VERSION 8 #define DB_VERSION 9
static sqlite3 *mDB = nullptr; static sqlite3 *mDB = nullptr;
...@@ -133,28 +133,47 @@ static char *open_and_init_db(sqlite3 *&db) { ...@@ -133,28 +133,47 @@ static char *open_and_init_db(sqlite3 *&db) {
if (ver < 5) { if (ver < 5) {
sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", nullptr, nullptr, &err); sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", nullptr, nullptr, &err);
err_ret(err); err_ret(err);
/* Skip version 5 */ /* Directly jump to version 6 */
ver = 6; ver = 6;
upgrade = true; upgrade = true;
} }
if (ver < 7) { if (ver < 7) {
// Hide list
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS hidelist " "CREATE TABLE IF NOT EXISTS hidelist "
"(process TEXT, PRIMARY KEY(process))", "(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process));",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
ver = 7; /* Directly jump to version 9 */
ver = 9;
upgrade = true; upgrade = true;
} }
if (ver < 8) { if (ver < 8) {
sqlite3_exec(db, sqlite3_exec(db,
"ALTER TABLE hidelist ADD COLUMN package_name TEXT;" "BEGIN TRANSACTION;"
"SELECT process FROM hidelist;" "ALTER TABLE hidelist RENAME TO hidelist_tmp;"
"UPDATE hidelist SET package_name=process;", "CREATE TABLE IF NOT EXISTS hidelist "
"(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process));"
"INSERT INTO hidelist SELECT process as package_name, process FROM hidelist_tmp;"
"DROP TABLE hidelist_tmp;"
"COMMIT;",
nullptr, nullptr, &err);
err_ret(err);
/* Directly jump to version 9 */
ver = 9;
upgrade = true;
}
if (ver < 9) {
sqlite3_exec(db,
"BEGIN TRANSACTION;"
"ALTER TABLE hidelist RENAME TO hidelist_tmp;"
"CREATE TABLE IF NOT EXISTS hidelist "
"(package_name TEXT, process TEXT, PRIMARY KEY(package_name, process));"
"INSERT INTO hidelist SELECT * FROM hidelist_tmp;"
"DROP TABLE hidelist_tmp;"
"COMMIT;",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
ver = 8; ver = 9;
upgrade = true; upgrade = true;
} }
......
...@@ -123,7 +123,8 @@ static int add_list(const char *pkg, const char *proc = "") { ...@@ -123,7 +123,8 @@ static int add_list(const char *pkg, const char *proc = "") {
if (proc[0] == '\0') if (proc[0] == '\0')
proc = pkg; proc = pkg;
if (hide_map.count(proc)) for (auto &hide : hide_set)
if (hide.first == pkg && hide.second == proc)
return HIDE_ITEM_EXIST; return HIDE_ITEM_EXIST;
// Add to database // Add to database
...@@ -133,12 +134,12 @@ static int add_list(const char *pkg, const char *proc = "") { ...@@ -133,12 +134,12 @@ static int add_list(const char *pkg, const char *proc = "") {
char *err = db_exec(sql); char *err = db_exec(sql);
db_err_cmd(err, return DAEMON_ERROR); db_err_cmd(err, return DAEMON_ERROR);
LOGI("hide_list add: [%s]\n", proc); LOGI("hide_list add: [%s/%s]\n", pkg, proc);
// Critical region // Critical region
{ {
MutexGuard lock(monitor_lock); MutexGuard lock(monitor_lock);
hide_map[proc] = pkg; hide_set.emplace(pkg, proc);
} }
kill_process(proc); kill_process(proc);
...@@ -160,24 +161,15 @@ static int rm_list(const char *pkg, const char *proc = "") { ...@@ -160,24 +161,15 @@ static int rm_list(const char *pkg, const char *proc = "") {
// Critical region // Critical region
MutexGuard lock(monitor_lock); MutexGuard lock(monitor_lock);
bool remove = false; bool remove = false;
if (proc[0] == '\0') { auto next = hide_set.begin();
auto next = hide_map.begin();
decltype(next) cur; decltype(next) cur;
while (next != hide_map.end()) { while (next != hide_set.end()) {
cur = next; cur = next;
++next; ++next;
if (cur->second == pkg) { if (cur->first == pkg && (proc[0] == '\0' || cur->second == proc)) {
remove = true; remove = true;
LOGI("hide_list rm: [%s]\n", cur->first.data()); LOGI("hide_list rm: [%s]\n", cur->second.data());
hide_map.erase(cur); hide_set.erase(cur);
}
}
} else {
auto it = hide_map.find(proc);
if (it != hide_map.end()) {
remove = true;
hide_map.erase(it);
LOGI("hide_list rm: [%s]\n", proc);
} }
} }
if (!remove) if (!remove)
...@@ -188,7 +180,8 @@ static int rm_list(const char *pkg, const char *proc = "") { ...@@ -188,7 +180,8 @@ static int rm_list(const char *pkg, const char *proc = "") {
if (proc[0] == '\0') if (proc[0] == '\0')
snprintf(sql, sizeof(sql), "DELETE FROM hidelist WHERE package_name='%s'", pkg); snprintf(sql, sizeof(sql), "DELETE FROM hidelist WHERE package_name='%s'", pkg);
else else
snprintf(sql, sizeof(sql), "DELETE FROM hidelist WHERE process='%s'", proc); snprintf(sql, sizeof(sql),
"DELETE FROM hidelist WHERE package_name='%s' AND process='%s'", pkg, proc);
char *err = db_exec(sql); char *err = db_exec(sql);
db_err(err); db_err(err);
return DAEMON_SUCCESS; return DAEMON_SUCCESS;
...@@ -206,8 +199,8 @@ int rm_list(int client) { ...@@ -206,8 +199,8 @@ int rm_list(int client) {
} }
static void init_list(const char *pkg, const char *proc) { static void init_list(const char *pkg, const char *proc) {
LOGI("hide_list init: [%s]\n", proc); LOGI("hide_list init: [%s/%s]\n", pkg, proc);
hide_map[proc] = pkg; hide_set.emplace(pkg, proc);
kill_process(proc); kill_process(proc);
} }
...@@ -242,6 +235,7 @@ bool init_list() { ...@@ -242,6 +235,7 @@ bool init_list() {
// Add SafetyNet by default // Add SafetyNet by default
rm_list(SAFETYNET_COMPONENT); rm_list(SAFETYNET_COMPONENT);
rm_list(SAFETYNET_PROCESS);
init_list(SAFETYNET_PKG, SAFETYNET_PROCESS); init_list(SAFETYNET_PKG, SAFETYNET_PROCESS);
update_uid_map(); update_uid_map();
...@@ -250,8 +244,8 @@ bool init_list() { ...@@ -250,8 +244,8 @@ bool init_list() {
void ls_list(int client) { void ls_list(int client) {
FILE *out = fdopen(recv_fd(client), "a"); FILE *out = fdopen(recv_fd(client), "a");
for (auto &s : hide_map) for (auto &hide : hide_set)
fprintf(out, "%s|%s\n", s.second.data(), s.first.data()); fprintf(out, "%s|%s\n", hide.first.data(), hide.second.data());
fclose(out); fclose(out);
write_int(client, DAEMON_SUCCESS); write_int(client, DAEMON_SUCCESS);
close(client); close(client);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include <functional> #include <functional>
#include <map> #include <map>
#include <set>
#include "daemon.h" #include "daemon.h"
...@@ -54,7 +55,7 @@ static inline int parse_int(const char *s) { ...@@ -54,7 +55,7 @@ static inline int parse_int(const char *s) {
extern bool hide_enabled; extern bool hide_enabled;
extern pthread_mutex_t monitor_lock; extern pthread_mutex_t monitor_lock;
extern std::map<std::string, std::string> hide_map; extern std::set<std::pair<std::string, std::string>> hide_set;
extern int next_zygote; extern int next_zygote;
enum { enum {
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <set>
#include <magisk.h> #include <magisk.h>
#include <utils.h> #include <utils.h>
...@@ -39,7 +38,7 @@ static void new_zygote(int pid); ...@@ -39,7 +38,7 @@ static void new_zygote(int pid);
* All the maps and sets * All the maps and sets
************************/ ************************/
map<string, string> hide_map; /* process -> package_name */ set<pair<string, string>> hide_set; /* set of <pkg, process> pair */
static map<int, struct stat> zygote_map; /* zygote pid -> mnt ns */ static map<int, struct stat> zygote_map; /* zygote pid -> mnt ns */
static map<int, vector<string_view>> uid_proc_map; /* uid -> list of process */ static map<int, vector<string_view>> uid_proc_map; /* uid -> list of process */
...@@ -88,7 +87,7 @@ static bool parse_packages_xml(string_view s) { ...@@ -88,7 +87,7 @@ static bool parse_packages_xml(string_view s) {
start += 9; /* Skip '<package ' */ start += 9; /* Skip '<package ' */
char key[32], value[1024]; char key[32], value[1024];
char *pkg = nullptr; const char *pkg = nullptr;
char *tok; char *tok;
while ((tok = strtok_r(nullptr, " ", &start))) { while ((tok = strtok_r(nullptr, " ", &start))) {
...@@ -96,9 +95,9 @@ static bool parse_packages_xml(string_view s) { ...@@ -96,9 +95,9 @@ static bool parse_packages_xml(string_view s) {
string_view key_view(key); string_view key_view(key);
string_view value_view(value); string_view value_view(value);
if (key_view == "name") { if (key_view == "name") {
for (auto &hide : hide_map) { for (auto &hide : hide_set) {
if (hide.second == value_view) { if (hide.first == value_view) {
pkg = hide.second.data(); pkg = hide.first.data();
break; break;
} }
} }
...@@ -106,9 +105,9 @@ static bool parse_packages_xml(string_view s) { ...@@ -106,9 +105,9 @@ static bool parse_packages_xml(string_view s) {
return true; return true;
} else if (key_view == "userId" || key_view == "sharedUserId") { } else if (key_view == "userId" || key_view == "sharedUserId") {
int uid = parse_int(value); int uid = parse_int(value);
for (auto &hide : hide_map) { for (auto &hide : hide_set) {
if (hide.second == pkg) if (hide.first == pkg)
uid_proc_map[uid].emplace_back(hide.first); uid_proc_map[uid].emplace_back(hide.second);
} }
} }
} }
...@@ -215,10 +214,10 @@ static void zygote_sig(int) { ...@@ -215,10 +214,10 @@ static void zygote_sig(int) {
static void term_thread(int) { static void term_thread(int) {
LOGD("proc_monitor: cleaning up\n"); LOGD("proc_monitor: cleaning up\n");
// Clear maps // Clear maps
hide_map.clear();
uid_proc_map.clear(); uid_proc_map.clear();
zygote_map.clear(); zygote_map.clear();
// Clear sets // Clear sets
hide_set.clear();
attaches.clear(); attaches.clear();
detaches.clear(); detaches.clear();
unknown.clear(); unknown.clear();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment