Loading include/client/gkfs_functions.hpp +1 −2 Original line number Diff line number Diff line Loading @@ -42,11 +42,10 @@ #include <client/open_file_map.hpp> #include <common/metadata.hpp> #include <client/intercept.hpp> struct statfs; struct statvfs; struct linux_dirent; struct linux_dirent64; namespace gkfs::syscall { Loading include/client/hooks.hpp +1 −3 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ extern "C" { #include <client/void_syscall_intercept.hpp> #endif #include <client/intercept.hpp> /* * For PowerPC, syscall_no_intercept_wrapper() is defined in the Loading @@ -75,9 +76,6 @@ syscall_no_intercept_wrapper(long syscall_number, Args... args) { #endif struct statfs; struct linux_dirent; struct linux_dirent64; namespace gkfs::hook { int Loading include/client/intercept.hpp +31 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,37 @@ #ifndef GEKKOFS_INTERCEPT_HPP #define GEKKOFS_INTERCEPT_HPP #include <stdint.h> /* * linux_dirent is used in getdents() but is privately defined in the linux * kernel: fs/readdir.c. */ struct linux_dirent { #ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; #else uint64_t d_ino; int64_t d_off; #endif unsigned short d_reclen; unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* * linux_dirent64 is used in getdents64() and defined in the linux kernel: * include/linux/dirent.h. However, it is not part of the kernel-headers and * cannot be imported. */ struct linux_dirent64 { uint64_t d_ino; int64_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ // forbids zero-size array 'd_name' }; namespace gkfs::preload { int Loading src/client/gkfs_functions.cpp +0 −30 Original line number Diff line number Diff line Loading @@ -70,36 +70,6 @@ using namespace std; */ #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) /* * linux_dirent is used in getdents() but is privately defined in the linux * kernel: fs/readdir.c. */ struct linux_dirent { #ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; #else uint64_t d_ino; int64_t d_off; #endif unsigned short d_reclen; unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* * linux_dirent64 is used in getdents64() and defined in the linux kernel: * include/linux/dirent.h. However, it is not part of the kernel-headers and * cannot be imported. */ struct linux_dirent64 { uint64_t d_ino; int64_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ // forbids zero-size array 'd_name' }; struct dirent_extended { size_t size; time_t ctime; Loading src/client/gkfs_libc.cpp +107 −12 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ initializeGekko() { void log_arguments(const char* symbol) { LOG(DEBUG, "[BYPASS] {}", symbol); // printf("[BYPASS] %s\n",symbol); } // Variadic case: 1+ arguments Loading @@ -94,6 +95,18 @@ log_arguments(const char* symbol, Args&&... args) { ss << "[BYPASS] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); // printf("%s\n",ss.str().c_str()); } // Variadic case: 1+ arguments template <typename... Args> void log_argumentsx(const char* symbol, Args&&... args) { std::stringstream ss; ss << "[BYPASS-ERROR] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); // printf("%s\n",ss.str().c_str()); } /** Loading Loading @@ -137,6 +150,28 @@ log_arguments(const char* symbol, Args&&... args) { } #define CDLSYM_WRAPPER(return_type, func_name, params, args, symbol_name) \ static return_type(*real_##func_name) params = nullptr; \ return_type dlsym_##func_name params { \ if(!real_##func_name) { \ real_##func_name = reinterpret_cast<return_type(*) params>( \ dlsym(RTLD_NEXT, symbol_name)); \ if(!real_##func_name) { \ fprintf(stderr, "dlsym failed for %s: %s\n", symbol_name, \ dlerror()); \ errno = ENOSYS; /* Set errno to ENOSYS to indicate function \ not supported */ \ return (return_type) - 1; /* Return error value */ \ } \ } \ log_argumentsx(symbol_name, STRIP_PARENS args); \ return real_##func_name args; \ } \ return_type func_name params { \ return dlsym_##func_name args; \ } // DLSYM_WRAPPER(int, open, (char* path, int flags, mode_t mode), (path, flags, // mode), "open") DLSYM_WRAPPER(int, open2, (const char* path, int flags, mode_t mode), Loading Loading @@ -188,8 +223,7 @@ DLSYM_WRAPPER(int, stat, (int ver, const char* path, struct stat* buf), (ver, path, buf), "__xstat") DLSYM_WRAPPER(int, fstat, (int ver, int fd, struct stat* buf), (ver, fd, buf), "__fxstat") DLSYM_WRAPPER(int, fstat64, ( int fd,struct stat64* buf), ( fd, buf), "__fxstat64") DLSYM_WRAPPER(int, fstat64, (int fd, struct stat64* buf), (fd, buf), "fstat64") DLSYM_WRAPPER(int, fxstatat, (int ver, int dfd, const char* path, struct stat* buf, int flags), (ver, dfd, path, buf, flags), "__fxstatat") Loading Loading @@ -227,6 +261,9 @@ DLSYM_WRAPPER(int, chown, (char* path, uid_t owner, gid_t group), (path, owner, group), "chown") DLSYM_WRAPPER(int, fcntl, (int fd, int cmd, long arg), (fd, cmd, arg), "fcntl") DLSYM_WRAPPER(int, access, (const char* path, int mode), (path, mode), "access") DLSYM_WRAPPER(int, faccessat, (int dfd, const char* path, int mode, int flags), (dfd, path, mode, flags), "faccessat") DLSYM_WRAPPER(char*, realpath, (const char* path, char* resolved_path), (path, resolved_path), "realpath") DLSYM_WRAPPER(int, fsync, (int fd), (fd), "fsync") Loading Loading @@ -258,7 +295,48 @@ DLSYM_WRAPPER(int, fputs, (const char* str, FILE* stream), (str, stream), DLSYM_WRAPPER(char*, fgets, (char* str, int n, FILE* stream), (str, n, stream), "fgets") DLSYM_WRAPPER(int, fflush, (FILE * stream), (stream), "fflush") CDLSYM_WRAPPER(ssize_t, readlink, (const char* path, char* buf, size_t bufsize), (path, buf, bufsize), "readlink") CDLSYM_WRAPPER(ssize_t, readlinkat, (int dfd, const char* path, char* buf, size_t bufsize), (dfd, path, buf, bufsize), "readlinkat") CDLSYM_WRAPPER(int, openat2, (int dfd, const char* path, int flags, mode_t mode), (dfd, path, flags, mode), "openat2") CDLSYM_WRAPPER(int, execve, (const char* filename, char* const argv, char* const envp), (filename, argv, envp), "execve") CDLSYM_WRAPPER(int, execveat, (int dfd, const char* filename, char* const argv[], char* const envp[], int flags), (dfd, filename, argv, envp, flags), "execveat") CDLSYM_WRAPPER(int, execv, (const char* filename, char* const argv[]), (filename, argv), "execv") CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]), (fd, filename, argv), "fexecve") DLSYM_WRAPPER(long, syscall, (long number, char* cmd, void* arg, void* env), (number, cmd, arg, env), "syscall") long syscall(long number, ...) { if(number == SYS_execve or number == SYS_execveat) { LOG(DEBUG, "OSTIA execve {}", number); } va_list myargs; va_start(myargs, number); auto res = syscall_no_intercept_wrapper(number, myargs); va_end(myargs); return res; } /* not used */ /*static void convert(struct stat64* src, struct stat* dest) { Loading Loading @@ -362,6 +440,7 @@ is_gkfs_fd(int fd) { #define GKFS_OPERATION(name, ...) \ if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \ LOG(DEBUG, "[GKFS] {}", fd); \ printf("[GKFS] %d\n", fd); \ return gkfs::syscall::gkfs_##name(__VA_ARGS__); \ } Loading @@ -371,6 +450,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \ case PathStatus::Error: \ return -errno; \ Loading @@ -385,6 +465,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(dirfd, resolved, \ __VA_ARGS__); \ case PathStatus::Error: \ Loading @@ -400,6 +481,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(resolved); \ case PathStatus::Error: \ return -errno; \ Loading Loading @@ -445,7 +527,6 @@ open64(const char* path, int flags, mode_t mode) { } int openat(int dirfd, const char* path, int flags, ...) { va_list ap; Loading Loading @@ -519,7 +600,7 @@ get_open_fds() { int close_range(unsigned low, unsigned high, int flags) { LOG(DEBUG, "close_range({}, {}, {})", low, high, flags); //return 0; return 0; auto fds = get_open_fds(); if(flags & CLOSE_RANGE_UNSHARE) { // Unshare the file descriptor table Loading Loading @@ -795,6 +876,22 @@ __fxstat64(int ver, int fd, struct stat64* buf) { GKFS_FALLBACK(fxstat64, ver, fd, buf); } int fstat64(int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) convert(&st, buf); return res; } GKFS_FALLBACK(fstat64, fd, buf); } int __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, int flags) { Loading Loading @@ -969,12 +1066,10 @@ dup2(int fd, int fd2) { if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); }else if(is_gkfs_fd(fd2)) { } else if(is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup(fd); }else if(is_gkfs_fd(fd)) { } else if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } Loading Loading
include/client/gkfs_functions.hpp +1 −2 Original line number Diff line number Diff line Loading @@ -42,11 +42,10 @@ #include <client/open_file_map.hpp> #include <common/metadata.hpp> #include <client/intercept.hpp> struct statfs; struct statvfs; struct linux_dirent; struct linux_dirent64; namespace gkfs::syscall { Loading
include/client/hooks.hpp +1 −3 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ extern "C" { #include <client/void_syscall_intercept.hpp> #endif #include <client/intercept.hpp> /* * For PowerPC, syscall_no_intercept_wrapper() is defined in the Loading @@ -75,9 +76,6 @@ syscall_no_intercept_wrapper(long syscall_number, Args... args) { #endif struct statfs; struct linux_dirent; struct linux_dirent64; namespace gkfs::hook { int Loading
include/client/intercept.hpp +31 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,37 @@ #ifndef GEKKOFS_INTERCEPT_HPP #define GEKKOFS_INTERCEPT_HPP #include <stdint.h> /* * linux_dirent is used in getdents() but is privately defined in the linux * kernel: fs/readdir.c. */ struct linux_dirent { #ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; #else uint64_t d_ino; int64_t d_off; #endif unsigned short d_reclen; unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* * linux_dirent64 is used in getdents64() and defined in the linux kernel: * include/linux/dirent.h. However, it is not part of the kernel-headers and * cannot be imported. */ struct linux_dirent64 { uint64_t d_ino; int64_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ // forbids zero-size array 'd_name' }; namespace gkfs::preload { int Loading
src/client/gkfs_functions.cpp +0 −30 Original line number Diff line number Diff line Loading @@ -70,36 +70,6 @@ using namespace std; */ #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) /* * linux_dirent is used in getdents() but is privately defined in the linux * kernel: fs/readdir.c. */ struct linux_dirent { #ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; #else uint64_t d_ino; int64_t d_off; #endif unsigned short d_reclen; unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* * linux_dirent64 is used in getdents64() and defined in the linux kernel: * include/linux/dirent.h. However, it is not part of the kernel-headers and * cannot be imported. */ struct linux_dirent64 { uint64_t d_ino; int64_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ // forbids zero-size array 'd_name' }; struct dirent_extended { size_t size; time_t ctime; Loading
src/client/gkfs_libc.cpp +107 −12 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ initializeGekko() { void log_arguments(const char* symbol) { LOG(DEBUG, "[BYPASS] {}", symbol); // printf("[BYPASS] %s\n",symbol); } // Variadic case: 1+ arguments Loading @@ -94,6 +95,18 @@ log_arguments(const char* symbol, Args&&... args) { ss << "[BYPASS] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); // printf("%s\n",ss.str().c_str()); } // Variadic case: 1+ arguments template <typename... Args> void log_argumentsx(const char* symbol, Args&&... args) { std::stringstream ss; ss << "[BYPASS-ERROR] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); // printf("%s\n",ss.str().c_str()); } /** Loading Loading @@ -137,6 +150,28 @@ log_arguments(const char* symbol, Args&&... args) { } #define CDLSYM_WRAPPER(return_type, func_name, params, args, symbol_name) \ static return_type(*real_##func_name) params = nullptr; \ return_type dlsym_##func_name params { \ if(!real_##func_name) { \ real_##func_name = reinterpret_cast<return_type(*) params>( \ dlsym(RTLD_NEXT, symbol_name)); \ if(!real_##func_name) { \ fprintf(stderr, "dlsym failed for %s: %s\n", symbol_name, \ dlerror()); \ errno = ENOSYS; /* Set errno to ENOSYS to indicate function \ not supported */ \ return (return_type) - 1; /* Return error value */ \ } \ } \ log_argumentsx(symbol_name, STRIP_PARENS args); \ return real_##func_name args; \ } \ return_type func_name params { \ return dlsym_##func_name args; \ } // DLSYM_WRAPPER(int, open, (char* path, int flags, mode_t mode), (path, flags, // mode), "open") DLSYM_WRAPPER(int, open2, (const char* path, int flags, mode_t mode), Loading Loading @@ -188,8 +223,7 @@ DLSYM_WRAPPER(int, stat, (int ver, const char* path, struct stat* buf), (ver, path, buf), "__xstat") DLSYM_WRAPPER(int, fstat, (int ver, int fd, struct stat* buf), (ver, fd, buf), "__fxstat") DLSYM_WRAPPER(int, fstat64, ( int fd,struct stat64* buf), ( fd, buf), "__fxstat64") DLSYM_WRAPPER(int, fstat64, (int fd, struct stat64* buf), (fd, buf), "fstat64") DLSYM_WRAPPER(int, fxstatat, (int ver, int dfd, const char* path, struct stat* buf, int flags), (ver, dfd, path, buf, flags), "__fxstatat") Loading Loading @@ -227,6 +261,9 @@ DLSYM_WRAPPER(int, chown, (char* path, uid_t owner, gid_t group), (path, owner, group), "chown") DLSYM_WRAPPER(int, fcntl, (int fd, int cmd, long arg), (fd, cmd, arg), "fcntl") DLSYM_WRAPPER(int, access, (const char* path, int mode), (path, mode), "access") DLSYM_WRAPPER(int, faccessat, (int dfd, const char* path, int mode, int flags), (dfd, path, mode, flags), "faccessat") DLSYM_WRAPPER(char*, realpath, (const char* path, char* resolved_path), (path, resolved_path), "realpath") DLSYM_WRAPPER(int, fsync, (int fd), (fd), "fsync") Loading Loading @@ -258,7 +295,48 @@ DLSYM_WRAPPER(int, fputs, (const char* str, FILE* stream), (str, stream), DLSYM_WRAPPER(char*, fgets, (char* str, int n, FILE* stream), (str, n, stream), "fgets") DLSYM_WRAPPER(int, fflush, (FILE * stream), (stream), "fflush") CDLSYM_WRAPPER(ssize_t, readlink, (const char* path, char* buf, size_t bufsize), (path, buf, bufsize), "readlink") CDLSYM_WRAPPER(ssize_t, readlinkat, (int dfd, const char* path, char* buf, size_t bufsize), (dfd, path, buf, bufsize), "readlinkat") CDLSYM_WRAPPER(int, openat2, (int dfd, const char* path, int flags, mode_t mode), (dfd, path, flags, mode), "openat2") CDLSYM_WRAPPER(int, execve, (const char* filename, char* const argv, char* const envp), (filename, argv, envp), "execve") CDLSYM_WRAPPER(int, execveat, (int dfd, const char* filename, char* const argv[], char* const envp[], int flags), (dfd, filename, argv, envp, flags), "execveat") CDLSYM_WRAPPER(int, execv, (const char* filename, char* const argv[]), (filename, argv), "execv") CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]), (fd, filename, argv), "fexecve") DLSYM_WRAPPER(long, syscall, (long number, char* cmd, void* arg, void* env), (number, cmd, arg, env), "syscall") long syscall(long number, ...) { if(number == SYS_execve or number == SYS_execveat) { LOG(DEBUG, "OSTIA execve {}", number); } va_list myargs; va_start(myargs, number); auto res = syscall_no_intercept_wrapper(number, myargs); va_end(myargs); return res; } /* not used */ /*static void convert(struct stat64* src, struct stat* dest) { Loading Loading @@ -362,6 +440,7 @@ is_gkfs_fd(int fd) { #define GKFS_OPERATION(name, ...) \ if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \ LOG(DEBUG, "[GKFS] {}", fd); \ printf("[GKFS] %d\n", fd); \ return gkfs::syscall::gkfs_##name(__VA_ARGS__); \ } Loading @@ -371,6 +450,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \ case PathStatus::Error: \ return -errno; \ Loading @@ -385,6 +465,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(dirfd, resolved, \ __VA_ARGS__); \ case PathStatus::Error: \ Loading @@ -400,6 +481,7 @@ is_gkfs_fd(int fd) { switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ printf("[GKFS] %s\n", resolved.c_str()); \ return gkfs::syscall::gkfs_##name(resolved); \ case PathStatus::Error: \ return -errno; \ Loading Loading @@ -445,7 +527,6 @@ open64(const char* path, int flags, mode_t mode) { } int openat(int dirfd, const char* path, int flags, ...) { va_list ap; Loading Loading @@ -519,7 +600,7 @@ get_open_fds() { int close_range(unsigned low, unsigned high, int flags) { LOG(DEBUG, "close_range({}, {}, {})", low, high, flags); //return 0; return 0; auto fds = get_open_fds(); if(flags & CLOSE_RANGE_UNSHARE) { // Unshare the file descriptor table Loading Loading @@ -795,6 +876,22 @@ __fxstat64(int ver, int fd, struct stat64* buf) { GKFS_FALLBACK(fxstat64, ver, fd, buf); } int fstat64(int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) convert(&st, buf); return res; } GKFS_FALLBACK(fstat64, fd, buf); } int __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, int flags) { Loading Loading @@ -969,12 +1066,10 @@ dup2(int fd, int fd2) { if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); }else if(is_gkfs_fd(fd2)) { } else if(is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup(fd); }else if(is_gkfs_fd(fd)) { } else if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } Loading