Loading src/client/gkfs_libc.cpp +127 −55 Original line number Diff line number Diff line Loading @@ -58,14 +58,16 @@ std::atomic<bool> initializing{false}; #ifdef GKFS_TRACE #define DEBUG_INFO(...) \ do { \ fprintf(stderr, "[DEBUG] [GKFS] %s:%d: ", __FILE__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ LOG(DEBUG, __VA_ARGS__); \ } while(0) #else #define DEBUG_INFO(...) /* No debug output */ #endif #endif #define GKFS_DEBUG(...) DEBUG_INFO(__VA_ARGS__) // set to store void * addr, fd, length and offset std::set<std::tuple<void*, int, size_t, off_t>> mmap_set; void initializeGekko() { Loading @@ -85,7 +87,7 @@ initializeGekko() { void log_arguments(const char* symbol) { LOG(DEBUG, "[BYPASS] {}", symbol); DEBUG_INFO("[BYPASS] {}", symbol); // printf("[BYPASS] %s\n",symbol); } Loading @@ -96,7 +98,7 @@ log_arguments(const char* symbol, Args&&... args) { std::stringstream ss; ss << "[BYPASS] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); DEBUG_INFO("{}", ss.str()); // printf("%s\n",ss.str().c_str()); } Loading @@ -107,7 +109,7 @@ 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()); DEBUG_INFO("{}", ss.str()); // printf("%s\n",ss.str().c_str()); } Loading Loading @@ -274,6 +276,10 @@ DLSYM_WRAPPER(void*, mmap, (void* addr, size_t length, int prot, int flags, int fd, off_t offset), (addr, length, prot, flags, fd, offset), "mmap") DLSYM_WRAPPER(int, msync, (void* addr, size_t length, int flags), (addr, length, flags), "msync") DLSYM_WRAPPER(int, munmap, (void* addr, size_t length), (addr, length), "munmap") DLSYM_WRAPPER(FILE*, fopen, (const char* filename, const char* mode), (filename, mode), "fopen") DLSYM_WRAPPER(FILE*, fdopen, (int fd, const char* mode), (fd, mode), "fdopen") Loading Loading @@ -326,11 +332,12 @@ CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]), 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, "execve {}", number); DEBUG_INFO("execve {}", number); } va_list myargs; va_start(myargs, number); Loading Loading @@ -442,7 +449,7 @@ is_gkfs_fd(int fd) { #define GKFS_OPERATION(name, ...) \ if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \ LOG(DEBUG, "[GKFS] {}", fd); \ DEBUG_INFO("[GKFS] {}", fd); \ return gkfs::syscall::gkfs_##name(__VA_ARGS__); \ } Loading @@ -451,7 +458,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \ case PathStatus::Error: \ return -errno; \ Loading @@ -465,7 +472,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(dirfd, resolved, \ __VA_ARGS__); \ case PathStatus::Error: \ Loading @@ -480,7 +487,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(resolved); \ case PathStatus::Error: \ return -errno; \ Loading Loading @@ -598,13 +605,13 @@ get_open_fds() { int close_range(unsigned low, unsigned high, int flags) { LOG(DEBUG, "close_range({}, {}, {})", low, high, flags); DEBUG_INFO("close_range({}, {}, {})", low, high, flags); return 0; auto fds = get_open_fds(); #ifdef CLOSE_RANGE_UNSHARE if(flags & CLOSE_RANGE_UNSHARE) { // Unshare the file descriptor table LOG(DEBUG, "close_range with CLOSE_RANGE_UNSHARE"); DEBUG_INFO("close_range with CLOSE_RANGE_UNSHARE"); if(unshare(CLONE_FILES) == -1) { perror("unshare() failed"); return -1; Loading @@ -614,7 +621,7 @@ close_range(unsigned low, unsigned high, int flags) { #ifdef CLOSE_RANGE_CLOEXEC if(flags & CLOSE_RANGE_CLOEXEC) { // Close all file descriptors in the range LOG(DEBUG, "close_range with CLOSE_RANGE_CLOEXEC"); DEBUG_INFO("close_range with CLOSE_RANGE_CLOEXEC"); } #endif // Is fd from gekkofs ? Loading Loading @@ -662,7 +669,7 @@ ftruncate(int fd, off_t length) { initializeGekko(); if(is_gkfs_fd(fd)) { std::string path_str = CTX->file_map()->get(fd)->path(); LOG(DEBUG, "[GKFS] {}", path_str); DEBUG_INFO("[GKFS] {}", path_str); return gkfs::syscall::gkfs_truncate(path_str, length); } GKFS_FALLBACK(ftruncate, fd, length); Loading Loading @@ -767,7 +774,7 @@ __xstat64(int ver, const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading Loading @@ -809,7 +816,7 @@ __lxstat(int ver, const char* path, struct stat* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved, 0, false)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, buf); return res; } Loading @@ -832,7 +839,7 @@ __lxstat64(int ver, const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading @@ -851,7 +858,7 @@ int __fxstat(int ver, int fd, struct stat* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } GKFS_FALLBACK(fstat, ver, fd, buf); Loading @@ -869,7 +876,7 @@ __fxstat64(int ver, int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) Loading @@ -884,7 +891,7 @@ fstat64(int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) Loading @@ -904,7 +911,7 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, std::string resolved; switch(resolve_gkfs_path(dfd, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading Loading @@ -934,7 +941,7 @@ stat64(const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading @@ -956,7 +963,7 @@ int fstat(int fd, struct stat* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } GKFS_FALLBACK(fstat, _STAT_VER, fd, buf); Loading @@ -969,7 +976,7 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) { std::string resolved; switch(resolve_gkfs_path(dfd, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, buf); return res; } Loading Loading @@ -999,7 +1006,7 @@ rename(const char* oldpath, const char* newpath) { case PathStatus::Internal: switch(rstatus_new) { case PathStatus::Internal: LOG(DEBUG, "[GKFS] {} {}{}", "NOT IMPLEMENTED", DEBUG_INFO("[GKFS] {} {}{}", "NOT IMPLEMENTED", resolved_old, resolved_new); return -ENOTDIR; // return Loading Loading @@ -1050,7 +1057,7 @@ pipe(int pipefd[2]) { initializeGekko(); auto res = dlsym_pipe(pipefd); LOG(DEBUG, "pipe {} <---> {}", pipefd[0], pipefd[1]); DEBUG_INFO("pipe {} <---> {}", pipefd[0], pipefd[1]); // GKFS_FALLBACK(pipe, pipefd); return res; Loading @@ -1067,13 +1074,13 @@ int dup2(int fd, int fd2) { initializeGekko(); if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2); DEBUG_INFO("[GKFS] DUP2 G{} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } else if(is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2); DEBUG_INFO("[GKFS-NON] DUP2 {} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup(fd); } else if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2); DEBUG_INFO("[GKFS-NON] DUP2 G{} --> {}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } Loading Loading @@ -1114,7 +1121,7 @@ chdir(const char* path) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: LOG(DEBUG, "[GKFS] NOT IMPLEMENTED {}", path); DEBUG_INFO("[GKFS] NOT IMPLEMENTED {}", path); break; default: Loading @@ -1138,12 +1145,12 @@ fcntl(int fd, int cmd, long arg) // TODO switch(cmd) { case F_DUPFD: LOG(DEBUG, "[GKFS] DUPFD {}", fd); DEBUG_INFO("[GKFS] DUPFD {}", fd); return gkfs::syscall::gkfs_dup(fd); case F_DUPFD_CLOEXEC: LOG(DEBUG, "[GKFS] F_DUPFD_CLOEXEC {}", fd); DEBUG_INFO("[GKFS] F_DUPFD_CLOEXEC {}", fd); ret = gkfs::syscall::gkfs_dup(fd); if(ret == -1) { return -errno; Loading @@ -1153,7 +1160,7 @@ fcntl(int fd, int cmd, long arg) // TODO return ret; case F_GETFD: LOG(DEBUG, "[GKFS] F_GETFD {}", fd); DEBUG_INFO("[GKFS] F_GETFD {}", fd); if(CTX->file_map()->get(fd)->get_flag( gkfs::filemap::OpenFile_flags::cloexec)) { return FD_CLOEXEC; Loading @@ -1161,7 +1168,7 @@ fcntl(int fd, int cmd, long arg) // TODO return 0; case F_GETFL: LOG(DEBUG, "[GKFS] F_GETFL {}", fd); DEBUG_INFO("[GKFS] F_GETFL {}", fd); ret = 0; if(CTX->file_map()->get(fd)->get_flag( gkfs::filemap::OpenFile_flags::rdonly)) { Loading @@ -1178,18 +1185,18 @@ fcntl(int fd, int cmd, long arg) // TODO return ret; case F_SETFD: LOG(DEBUG, "[GKFS] F_SETFD {}", fd); DEBUG_INFO("[GKFS] F_SETFD {}", fd); CTX->file_map()->get(fd)->set_flag( gkfs::filemap::OpenFile_flags::cloexec, (arg & FD_CLOEXEC)); return 0; case F_GETLK: LOG(DEBUG, "[GKFS] F_GETLK {}", fd); DEBUG_INFO("[GKFS] F_GETLK {}", fd); return 0; case F_SETLK: LOG(DEBUG, "[GKFS] F_SETLK {}", fd); DEBUG_INFO("[GKFS] F_SETLK {}", fd); return 0; default: Loading Loading @@ -1224,7 +1231,7 @@ realpath(const char* path, char* resolved_path) { return nullptr; case gkfs::preload::RelativizeStatus::internal: LOG(DEBUG, "[GKFS] {} --> {}", resolved, path); DEBUG_INFO("[GKFS] {} --> {}", resolved, path); if(resolved_path == nullptr) { resolved_path = static_cast<char*>(malloc(resolved.size() + 1)); Loading Loading @@ -1289,7 +1296,7 @@ opendir(const char* dirname) { std::string resolved; if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) == PathStatus::Internal) { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); return gekko_opendir(resolved); } } Loading @@ -1303,7 +1310,7 @@ opendir64(const char* dirname) { std::string resolved; if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) == PathStatus::Internal) { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); return gekko_opendir(resolved); } } Loading Loading @@ -1427,7 +1434,7 @@ closedir(DIR* dirp) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] {}", dirp->fd); DEBUG_INFO("[GKFS] {}", dirp->fd); ret = gkfs::syscall::gkfs_close(dirp->fd); free(dirp->path); free(dirp); Loading @@ -1446,7 +1453,7 @@ telldir(DIR* dirp) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] NOT IMPLEMENTED"); DEBUG_INFO("[GKFS] NOT IMPLEMENTED"); ret = 0; // ret = gkfs::syscall::gkfs_telldir(dirp->fd); return ret; Loading @@ -1463,7 +1470,7 @@ seekdir(DIR* dirp, long loc) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] NOT IMPLEMENTED"); DEBUG_INFO("[GKFS] NOT IMPLEMENTED"); return; } } Loading Loading @@ -1519,7 +1526,7 @@ fopen(const char* path, const char* mode) { flags = O_WRONLY | O_CREAT | O_APPEND; if(strchr(mode, '+')) flags = O_RDWR | O_CREAT; LOG(DEBUG, "[GEKKO] {}", resolved); DEBUG_INFO("[GEKKO] {}", resolved); const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags); if(fd < 0) return nullptr; Loading Loading @@ -1547,7 +1554,7 @@ freopen64(const char* path, const char* mode, FILE* stream) { flags = O_WRONLY | O_CREAT | O_APPEND; if(strchr(mode, '+')) flags = O_RDWR | O_CREAT; LOG(DEBUG, "[GEKKO] {}", resolved); DEBUG_INFO("[GEKKO] {}", resolved); const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags); if(fd < 0) return nullptr; Loading @@ -1563,7 +1570,7 @@ freopen64(const char* path, const char* mode, FILE* stream) { size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GEKKO] {}", stream->_fileno); DEBUG_INFO("[GEKKO] {}", stream->_fileno); return gkfs::syscall::gkfs_read(stream->_fileno, ptr, size * nmemb) / size; } Loading @@ -1576,7 +1583,7 @@ fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GEKKO] {}", stream->_fileno); DEBUG_INFO("[GEKKO] {}", stream->_fileno); return gkfs::syscall::gkfs_write(stream->_fileno, ptr, size * nmemb) / size; } Loading @@ -1588,7 +1595,7 @@ int fseek(FILE* stream, long int offset, int whence) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); return gkfs::syscall::gkfs_lseek(stream->_fileno, offset, whence); } Loading @@ -1599,7 +1606,7 @@ long ftell(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); return gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR); } Loading @@ -1610,7 +1617,7 @@ void rewind(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_SET); } GKFS_FALLBACK(rewind, stream) Loading @@ -1621,7 +1628,7 @@ fclose(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); auto ret = gkfs::syscall::gkfs_close(stream->_fileno); // should I do a fclose (stream)? free(stream); Loading @@ -1636,7 +1643,7 @@ int feof(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); off_t cur = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR); off_t end = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_END); gkfs::syscall::gkfs_lseek(stream->_fileno, cur, SEEK_SET); Loading @@ -1658,7 +1665,7 @@ fgets(char* str, int n, FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { // read str n chars LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); auto l = gkfs::syscall::gkfs_read(stream->_fileno, str, n); if(l == 0) { return NULL; Loading @@ -1678,3 +1685,68 @@ fflush(FILE* stream) { } GKFS_FALLBACK(fflush, stream) } void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { initializeGekko(); if(is_gkfs_fd(fd)) { DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); // create a malloc of length void* ptr = malloc(length); if(ptr == nullptr) { return MAP_FAILED; } // store info on mmap_set mmap_set.insert(std::make_tuple(ptr, fd, length, offset)); gkfs::syscall::gkfs_pread(fd, ptr, length, offset); return ptr; } GKFS_FALLBACK(mmap, addr, length, prot, flags, fd, offset); } // implement msync, if addr is from gekkofs (we should have a set with them) // We pwrite length to the original offset (also from the set), and return // if not just go to the normal msync int msync(void* addr, size_t length, int flags) { initializeGekko(); // check if addr is from gekkofs (mmap_set) // if so, get the fd and offset // pwrite length to the original offset // return // if not just go to the normal msync for(const auto& tuple : mmap_set) { if(std::get<0>(tuple) == addr) { int fd = std::get<1>(tuple); off_t offset = std::get<3>(tuple); gkfs::syscall::gkfs_pwrite(fd, addr, length, offset); return 0; } } GKFS_FALLBACK(msync, addr, length, flags); } // implement munmap, if it's on the set, call msync, free memory int munmap(void* addr, size_t length) { initializeGekko(); // check if addr is from gekkofs (mmap_set) // if so, call msync // free memory // return // if not just go to the normal munmap for(auto it = mmap_set.begin(); it != mmap_set.end(); ++it) { if(std::get<0>(*it) == addr) { msync(addr, length, 0); free(addr); mmap_set.erase(it); return 0; } } GKFS_FALLBACK(munmap, addr, length); } Loading
src/client/gkfs_libc.cpp +127 −55 Original line number Diff line number Diff line Loading @@ -58,14 +58,16 @@ std::atomic<bool> initializing{false}; #ifdef GKFS_TRACE #define DEBUG_INFO(...) \ do { \ fprintf(stderr, "[DEBUG] [GKFS] %s:%d: ", __FILE__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ LOG(DEBUG, __VA_ARGS__); \ } while(0) #else #define DEBUG_INFO(...) /* No debug output */ #endif #endif #define GKFS_DEBUG(...) DEBUG_INFO(__VA_ARGS__) // set to store void * addr, fd, length and offset std::set<std::tuple<void*, int, size_t, off_t>> mmap_set; void initializeGekko() { Loading @@ -85,7 +87,7 @@ initializeGekko() { void log_arguments(const char* symbol) { LOG(DEBUG, "[BYPASS] {}", symbol); DEBUG_INFO("[BYPASS] {}", symbol); // printf("[BYPASS] %s\n",symbol); } Loading @@ -96,7 +98,7 @@ log_arguments(const char* symbol, Args&&... args) { std::stringstream ss; ss << "[BYPASS] Calling " << symbol << " with arguments: "; ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...); LOG(DEBUG, "{}", ss.str()); DEBUG_INFO("{}", ss.str()); // printf("%s\n",ss.str().c_str()); } Loading @@ -107,7 +109,7 @@ 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()); DEBUG_INFO("{}", ss.str()); // printf("%s\n",ss.str().c_str()); } Loading Loading @@ -274,6 +276,10 @@ DLSYM_WRAPPER(void*, mmap, (void* addr, size_t length, int prot, int flags, int fd, off_t offset), (addr, length, prot, flags, fd, offset), "mmap") DLSYM_WRAPPER(int, msync, (void* addr, size_t length, int flags), (addr, length, flags), "msync") DLSYM_WRAPPER(int, munmap, (void* addr, size_t length), (addr, length), "munmap") DLSYM_WRAPPER(FILE*, fopen, (const char* filename, const char* mode), (filename, mode), "fopen") DLSYM_WRAPPER(FILE*, fdopen, (int fd, const char* mode), (fd, mode), "fdopen") Loading Loading @@ -326,11 +332,12 @@ CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]), 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, "execve {}", number); DEBUG_INFO("execve {}", number); } va_list myargs; va_start(myargs, number); Loading Loading @@ -442,7 +449,7 @@ is_gkfs_fd(int fd) { #define GKFS_OPERATION(name, ...) \ if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \ LOG(DEBUG, "[GKFS] {}", fd); \ DEBUG_INFO("[GKFS] {}", fd); \ return gkfs::syscall::gkfs_##name(__VA_ARGS__); \ } Loading @@ -451,7 +458,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \ case PathStatus::Error: \ return -errno; \ Loading @@ -465,7 +472,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(dirfd, resolved, \ __VA_ARGS__); \ case PathStatus::Error: \ Loading @@ -480,7 +487,7 @@ is_gkfs_fd(int fd) { std::string resolved; \ switch(resolve_gkfs_path(dirfd, path, resolved)) { \ case PathStatus::Internal: \ LOG(DEBUG, "[GKFS] {}", resolved); \ DEBUG_INFO("[GKFS] {}", resolved); \ return gkfs::syscall::gkfs_##name(resolved); \ case PathStatus::Error: \ return -errno; \ Loading Loading @@ -598,13 +605,13 @@ get_open_fds() { int close_range(unsigned low, unsigned high, int flags) { LOG(DEBUG, "close_range({}, {}, {})", low, high, flags); DEBUG_INFO("close_range({}, {}, {})", low, high, flags); return 0; auto fds = get_open_fds(); #ifdef CLOSE_RANGE_UNSHARE if(flags & CLOSE_RANGE_UNSHARE) { // Unshare the file descriptor table LOG(DEBUG, "close_range with CLOSE_RANGE_UNSHARE"); DEBUG_INFO("close_range with CLOSE_RANGE_UNSHARE"); if(unshare(CLONE_FILES) == -1) { perror("unshare() failed"); return -1; Loading @@ -614,7 +621,7 @@ close_range(unsigned low, unsigned high, int flags) { #ifdef CLOSE_RANGE_CLOEXEC if(flags & CLOSE_RANGE_CLOEXEC) { // Close all file descriptors in the range LOG(DEBUG, "close_range with CLOSE_RANGE_CLOEXEC"); DEBUG_INFO("close_range with CLOSE_RANGE_CLOEXEC"); } #endif // Is fd from gekkofs ? Loading Loading @@ -662,7 +669,7 @@ ftruncate(int fd, off_t length) { initializeGekko(); if(is_gkfs_fd(fd)) { std::string path_str = CTX->file_map()->get(fd)->path(); LOG(DEBUG, "[GKFS] {}", path_str); DEBUG_INFO("[GKFS] {}", path_str); return gkfs::syscall::gkfs_truncate(path_str, length); } GKFS_FALLBACK(ftruncate, fd, length); Loading Loading @@ -767,7 +774,7 @@ __xstat64(int ver, const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading Loading @@ -809,7 +816,7 @@ __lxstat(int ver, const char* path, struct stat* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved, 0, false)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, buf); return res; } Loading @@ -832,7 +839,7 @@ __lxstat64(int ver, const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading @@ -851,7 +858,7 @@ int __fxstat(int ver, int fd, struct stat* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } GKFS_FALLBACK(fstat, ver, fd, buf); Loading @@ -869,7 +876,7 @@ __fxstat64(int ver, int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) Loading @@ -884,7 +891,7 @@ fstat64(int fd, struct stat64* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { struct stat st; LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); int res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st); if(res == 0) Loading @@ -904,7 +911,7 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, std::string resolved; switch(resolve_gkfs_path(dfd, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading Loading @@ -934,7 +941,7 @@ stat64(const char* path, struct stat64* buf) { std::string resolved; switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, &st); convert(&st, buf); return res; Loading @@ -956,7 +963,7 @@ int fstat(int fd, struct stat* buf) { initializeGekko(); if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path()); DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } GKFS_FALLBACK(fstat, _STAT_VER, fd, buf); Loading @@ -969,7 +976,7 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) { std::string resolved; switch(resolve_gkfs_path(dfd, path, resolved)) { case PathStatus::Internal: { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); auto res = gkfs::syscall::gkfs_stat(resolved, buf); return res; } Loading Loading @@ -999,7 +1006,7 @@ rename(const char* oldpath, const char* newpath) { case PathStatus::Internal: switch(rstatus_new) { case PathStatus::Internal: LOG(DEBUG, "[GKFS] {} {}{}", "NOT IMPLEMENTED", DEBUG_INFO("[GKFS] {} {}{}", "NOT IMPLEMENTED", resolved_old, resolved_new); return -ENOTDIR; // return Loading Loading @@ -1050,7 +1057,7 @@ pipe(int pipefd[2]) { initializeGekko(); auto res = dlsym_pipe(pipefd); LOG(DEBUG, "pipe {} <---> {}", pipefd[0], pipefd[1]); DEBUG_INFO("pipe {} <---> {}", pipefd[0], pipefd[1]); // GKFS_FALLBACK(pipe, pipefd); return res; Loading @@ -1067,13 +1074,13 @@ int dup2(int fd, int fd2) { initializeGekko(); if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2); DEBUG_INFO("[GKFS] DUP2 G{} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } else if(is_gkfs_fd(fd2)) { LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2); DEBUG_INFO("[GKFS-NON] DUP2 {} --> G{}", fd, fd2); return gkfs::syscall::gkfs_dup(fd); } else if(is_gkfs_fd(fd)) { LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2); DEBUG_INFO("[GKFS-NON] DUP2 G{} --> {}", fd, fd2); return gkfs::syscall::gkfs_dup2(fd, fd2); } Loading Loading @@ -1114,7 +1121,7 @@ chdir(const char* path) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: LOG(DEBUG, "[GKFS] NOT IMPLEMENTED {}", path); DEBUG_INFO("[GKFS] NOT IMPLEMENTED {}", path); break; default: Loading @@ -1138,12 +1145,12 @@ fcntl(int fd, int cmd, long arg) // TODO switch(cmd) { case F_DUPFD: LOG(DEBUG, "[GKFS] DUPFD {}", fd); DEBUG_INFO("[GKFS] DUPFD {}", fd); return gkfs::syscall::gkfs_dup(fd); case F_DUPFD_CLOEXEC: LOG(DEBUG, "[GKFS] F_DUPFD_CLOEXEC {}", fd); DEBUG_INFO("[GKFS] F_DUPFD_CLOEXEC {}", fd); ret = gkfs::syscall::gkfs_dup(fd); if(ret == -1) { return -errno; Loading @@ -1153,7 +1160,7 @@ fcntl(int fd, int cmd, long arg) // TODO return ret; case F_GETFD: LOG(DEBUG, "[GKFS] F_GETFD {}", fd); DEBUG_INFO("[GKFS] F_GETFD {}", fd); if(CTX->file_map()->get(fd)->get_flag( gkfs::filemap::OpenFile_flags::cloexec)) { return FD_CLOEXEC; Loading @@ -1161,7 +1168,7 @@ fcntl(int fd, int cmd, long arg) // TODO return 0; case F_GETFL: LOG(DEBUG, "[GKFS] F_GETFL {}", fd); DEBUG_INFO("[GKFS] F_GETFL {}", fd); ret = 0; if(CTX->file_map()->get(fd)->get_flag( gkfs::filemap::OpenFile_flags::rdonly)) { Loading @@ -1178,18 +1185,18 @@ fcntl(int fd, int cmd, long arg) // TODO return ret; case F_SETFD: LOG(DEBUG, "[GKFS] F_SETFD {}", fd); DEBUG_INFO("[GKFS] F_SETFD {}", fd); CTX->file_map()->get(fd)->set_flag( gkfs::filemap::OpenFile_flags::cloexec, (arg & FD_CLOEXEC)); return 0; case F_GETLK: LOG(DEBUG, "[GKFS] F_GETLK {}", fd); DEBUG_INFO("[GKFS] F_GETLK {}", fd); return 0; case F_SETLK: LOG(DEBUG, "[GKFS] F_SETLK {}", fd); DEBUG_INFO("[GKFS] F_SETLK {}", fd); return 0; default: Loading Loading @@ -1224,7 +1231,7 @@ realpath(const char* path, char* resolved_path) { return nullptr; case gkfs::preload::RelativizeStatus::internal: LOG(DEBUG, "[GKFS] {} --> {}", resolved, path); DEBUG_INFO("[GKFS] {} --> {}", resolved, path); if(resolved_path == nullptr) { resolved_path = static_cast<char*>(malloc(resolved.size() + 1)); Loading Loading @@ -1289,7 +1296,7 @@ opendir(const char* dirname) { std::string resolved; if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) == PathStatus::Internal) { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); return gekko_opendir(resolved); } } Loading @@ -1303,7 +1310,7 @@ opendir64(const char* dirname) { std::string resolved; if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) == PathStatus::Internal) { LOG(DEBUG, "[GKFS] {}", resolved); DEBUG_INFO("[GKFS] {}", resolved); return gekko_opendir(resolved); } } Loading Loading @@ -1427,7 +1434,7 @@ closedir(DIR* dirp) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] {}", dirp->fd); DEBUG_INFO("[GKFS] {}", dirp->fd); ret = gkfs::syscall::gkfs_close(dirp->fd); free(dirp->path); free(dirp); Loading @@ -1446,7 +1453,7 @@ telldir(DIR* dirp) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] NOT IMPLEMENTED"); DEBUG_INFO("[GKFS] NOT IMPLEMENTED"); ret = 0; // ret = gkfs::syscall::gkfs_telldir(dirp->fd); return ret; Loading @@ -1463,7 +1470,7 @@ seekdir(DIR* dirp, long loc) { initializeGekko(); if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { LOG(DEBUG, "[GKFS] NOT IMPLEMENTED"); DEBUG_INFO("[GKFS] NOT IMPLEMENTED"); return; } } Loading Loading @@ -1519,7 +1526,7 @@ fopen(const char* path, const char* mode) { flags = O_WRONLY | O_CREAT | O_APPEND; if(strchr(mode, '+')) flags = O_RDWR | O_CREAT; LOG(DEBUG, "[GEKKO] {}", resolved); DEBUG_INFO("[GEKKO] {}", resolved); const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags); if(fd < 0) return nullptr; Loading Loading @@ -1547,7 +1554,7 @@ freopen64(const char* path, const char* mode, FILE* stream) { flags = O_WRONLY | O_CREAT | O_APPEND; if(strchr(mode, '+')) flags = O_RDWR | O_CREAT; LOG(DEBUG, "[GEKKO] {}", resolved); DEBUG_INFO("[GEKKO] {}", resolved); const int fd = gkfs::syscall::gkfs_open(resolved, 0666, flags); if(fd < 0) return nullptr; Loading @@ -1563,7 +1570,7 @@ freopen64(const char* path, const char* mode, FILE* stream) { size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GEKKO] {}", stream->_fileno); DEBUG_INFO("[GEKKO] {}", stream->_fileno); return gkfs::syscall::gkfs_read(stream->_fileno, ptr, size * nmemb) / size; } Loading @@ -1576,7 +1583,7 @@ fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GEKKO] {}", stream->_fileno); DEBUG_INFO("[GEKKO] {}", stream->_fileno); return gkfs::syscall::gkfs_write(stream->_fileno, ptr, size * nmemb) / size; } Loading @@ -1588,7 +1595,7 @@ int fseek(FILE* stream, long int offset, int whence) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); return gkfs::syscall::gkfs_lseek(stream->_fileno, offset, whence); } Loading @@ -1599,7 +1606,7 @@ long ftell(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); return gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR); } Loading @@ -1610,7 +1617,7 @@ void rewind(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_SET); } GKFS_FALLBACK(rewind, stream) Loading @@ -1621,7 +1628,7 @@ fclose(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); auto ret = gkfs::syscall::gkfs_close(stream->_fileno); // should I do a fclose (stream)? free(stream); Loading @@ -1636,7 +1643,7 @@ int feof(FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); off_t cur = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR); off_t end = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_END); gkfs::syscall::gkfs_lseek(stream->_fileno, cur, SEEK_SET); Loading @@ -1658,7 +1665,7 @@ fgets(char* str, int n, FILE* stream) { initializeGekko(); if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) { // read str n chars LOG(DEBUG, "[GKFS] {}", stream->_fileno); DEBUG_INFO("[GKFS] {}", stream->_fileno); auto l = gkfs::syscall::gkfs_read(stream->_fileno, str, n); if(l == 0) { return NULL; Loading @@ -1678,3 +1685,68 @@ fflush(FILE* stream) { } GKFS_FALLBACK(fflush, stream) } void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { initializeGekko(); if(is_gkfs_fd(fd)) { DEBUG_INFO("[GKFS] {}", CTX->file_map()->get(fd)->path()); // create a malloc of length void* ptr = malloc(length); if(ptr == nullptr) { return MAP_FAILED; } // store info on mmap_set mmap_set.insert(std::make_tuple(ptr, fd, length, offset)); gkfs::syscall::gkfs_pread(fd, ptr, length, offset); return ptr; } GKFS_FALLBACK(mmap, addr, length, prot, flags, fd, offset); } // implement msync, if addr is from gekkofs (we should have a set with them) // We pwrite length to the original offset (also from the set), and return // if not just go to the normal msync int msync(void* addr, size_t length, int flags) { initializeGekko(); // check if addr is from gekkofs (mmap_set) // if so, get the fd and offset // pwrite length to the original offset // return // if not just go to the normal msync for(const auto& tuple : mmap_set) { if(std::get<0>(tuple) == addr) { int fd = std::get<1>(tuple); off_t offset = std::get<3>(tuple); gkfs::syscall::gkfs_pwrite(fd, addr, length, offset); return 0; } } GKFS_FALLBACK(msync, addr, length, flags); } // implement munmap, if it's on the set, call msync, free memory int munmap(void* addr, size_t length) { initializeGekko(); // check if addr is from gekkofs (mmap_set) // if so, call msync // free memory // return // if not just go to the normal munmap for(auto it = mmap_set.begin(); it != mmap_set.end(); ++it) { if(std::get<0>(*it) == addr) { msync(addr, length, 0); free(addr); mmap_set.erase(it); return 0; } } GKFS_FALLBACK(munmap, addr, length); }