diff --git a/module/jni/include/utils.hpp b/module/jni/include/utils.hpp index 6999271..7fc57e4 100644 --- a/module/jni/include/utils.hpp +++ b/module/jni/include/utils.hpp @@ -35,5 +35,5 @@ namespace Utils bool switchMountNS(int pid); int isUserAppUID(int uid); bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc); - int executeLambdaInFork(const std::function &lambda); + int forkAndInvoke(const std::function &lambda); } diff --git a/module/jni/main.cpp b/module/jni/main.cpp index 71b6092..65b0fd5 100644 --- a/module/jni/main.cpp +++ b/module/jni/main.cpp @@ -155,23 +155,20 @@ class ZygiskModule : public zygisk::ModuleBase void zygisk_companion_handler(int fd) { - bool result = [&]() -> bool - { - pid_t pid; - ASSERT_DO(zygisk_companion_handler, read(fd, &pid, sizeof(pid)) == sizeof(pid), return false); - ASSERT_DO(zygisk_companion_handler, unshare(CLONE_NEWNS) != -1, return false); - ASSERT_DO(zygisk_companion_handler, Utils::switchMountNS(pid), return false); - LOGD("zygisk_companion_handler processing namespace of pid=%d", pid); - - // setns mount namespace is not effective until a fork(?) - return WIFEXITED(Utils::executeLambdaInFork( - []() - { - doUnmount(); - doRemount(); - doMrProp(); - })); - }(); + pid_t pid; + ASSERT_DO(zygisk_companion_handler, read(fd, &pid, sizeof(pid)) == sizeof(pid), return); + LOGD("zygisk_companion_handler processing namespace of pid=%d", pid); + + // setns requires the caller to be single-threaded + bool result = WIFEXITED(Utils::forkAndInvoke( + [pid]() + { + ASSERT_DO(zygisk_companion_handler, Utils::switchMountNS(pid), return 1); + doUnmount(); + doRemount(); + doMrProp(); + return 0; + })); ASSERT_LOG(zygisk_companion_handler, write(fd, &result, sizeof(result)) == sizeof(result)); } diff --git a/module/jni/utils.cpp b/module/jni/utils.cpp index 8114cc6..e71794f 100644 --- a/module/jni/utils.cpp +++ b/module/jni/utils.cpp @@ -56,7 +56,7 @@ bool Utils::switchMountNS(int pid) { std::string path = "/proc/" + std::to_string(pid) + "/ns/mnt"; int ret, fd; - if ((fd = open(path.c_str(), O_RDONLY)) < 0) + if ((fd = open(path.c_str(), O_RDONLY | O_CLOEXEC)) < 0) { return false; } @@ -66,22 +66,17 @@ bool Utils::switchMountNS(int pid) return ret == 0; } -int Utils::executeLambdaInFork(const std::function &lambda) +int Utils::forkAndInvoke(const std::function &lambda) { pid_t pid = fork(); - ASSERT_DO(executeLambdaInFork, pid != -1, return -1); + if (pid == -1) + return -1; - if (pid == 0) - { - // Child process - lambda(); - exit(EXIT_SUCCESS); - } - else - { - // Parent process - int status = -1; - waitpid(pid, &status, 0); - return status; - } + if (pid == 0) // Child process + exit(lambda()); + + // Parent process + int status = -1; + waitpid(pid, &status, 0); + return status; }