Fix MagiskHide unmount daemon

Close #1101
This commit is contained in:
topjohnwu 2019-02-19 01:50:41 -05:00
parent 3ebc886f8a
commit 660e0dc09a
2 changed files with 42 additions and 19 deletions

View File

@ -95,41 +95,52 @@ static bool is_snet(const int pid) {
} }
static void hide_daemon(int pid) { static void hide_daemon(int pid) {
char buffer[4096]; RunFinally fin([=]() -> void {
// Send resume signal
kill(pid, SIGCONT);
_exit(0);
});
if (switch_mnt_ns(pid)) if (switch_mnt_ns(pid))
goto exit; return;
LOGD("hide_daemon: handling PID=[%d]\n", pid); LOGD("hide_daemon: handling PID=[%d]\n", pid);
manage_selinux(); manage_selinux();
clean_magisk_props(); clean_magisk_props();
snprintf(buffer, sizeof(buffer), "/proc/%d", pid);
chdir(buffer); vector<string> targets;
// Unmount dummy skeletons and /sbin links // Unmount dummy skeletons and /sbin links
file_readline("mounts", [&](string_view &s) -> bool { file_readline("/proc/self/mounts", [&](string_view &s) -> bool {
if (str_contains(s, "tmpfs /system/") || str_contains(s, "tmpfs /vendor/") || if (str_contains(s, "tmpfs /system/") || str_contains(s, "tmpfs /vendor/") ||
str_contains(s, "tmpfs /sbin")) { str_contains(s, "tmpfs /sbin")) {
sscanf(s.data(), "%*s %4096s", buffer); char *path = (char *) s.data();
lazy_unmount(buffer); // Skip first token
strtok_r(nullptr, " ", &path);
targets.emplace_back(strtok_r(nullptr, " ", &path));
} }
return true; return true;
}); });
for (auto &s : targets)
lazy_unmount(s.data());
targets.clear();
// Unmount everything under /system, /vendor, and data mounts // Unmount everything under /system, /vendor, and data mounts
file_readline("mounts", [&](string_view &s) -> bool { file_readline("/proc/self/mounts", [&](string_view &s) -> bool {
if ((str_contains(s, " /system/") || str_contains(s, " /vendor/")) && if ((str_contains(s, " /system/") || str_contains(s, " /vendor/")) &&
(str_contains(s, system_block) || str_contains(s, vendor_block) || (str_contains(s, system_block) || str_contains(s, vendor_block) ||
str_contains(s, data_block))) { str_contains(s, data_block))) {
sscanf(s.data(), "%*s %4096s", buffer); char *path = (char *) s.data();
lazy_unmount(buffer); // Skip first token
strtok_r(nullptr, " ", &path);
targets.emplace_back(strtok_r(nullptr, " ", &path));
} }
return true; return true;
}); });
exit: for (auto &s : targets)
// Send resume signal lazy_unmount(s.data());
kill(pid, SIGCONT);
_exit(0);
} }
// A mapping from pid to namespace inode to avoid time-consuming GC // A mapping from pid to namespace inode to avoid time-consuming GC

View File

@ -146,11 +146,7 @@ void write_zero(int fd, size_t size);
#define str_contains(s, ss) ((ss) != nullptr && (s).find(ss) != std::string::npos) #define str_contains(s, ss) ((ss) != nullptr && (s).find(ss) != std::string::npos)
#define str_starts(s, ss) ((ss) != nullptr && (s).compare(0, strlen(ss), ss) == 0) #define str_starts(s, ss) ((ss) != nullptr && (s).compare(0, strlen(ss), ss) == 0)
// file.cpp // RAII
void file_readline(const char *filename, const std::function<bool (std::string_view&)> &fn, bool trim = false);
// misc.cpp
class MutexGuard { class MutexGuard {
public: public:
@ -170,6 +166,22 @@ private:
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
}; };
class RunFinally {
public:
explicit RunFinally(std::function<void()> &&fn): fn(std::move(fn)) {}
~RunFinally() { fn(); }
private:
const std::function<void ()> fn;
};
// file.cpp
void file_readline(const char *filename, const std::function<bool (std::string_view&)> &fn, bool trim = false);
// misc.cpp
int new_daemon_thread(void *(*start_routine) (void *), void *arg = nullptr, int new_daemon_thread(void *(*start_routine) (void *), void *arg = nullptr,
const pthread_attr_t *attr = nullptr); const pthread_attr_t *attr = nullptr);