Use large vector<bool> instead of set<pid>

vector<bool> uses bitsets, so we actually only use 12k memory to
store all 3 possible PID info tables. PID checkup will be now become
O(1) instead of O(logn).

P.S. The reason why we don't use unordered_map is because including it
will result in significant binary size increase (might be due to the
complex hash table STL implementation? I really don't know).
This commit is contained in:
topjohnwu 2019-03-09 22:28:43 -05:00
parent a46e255709
commit faf4d76388

View File

@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <vector>
#include <magisk.h>
#include <utils.h>
@ -34,9 +35,9 @@ static int inotify_fd = -1;
static void term_thread(int sig = SIGTERMTHRD);
static void new_zygote(int pid);
/************************
* All the maps and sets
************************/
/**********************
* All data structures
**********************/
set<pair<string, string>> hide_set; /* set of <pkg, process> pair */
static map<int, struct stat> zygote_map; /* zygote pid -> mnt ns */
@ -44,9 +45,10 @@ static map<int, vector<string_view>> uid_proc_map; /* uid -> list of process */
pthread_mutex_t monitor_lock;
static set<int> attaches; /* A set of pid that should be attached */
static set<int> detaches; /* A set of tid that should be detached */
static set<int> unknown; /* A set of pid/tid that is unknown */
#define PID_MAX 32768
static vector<bool> attaches(PID_MAX); /* true if pid should be monitored */
static vector<bool> detaches(PID_MAX); /* true if tid should be detached */
static vector<bool> unknowns(PID_MAX); /* true if pid/tid is in unknown state */
/********
* Utils
@ -240,14 +242,12 @@ static void inotify_event(int) {
// Workaround for the lack of pthread_cancel
static void term_thread(int) {
LOGD("proc_monitor: cleaning up\n");
// Clear maps
uid_proc_map.clear();
zygote_map.clear();
// Clear sets
hide_set.clear();
attaches.clear();
detaches.clear();
unknown.clear();
std::fill(attaches.begin(), attaches.end(), false);
std::fill(detaches.begin(), detaches.end(), false);
std::fill(unknowns.begin(), unknowns.end(), false);
// Misc
hide_enabled = false;
pthread_mutex_destroy(&monitor_lock);
@ -282,7 +282,7 @@ static bool check_pid(int pid) {
/* This process is fully initialized, we will stop
* tracing it no matter if it is a target or not. */
attaches.erase(pid);
attaches[pid] = false;
sprintf(path, "/proc/%d", pid);
struct stat st;
@ -324,8 +324,8 @@ static bool check_pid(int pid) {
}
static void handle_unknown(int tid, int pid = -1) {
if (unknown.count(tid)) {
unknown.erase(tid);
if (unknowns[pid]) {
unknowns[pid] = false;
tgkill(pid < 0 ? tid : pid, tid, SIGSTOP);
}
}
@ -388,9 +388,9 @@ void proc_monitor() {
if (pid < 0)
continue;
if (WIFSTOPPED(status)) {
if (detaches.count(pid)) {
if (detaches[pid]) {
PTRACE_LOG("detach\n");
detaches.erase(pid);
detaches[pid] = false;
xptrace(PTRACE_DETACH, pid);
continue;
}
@ -403,7 +403,7 @@ void proc_monitor() {
case PTRACE_EVENT_FORK:
case PTRACE_EVENT_VFORK:
PTRACE_LOG("zygote forked: [%d]\n", msg);
attaches.insert(msg);
attaches[msg] = true;
handle_unknown(msg);
break;
case PTRACE_EVENT_EXIT:
@ -419,15 +419,15 @@ void proc_monitor() {
switch (WEVENT(status)) {
case PTRACE_EVENT_CLONE:
PTRACE_LOG("create new threads: [%d]\n", msg);
detaches.insert(msg);
detaches[msg] = true;
handle_unknown(msg, pid);
if (attaches.count(pid) && check_pid(pid))
if (attaches[pid] && check_pid(pid))
continue;
break;
case PTRACE_EVENT_EXIT:
PTRACE_LOG("exited with status: [%d]\n", msg);
attaches.erase(pid);
unknown.erase(pid);
attaches[pid] = false;
unknowns[pid] = false;
break;
default:
PTRACE_LOG("unknown event: %d\n", WEVENT(status));
@ -436,12 +436,12 @@ void proc_monitor() {
xptrace(PTRACE_CONT, pid);
}
} else if (WSTOPSIG(status) == SIGSTOP) {
if (attaches.count(pid)) {
if (attaches[pid]) {
PTRACE_LOG("SIGSTOP from zygote child\n");
xptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT);
} else {
PTRACE_LOG("SIGSTOP from unknown\n");
unknown.insert(pid);
unknowns[pid] = true;
}
xptrace(PTRACE_CONT, pid);
} else {