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.
This commit is contained in:
topjohnwu 2019-03-06 05:40:52 -05:00
parent 04ef1e6405
commit 4e53ebfe44
4 changed files with 79 additions and 66 deletions

View File

@ -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;
@ -99,23 +99,23 @@ static char *open_and_init_db(sqlite3 *&db) {
if (ver < 3) { if (ver < 3) {
// Policies // Policies
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS policies " "CREATE TABLE IF NOT EXISTS policies "
"(uid INT, package_name TEXT, policy INT, until INT, " "(uid INT, package_name TEXT, policy INT, until INT, "
"logging INT, notification INT, PRIMARY KEY(uid))", "logging INT, notification INT, PRIMARY KEY(uid))",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
// Logs // Logs
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS logs " "CREATE TABLE IF NOT EXISTS logs "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " "(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"to_uid INT, action INT, time INT, command TEXT)", "to_uid INT, action INT, time INT, command TEXT)",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
// Settings // Settings
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS settings " "CREATE TABLE IF NOT EXISTS settings "
"(key TEXT, value INT, PRIMARY KEY(key))", "(key TEXT, value INT, PRIMARY KEY(key))",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
ver = 3; ver = 3;
upgrade = true; upgrade = true;
@ -123,9 +123,9 @@ static char *open_and_init_db(sqlite3 *&db) {
if (ver < 4) { if (ver < 4) {
// Strings // Strings
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS strings " "CREATE TABLE IF NOT EXISTS strings "
"(key TEXT, value TEXT, PRIMARY KEY(key))", "(key TEXT, value TEXT, PRIMARY KEY(key))",
nullptr, nullptr, &err); nullptr, nullptr, &err);
err_ret(err); err_ret(err);
ver = 4; ver = 4;
upgrade = true; upgrade = true;
@ -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 "
nullptr, nullptr, &err); "(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); err_ret(err);
ver = 8; /* 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);
err_ret(err);
ver = 9;
upgrade = true; upgrade = true;
} }

View File

@ -123,8 +123,9 @@ 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)
return HIDE_ITEM_EXIST; if (hide.first == pkg && hide.second == proc)
return HIDE_ITEM_EXIST;
// Add to database // Add to database
char sql[4096]; char sql[4096];
@ -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 = "") {
// 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_set.end()) {
while (next != hide_map.end()) { cur = next;
cur = next; ++next;
++next; if (cur->first == pkg && (proc[0] == '\0' || cur->second == proc)) {
if (cur->second == pkg) {
remove = true;
LOGI("hide_list rm: [%s]\n", cur->first.data());
hide_map.erase(cur);
}
}
} else {
auto it = hide_map.find(proc);
if (it != hide_map.end()) {
remove = true; remove = true;
hide_map.erase(it); LOGI("hide_list rm: [%s]\n", cur->second.data());
LOGI("hide_list rm: [%s]\n", proc); hide_set.erase(cur);
} }
} }
if (!remove) if (!remove)
@ -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) {
} }
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() {
// 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() {
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);

View File

@ -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) {
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 {

View File

@ -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);
* 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) {
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) {
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) {
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);
} }
} }
} }
@ -184,9 +183,9 @@ static void inotify_event(int) {
/* Make sure we can actually read stuffs /* Make sure we can actually read stuffs
* or else the whole thread will be blocked.*/ * or else the whole thread will be blocked.*/
struct pollfd pfd = { struct pollfd pfd = {
.fd = inotify_fd, .fd = inotify_fd,
.events = POLLIN, .events = POLLIN,
.revents = 0 .revents = 0
}; };
if (poll(&pfd, 1, 0) <= 0) if (poll(&pfd, 1, 0) <= 0)
return; // Nothing to read return; // Nothing to read
@ -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();