Loading src/client/gkfs_libc.cpp +48 −26 Original line number Diff line number Diff line Loading @@ -303,37 +303,59 @@ DLSYM_WRAPPER(int, closedir, (DIR * dirp), (dirp), "closedir") DLSYM_WRAPPER(void, seekdir, (DIR * dirp, long loc), (dirp, loc), "seekdir") DLSYM_WRAPPER(long, telldir, (DIR * dirp), (dirp), "telldir") static int (*real_fork)(void) = nullptr; int dlsym_fork(void) { if(!real_fork) { real_fork = reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "fork")); if(!real_fork) { fprintf(stderr, "dlsym failed for %s: %s\n", "fork", dlerror()); (*__errno_location()) = 38; return (int) -1; } } log_arguments("fork"); return real_fork(); } static int (*real_vfork)(void) = nullptr; int dlsym_vfork(void) { if(!real_vfork) { static pid_t (*real_fork)(void) = NULL; static pid_t (*real_vfork)(void) = NULL; static pid_t (*real_clone)(int (*fn)(void*), void*, int, void*, ...) = NULL; /*pid_t fork(void) { if (!real_fork) reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "fork")); destroy_libc(); pid_t pid = real_fork(); (pid == 0) ? init_libc() : init_libc(); return pid; }*/ pid_t vfork(void) { if(!real_vfork) real_vfork = reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "vfork")); if(!real_vfork) { fprintf(stderr, "dlsym failed for %s: %s\n", "vfork", dlerror()); (*__errno_location()) = 38; return (int) -1; destroy_libc(); pid_t pid = real_vfork(); // vfork child shares memory until execve, so: if(pid == 0) { init_libc(); // Dangerous! Must be async-signal-safe } else { init_libc(); } return pid; } log_arguments("vfork"); return real_vfork(); pid_t clone(int (*fn)(void*), void* stack, int flags, void* arg, ...) { if(!real_clone) real_clone = reinterpret_cast<decltype(&::clone)>(dlsym(RTLD_NEXT, "clone")); // Only handle process-creation clones if(flags & (SIGCHLD | CLONE_VFORK)) { destroy_libc(); } pid_t pid = real_clone(fn, stack, flags, arg); if(flags & (SIGCHLD | CLONE_VFORK)) { (pid == 0) ? init_libc() : init_libc(); } return pid; } DLSYM_WRAPPER(int, pipe, (int pipefd[2]), (pipefd), "pipe") DLSYM_WRAPPER(int, dup, (int fd), (fd), "dup") DLSYM_WRAPPER(int, dup2, (int fd, int fd2), (fd, fd2), "dup2") Loading src/client/preload.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -359,8 +359,7 @@ init_preload() { // The original errno value will be restored after initialization to not // leak internal error codes auto oerrno = errno; if(!init) { init = true; if (atomic_exchange(&init, 1) == 0) { pthread_atfork(&at_fork_syscall, &at_parent_syscall, &at_child_syscall); } CTX->enable_interception(); Loading Loading @@ -515,8 +514,7 @@ init_libc() { CTX->protect_user_fds(); } if(!init) { init = true; if (atomic_exchange(&init, 1) == 0) { pthread_atfork(&at_fork, &at_parent, &at_child); } Loading Loading
src/client/gkfs_libc.cpp +48 −26 Original line number Diff line number Diff line Loading @@ -303,37 +303,59 @@ DLSYM_WRAPPER(int, closedir, (DIR * dirp), (dirp), "closedir") DLSYM_WRAPPER(void, seekdir, (DIR * dirp, long loc), (dirp, loc), "seekdir") DLSYM_WRAPPER(long, telldir, (DIR * dirp), (dirp), "telldir") static int (*real_fork)(void) = nullptr; int dlsym_fork(void) { if(!real_fork) { real_fork = reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "fork")); if(!real_fork) { fprintf(stderr, "dlsym failed for %s: %s\n", "fork", dlerror()); (*__errno_location()) = 38; return (int) -1; } } log_arguments("fork"); return real_fork(); } static int (*real_vfork)(void) = nullptr; int dlsym_vfork(void) { if(!real_vfork) { static pid_t (*real_fork)(void) = NULL; static pid_t (*real_vfork)(void) = NULL; static pid_t (*real_clone)(int (*fn)(void*), void*, int, void*, ...) = NULL; /*pid_t fork(void) { if (!real_fork) reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "fork")); destroy_libc(); pid_t pid = real_fork(); (pid == 0) ? init_libc() : init_libc(); return pid; }*/ pid_t vfork(void) { if(!real_vfork) real_vfork = reinterpret_cast<int (*)(void)>(dlsym(((void*) -1l), "vfork")); if(!real_vfork) { fprintf(stderr, "dlsym failed for %s: %s\n", "vfork", dlerror()); (*__errno_location()) = 38; return (int) -1; destroy_libc(); pid_t pid = real_vfork(); // vfork child shares memory until execve, so: if(pid == 0) { init_libc(); // Dangerous! Must be async-signal-safe } else { init_libc(); } return pid; } log_arguments("vfork"); return real_vfork(); pid_t clone(int (*fn)(void*), void* stack, int flags, void* arg, ...) { if(!real_clone) real_clone = reinterpret_cast<decltype(&::clone)>(dlsym(RTLD_NEXT, "clone")); // Only handle process-creation clones if(flags & (SIGCHLD | CLONE_VFORK)) { destroy_libc(); } pid_t pid = real_clone(fn, stack, flags, arg); if(flags & (SIGCHLD | CLONE_VFORK)) { (pid == 0) ? init_libc() : init_libc(); } return pid; } DLSYM_WRAPPER(int, pipe, (int pipefd[2]), (pipefd), "pipe") DLSYM_WRAPPER(int, dup, (int fd), (fd), "dup") DLSYM_WRAPPER(int, dup2, (int fd, int fd2), (fd, fd2), "dup2") Loading
src/client/preload.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -359,8 +359,7 @@ init_preload() { // The original errno value will be restored after initialization to not // leak internal error codes auto oerrno = errno; if(!init) { init = true; if (atomic_exchange(&init, 1) == 0) { pthread_atfork(&at_fork_syscall, &at_parent_syscall, &at_child_syscall); } CTX->enable_interception(); Loading Loading @@ -515,8 +514,7 @@ init_libc() { CTX->protect_user_fds(); } if(!init) { init = true; if (atomic_exchange(&init, 1) == 0) { pthread_atfork(&at_fork, &at_parent, &at_child); } Loading