Support hiding apps not installed in main user

Fix #2181, close #1840
This commit is contained in:
topjohnwu 2020-11-08 01:53:18 -08:00
parent 2739d3cb67
commit ade1597e03
2 changed files with 28 additions and 21 deletions

View File

@ -24,7 +24,7 @@ void ls_list(int client);
[[noreturn]] void test_proc_monitor(); [[noreturn]] void test_proc_monitor();
// Process monitoring // Process monitoring
void proc_monitor(); [[noreturn]] void proc_monitor();
void update_uid_map(); void update_uid_map();
// Utility functions // Utility functions

View File

@ -56,7 +56,7 @@ static int parse_ppid(int pid) {
if (stat == nullptr) if (stat == nullptr)
return -1; return -1;
/* PID COMM STATE PPID ..... */ // PID COMM STATE PPID .....
fscanf(stat, "%*d %*s %*c %d", &ppid); fscanf(stat, "%*d %*s %*c %d", &ppid);
fclose(stat); fclose(stat);
@ -78,15 +78,23 @@ void update_uid_map() {
mutex_guard lock(monitor_lock); mutex_guard lock(monitor_lock);
uid_proc_map.clear(); uid_proc_map.clear();
string data_path(APP_DATA_DIR); string data_path(APP_DATA_DIR);
data_path += "/0/";
size_t len = data_path.length(); size_t len = data_path.length();
struct stat st; auto dir = open_dir(APP_DATA_DIR);
for (auto &hide : hide_set) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
data_path.erase(data_path.begin() + len, data_path.end()); data_path += '/';
data_path += hide.first; data_path += entry->d_name;
if (stat(data_path.data(), &st)) data_path += '/';
continue; size_t user_len = data_path.length();
uid_proc_map[st.st_uid].emplace_back(hide.second); struct stat st;
for (auto &hide : hide_set) {
data_path.resize(user_len);
data_path += hide.first;
if (stat(data_path.data(), &st))
continue;
uid_proc_map[st.st_uid].emplace_back(hide.second);
}
// Reset string
data_path.resize(len);
} }
} }
@ -178,9 +186,9 @@ static void term_thread(int) {
* Ptrace Madness * Ptrace Madness
******************/ ******************/
/* Ptrace is super tricky, preserve all excessive logging in code // Ptrace is super tricky, preserve all excessive logging in code
* but disable when actually building for usage (you won't want // but disable when actually building for usage (you won't want
* your logcat spammed with new thread events from all apps) */ // your logcat spammed with new thread events from all apps)
//#define PTRACE_LOG(fmt, args...) LOGD("PID=[%d] " fmt, pid, ##args) //#define PTRACE_LOG(fmt, args...) LOGD("PID=[%d] " fmt, pid, ##args)
#define PTRACE_LOG(...) #define PTRACE_LOG(...)
@ -208,9 +216,8 @@ static bool check_pid(int pid) {
return false; return false;
sprintf(path, "/proc/%d/cmdline", pid); sprintf(path, "/proc/%d/cmdline", pid);
if (FILE *f; (f = fopen(path, "re"))) { if (auto f = open_file(path, "re")) {
fgets(cmdline, sizeof(cmdline), f); fgets(cmdline, sizeof(cmdline), f.get());
fclose(f);
} else { } else {
// Process killed unexpectedly, ignore // Process killed unexpectedly, ignore
detach_pid(pid); detach_pid(pid);
@ -221,7 +228,7 @@ static bool check_pid(int pid) {
cmdline == "usap32"sv || cmdline == "usap64"sv) cmdline == "usap32"sv || cmdline == "usap64"sv)
return false; return false;
int uid = st.st_uid % 100000; int uid = st.st_uid;
auto it = uid_proc_map.find(uid); auto it = uid_proc_map.find(uid);
if (it != uid_proc_map.end()) { if (it != uid_proc_map.end()) {
for (auto &s : it->second) { for (auto &s : it->second) {
@ -240,9 +247,9 @@ static bool check_pid(int pid) {
if (!mnt_ns) if (!mnt_ns)
break; break;
/* Finally this is our target! // Finally this is our target!
* Detach from ptrace but should still remain stopped. // Detach from ptrace but should still remain stopped.
* The hide daemon will resume the process. */ // The hide daemon will resume the process.
PTRACE_LOG("target found\n"); PTRACE_LOG("target found\n");
LOGI("proc_monitor: [%s] PID=[%d] UID=[%d]\n", cmdline, pid, uid); LOGI("proc_monitor: [%s] PID=[%d] UID=[%d]\n", cmdline, pid, uid);
detach_pid(pid, SIGSTOP); detach_pid(pid, SIGSTOP);
@ -261,7 +268,7 @@ static bool is_process(int pid) {
char key[32]; char key[32];
int tgid; int tgid;
sprintf(buf, "/proc/%d/status", pid); sprintf(buf, "/proc/%d/status", pid);
unique_ptr<FILE, decltype(&fclose)> fp(fopen(buf, "re"), &fclose); auto fp = open_file(buf, "re");
// PID is dead // PID is dead
if (!fp) if (!fp)
return false; return false;