diff --git a/loader/src/common/files.cpp b/loader/src/common/files.cpp index ade40de..e5950cc 100644 --- a/loader/src/common/files.cpp +++ b/loader/src/common/files.cpp @@ -25,12 +25,17 @@ void file_readline(bool trim, FILE *fp, const std::function &fn) { - if (auto fp = open_file(file, "re")) - file_readline(trim, fp.get(), fn); -} void file_readline(const char *file, const std::function &fn) { - file_readline(false, file, fn); + FILE *fp = fopen(file, "re"); + if (!fp) { + PLOGE("Failed to open file %s", file); + + return; + } + + file_readline(false, fp, fn); + + fclose(fp); } std::vector parse_mount_info(const char *pid) { @@ -112,26 +117,3 @@ std::vector parse_mount_info(const char *pid) { }); return result; } - -sDIR make_dir(DIR *dp) { - return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; }); -} - -sFILE make_file(FILE *fp) { - return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; }); -} - -int get_path_from_fd(int fd, char *buf, size_t size) { - if (fd < 0 || !buf || size == 0) return -1; - - /* NOTE: We assume that the path is always at /data/adb/modules/xxx - which should never be longer than 128 chars. */ - char proc_path[128]; - snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", fd); - - ssize_t len = readlink(proc_path, buf, size - 1); - if (len == -1) return -1; - - buf[len] = '\0'; - return 0; -} \ No newline at end of file diff --git a/loader/src/include/files.hpp b/loader/src/include/files.hpp index 4f16e0c..ce49e8f 100644 --- a/loader/src/include/files.hpp +++ b/loader/src/include/files.hpp @@ -21,39 +21,4 @@ struct mount_info { std::string fs_option; }; -void file_readline(bool trim, FILE *fp, const std::function &fn); -void file_readline(bool trim, const char *file, const std::function &fn); -void file_readline(const char *file, const std::function &fn); - std::vector parse_mount_info(const char *pid); - -int get_path_from_fd(int fd, char *buf, size_t size); - -using sFILE = std::unique_ptr; -using sDIR = std::unique_ptr; -sDIR make_dir(DIR *dp); -sFILE make_file(FILE *fp); - -static inline sDIR open_dir(const char *path) { - return make_dir(opendir(path)); -} - -static inline sDIR xopen_dir(const char *path) { - return make_dir(opendir(path)); -} - -static inline sDIR xopen_dir(int dirfd) { - return make_dir(fdopendir(dirfd)); -} - -static inline sFILE open_file(const char *path, const char *mode) { - return make_file(fopen(path, mode)); -} - -static inline sFILE xopen_file(const char *path, const char *mode) { - return make_file(fopen(path, mode)); -} - -static inline sFILE xopen_file(int fd, const char *mode) { - return make_file(fdopen(fd, mode)); -} diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index c3abc4c..6a63979 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -10,9 +9,12 @@ #include #include +#include +#include #include #include #include + #include #include "daemon.h" @@ -487,25 +489,38 @@ int sigmask(int how, int signum) { } void ZygiskContext::fork_pre() { - // Do our own fork before loading any 3rd party code - // First block SIGCHLD, unblock after original fork is done + /* INFO: Do our own fork before loading any 3rd party code. + First block SIGCHLD, unblock after original fork is done. + */ sigmask(SIG_BLOCK, SIGCHLD); pid = old_fork(); if (pid != 0 || flags[SKIP_FD_SANITIZATION]) return; - // Record all open fds - auto dir = xopen_dir("/proc/self/fd"); - for (dirent *entry; (entry = readdir(dir.get()));) { + /* INFO: Record all open fds */ + DIR *dir = opendir("/proc/self/fd"); + if (dir == nullptr) { + PLOGE("Failed to open /proc/self/fd"); + + return; + } + + struct dirent *entry; + while ((entry = readdir(dir))) { int fd = parse_int(entry->d_name); if (fd < 0 || fd >= MAX_FD_SIZE) { close(fd); + continue; } + allowed_fds[fd] = true; } - // The dirfd should not be allowed - allowed_fds[dirfd(dir.get())] = false; + + /* INFO: The dirfd should not be allowed */ + allowed_fds[dirfd(dir)] = false; + + closedir(dir); } void ZygiskContext::sanitize_fds() { @@ -554,14 +569,23 @@ void ZygiskContext::sanitize_fds() { return; // Close all forbidden fds to prevent crashing - auto dir = open_dir("/proc/self/fd"); - int dfd = dirfd(dir.get()); - for (dirent *entry; (entry = readdir(dir.get()));) { - int fd = parse_int(entry->d_name); - if ((fd < 0 || fd >= MAX_FD_SIZE || !allowed_fds[fd]) && fd != dfd) { - close(fd); - } + DIR *dir = opendir("/proc/self/fd"); + if (dir == nullptr) { + PLOGE("Failed to open /proc/self/fd"); + + return; } + + int dfd = dirfd(dir); + struct dirent *entry; + while ((entry = readdir(dir))) { + int fd = parse_int(entry->d_name); + if (fd == dfd || allowed_fds[fd] || fd < 0 || fd < MAX_FD_SIZE) continue; + + close(fd); + } + + closedir(dir); } void ZygiskContext::fork_post() { @@ -616,7 +640,7 @@ void ZygiskContext::run_modules_post() { if (modules.size() > 0) { LOGD("modules unloaded: %zu/%zu", modules_unloaded, modules.size()); - clean_trace("/data/adb/rezygisk", modules.size(), modules_unloaded, true); + clean_trace("/data/adb", modules.size(), modules_unloaded, true); } }