From d8cd2031c7a45de3ac495996d7cd60bf2f476177 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 2 Mar 2019 04:24:41 -0500 Subject: [PATCH] SIGSTOP any possible process ASAP Shut down any UID matching process and resume if it turns out not to be our target. Since we will record every single process we have ever paused, this means that the same process will not be paused erroneously for another time. This is an optimization to hijack the app as soon as possible. --- native/jni/magiskhide/proc_monitor.cpp | 37 +++++++++++++------------- native/jni/utils/include/utils.h | 6 +++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/native/jni/magiskhide/proc_monitor.cpp b/native/jni/magiskhide/proc_monitor.cpp index 4588b6945..5e3265c4c 100644 --- a/native/jni/magiskhide/proc_monitor.cpp +++ b/native/jni/magiskhide/proc_monitor.cpp @@ -46,6 +46,7 @@ static inline void lazy_unmount(const char* mountpoint) { LOGD("hide_daemon: Unmounted (%s)\n", mountpoint); } +#if 0 static inline int parse_ppid(const int pid) { char path[32]; int ppid; @@ -61,6 +62,7 @@ static inline int parse_ppid(const int pid) { return ppid; } +#endif static void hide_daemon(int pid) { RunFinally fin([=]() -> void { @@ -132,21 +134,26 @@ static bool check_pid(int pid, int uid) { if (uid != get_uid(pid)) return true; - struct stat ns, pns; - int ppid; - - // Make sure we can read mount namespace - if ((ppid = parse_ppid(pid)) < 0 || read_ns(pid, &ns) || read_ns(ppid, &pns)) - return true; - // mount namespace is not separated, we only unmount once - if (ns.st_dev == pns.st_dev && ns.st_ino == pns.st_ino) + struct stat ns; + if (read_ns(pid, &ns)) return true; - // Check if it's a process we haven't already hijacked + // Check if we have already seen it before auto pos = pid_ns_map.find(pid); if (pos != pid_ns_map.end() && pos->second == ns.st_ino) return true; + // Will rather kill all just for one + if (kill(pid, SIGSTOP) == -1) + return true; + // Auto send resume signal if return + RunFinally resume([=]() -> void { + kill(pid, SIGCONT); + }); + + // Record this PID + pid_ns_map[pid] = ns.st_ino; + // Check whether process name match hide list const char *process = nullptr; for (auto &proc : uid_proc_map[uid]) @@ -156,20 +163,14 @@ static bool check_pid(int pid, int uid) { if (!process) return true; - // Send pause signal ASAP - if (kill(pid, SIGSTOP) == -1) - return true; - - pid_ns_map[pid] = ns.st_ino; LOGI("proc_monitor: [%s] UID=[%d] PID=[%d] ns=[%llu]\n", process, uid, pid, ns.st_ino); - /* - * The setns system call do not support multithread processes - * We have to fork a new process, setns, then do the unmounts - */ + // Disable auto resume PID, and let the daemon do it + resume.disable(); if (fork_dont_care() == 0) hide_daemon(pid); + // We found what we want, stop traversal return false; } diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 78bf9db9e..dc551d5d8 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -162,10 +162,12 @@ class RunFinally { public: explicit RunFinally(std::function &&fn): fn(std::move(fn)) {} - ~RunFinally() { fn(); } + void disable() { fn = nullptr; } + + ~RunFinally() { if (fn) fn(); } private: - const std::function fn; + std::function fn; }; // file.cpp