Loading src/client/hooks.cpp +72 −53 Original line number Diff line number Diff line Loading @@ -56,6 +56,19 @@ with_errno(int ret) { } // namespace template <class... Args> inline long syscall_no_intercept_wrapper(long syscall_number, Args... args) { long result; int error; result = syscall_no_intercept(syscall_number, args...); error = syscall_error_code(result); if(error != 0) { return -error; } return result; } namespace gkfs::hook { int Loading Loading @@ -103,7 +116,7 @@ hook_close(int fd) { return 0; } return syscall_no_intercept(SYS_close, fd); return syscall_no_intercept_wrapper(SYS_close, fd); } int Loading @@ -116,7 +129,8 @@ hook_stat(const char* path, struct stat* buf) { if(CTX->relativize_path(path, rel_path, false)) { return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_stat, rel_path.c_str(), buf); } #ifdef STATX_TYPE Loading Loading @@ -167,7 +181,8 @@ hook_lstat(const char* path, struct stat* buf) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_lstat, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_lstat, rel_path.c_str(), buf); ; } int Loading @@ -179,7 +194,7 @@ hook_fstat(unsigned int fd, struct stat* buf) { auto path = CTX->file_map()->get(fd)->path(); return with_errno(gkfs::syscall::gkfs_stat(path, buf)); } return syscall_no_intercept(SYS_fstat, fd, buf); return syscall_no_intercept_wrapper(SYS_fstat, fd, buf); } int Loading @@ -197,12 +212,12 @@ hook_fstatat(int dirfd, const char* cpath, struct stat* buf, int flags) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf, flags); return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd, cpath, buf, flags); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags); return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -225,7 +240,7 @@ hook_read(unsigned int fd, void* buf, size_t count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_read(fd, buf, count)); } return syscall_no_intercept(SYS_read, fd, buf, count); return syscall_no_intercept_wrapper(SYS_read, fd, buf, count); } int Loading @@ -239,7 +254,7 @@ hook_pread(unsigned int fd, char* buf, size_t count, loff_t pos) { } /* Since kernel 2.6: pread() became pread64(), and pwrite() became * pwrite64(). */ return syscall_no_intercept(SYS_pread64, fd, buf, count, pos); return syscall_no_intercept_wrapper(SYS_pread64, fd, buf, count, pos); } int Loading @@ -251,7 +266,7 @@ hook_readv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_readv(fd, iov, iovcnt)); } return syscall_no_intercept(SYS_readv, fd, iov, iovcnt); return syscall_no_intercept_wrapper(SYS_readv, fd, iov, iovcnt); } int Loading @@ -267,7 +282,7 @@ hook_preadv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_preadv(fd, iov, iovcnt, pos_l)); } return syscall_no_intercept(SYS_preadv, fd, iov, iovcnt, pos_l); return syscall_no_intercept_wrapper(SYS_preadv, fd, iov, iovcnt, pos_l); } int Loading @@ -279,7 +294,7 @@ hook_write(unsigned int fd, const char* buf, size_t count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_write(fd, buf, count)); } return syscall_no_intercept(SYS_write, fd, buf, count); return syscall_no_intercept_wrapper(SYS_write, fd, buf, count); } int Loading @@ -293,7 +308,7 @@ hook_pwrite(unsigned int fd, const char* buf, size_t count, loff_t pos) { } /* Since kernel 2.6: pread() became pread64(), and pwrite() became * pwrite64(). */ return syscall_no_intercept(SYS_pwrite64, fd, buf, count, pos); return syscall_no_intercept_wrapper(SYS_pwrite64, fd, buf, count, pos); } int Loading @@ -305,7 +320,7 @@ hook_writev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_writev(fd, iov, iovcnt)); } return syscall_no_intercept(SYS_writev, fd, iov, iovcnt); return syscall_no_intercept_wrapper(SYS_writev, fd, iov, iovcnt); } int Loading @@ -321,7 +336,7 @@ hook_pwritev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_pwritev(fd, iov, iovcnt, pos_l)); } return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt, pos_l); return syscall_no_intercept_wrapper(SYS_pwritev, fd, iov, iovcnt, pos_l); } int Loading @@ -339,11 +354,12 @@ hook_unlinkat(int dirfd, const char* cpath, int flags) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags); return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd, cpath, flags); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_unlinkat, dirfd, resolved.c_str(), flags); return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd, resolved.c_str(), flags); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading Loading @@ -378,11 +394,11 @@ hook_symlinkat(const char* oldname, int newdfd, const char* newname) { CTX->relativize_fd_path(newdfd, newname, newname_resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd, newname); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd, newname_resolved.c_str()); case gkfs::preload::RelativizeStatus::fd_not_a_dir: Loading Loading @@ -412,7 +428,7 @@ hook_access(const char* path, int mask) { } return ret; } return syscall_no_intercept(SYS_access, rel_path.c_str(), mask); return syscall_no_intercept_wrapper(SYS_access, rel_path.c_str(), mask); } int Loading @@ -425,11 +441,12 @@ hook_faccessat(int dirfd, const char* cpath, int mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_faccessat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_faccessat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_faccessat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading Loading @@ -460,7 +477,7 @@ hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { LOG(DEBUG, "{}() returning {}", __func__, off_ret); return off_ret; } return syscall_no_intercept(SYS_lseek, fd, offset, whence); return syscall_no_intercept_wrapper(SYS_lseek, fd, offset, whence); } int Loading @@ -472,7 +489,7 @@ hook_truncate(const char* path, long length) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_truncate(rel_path, length)); } return syscall_no_intercept(SYS_truncate, rel_path.c_str(), length); return syscall_no_intercept_wrapper(SYS_truncate, rel_path.c_str(), length); } int Loading @@ -484,7 +501,7 @@ hook_ftruncate(unsigned int fd, unsigned long length) { auto path = CTX->file_map()->get(fd)->path(); return with_errno(gkfs::syscall::gkfs_truncate(path, length)); } return syscall_no_intercept(SYS_ftruncate, fd, length); return syscall_no_intercept_wrapper(SYS_ftruncate, fd, length); } int Loading @@ -495,7 +512,7 @@ hook_dup(unsigned int fd) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_dup(fd)); } return syscall_no_intercept(SYS_dup, fd); return syscall_no_intercept_wrapper(SYS_dup, fd); } int Loading @@ -506,7 +523,7 @@ hook_dup2(unsigned int oldfd, unsigned int newfd) { if(CTX->file_map()->exist(oldfd)) { return with_errno(gkfs::syscall::gkfs_dup2(oldfd, newfd)); } return syscall_no_intercept(SYS_dup2, oldfd, newfd); return syscall_no_intercept_wrapper(SYS_dup2, oldfd, newfd); } int Loading @@ -521,7 +538,7 @@ hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) { LOG(WARNING, "{}() Not supported", __func__); return -ENOTSUP; } return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags); return syscall_no_intercept_wrapper(SYS_dup3, oldfd, newfd, flags); } int Loading @@ -533,7 +550,7 @@ hook_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_getdents(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents, fd, dirp, count); return syscall_no_intercept_wrapper(SYS_getdents, fd, dirp, count); } Loading @@ -547,7 +564,7 @@ hook_getdents64(unsigned int fd, struct linux_dirent64* dirp, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_getdents64(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents64, fd, dirp, count); return syscall_no_intercept_wrapper(SYS_getdents64, fd, dirp, count); } Loading @@ -561,11 +578,12 @@ hook_mkdirat(int dirfd, const char* cpath, mode_t mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -590,11 +608,12 @@ hook_fchmodat(int dirfd, const char* cpath, mode_t mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_fchmodat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -618,7 +637,7 @@ hook_fchmod(unsigned int fd, mode_t mode) { LOG(WARNING, "{}() operation not supported", __func__); return -ENOTSUP; } return syscall_no_intercept(SYS_fchmod, fd, mode); return syscall_no_intercept_wrapper(SYS_fchmod, fd, mode); } int Loading Loading @@ -681,7 +700,7 @@ hook_fchdir(unsigned int fd) { return -(se.code().value()); } } else { long ret = syscall_no_intercept(SYS_fchdir, fd); long ret = syscall_no_intercept_wrapper(SYS_fchdir, fd); if(ret < 0) { throw std::system_error( syscall_error_code(ret), std::system_category(), Loading Loading @@ -719,12 +738,12 @@ hook_readlinkat(int dirfd, const char* cpath, char* buf, int bufsiz) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf, bufsiz); return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd, cpath, buf, bufsiz); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz); return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -746,7 +765,7 @@ hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { arg); if(!CTX->file_map()->exist(fd)) { return syscall_no_intercept(SYS_fcntl, fd, cmd, arg); return syscall_no_intercept_wrapper(SYS_fcntl, fd, cmd, arg); } int ret; switch(cmd) { Loading Loading @@ -864,8 +883,8 @@ hook_renameat(int olddfd, const char* oldname, int newdfd, const char* newname, return -EINVAL; } return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); return syscall_no_intercept_wrapper(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); } int Loading @@ -878,7 +897,7 @@ hook_statfs(const char* path, struct statfs* buf) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_statfs(buf)); } return syscall_no_intercept(SYS_statfs, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_statfs, rel_path.c_str(), buf); } int Loading @@ -889,7 +908,7 @@ hook_fstatfs(unsigned int fd, struct statfs* buf) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_statfs(buf)); } return syscall_no_intercept(SYS_fstatfs, fd, buf); return syscall_no_intercept_wrapper(SYS_fstatfs, fd, buf); } /* The function should broadcast a flush message (pmem_persist i.e.) if the Loading @@ -904,7 +923,7 @@ hook_fsync(unsigned int fd) { return 0; } return syscall_no_intercept(SYS_fsync, fd); return syscall_no_intercept_wrapper(SYS_fsync, fd); } } // namespace gkfs::hook src/client/intercept.cpp +40 −13 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, const long args[gkfs::syscall::MAX_ARGS] = {arg0, arg1, arg2, arg3, arg4, arg5}; #endif int syserror = 0; LOG(SYSCALL, gkfs::syscall::from_internal_code | gkfs::syscall::to_hook | Loading @@ -96,9 +97,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept( syscall_number, reinterpret_cast<char*>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -107,9 +111,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept( syscall_number, reinterpret_cast<const char*>(arg0), O_WRONLY | O_CREAT | O_TRUNC, static_cast<mode_t>(arg1)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -119,19 +126,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, syscall_number, static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; case SYS_epoll_create: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -139,9 +151,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, case SYS_epoll_create1: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -149,8 +164,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, case SYS_dup: *result = syscall_no_intercept(syscall_number, static_cast<unsigned int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading @@ -160,8 +176,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept(syscall_number, static_cast<unsigned int>(arg0), static_cast<unsigned int>(arg1)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading @@ -172,7 +189,11 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, syscall_number, static_cast<unsigned int>(arg0), static_cast<unsigned int>(arg1), static_cast<int>(arg2)); if(*result >= 0) { syserror = syscall_error_code(*result); if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading Loading @@ -370,18 +391,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0), static_cast<int>(arg1), arg2); syserror = syscall_error_code(*result); if(*result >= 0 && (static_cast<int>(arg1) == F_DUPFD || if(syserror == 0) { if((static_cast<int>(arg1) == F_DUPFD || static_cast<int>(arg1) == F_DUPFD_CLOEXEC)) { *result = CTX->register_internal_fd(*result); } } break; case SYS_close: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result == 0) { if(syserror == 0) { CTX->unregister_internal_fd(arg0); } break; Loading src/client/preload_context.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -395,8 +395,8 @@ PreloadContext::protect_user_fds() { const auto fd_is_open = [](int fd) -> bool { const int ret = ::syscall_no_intercept(SYS_fcntl, fd, F_GETFD); return ::syscall_error_code(ret) == 0 || ::syscall_error_code(ret) != EBADF; const int error = ::syscall_error_code(ret); return error == 0 || error != EBADF; }; for(int fd = 0; fd < MAX_USER_FDS; ++fd) { Loading Loading
src/client/hooks.cpp +72 −53 Original line number Diff line number Diff line Loading @@ -56,6 +56,19 @@ with_errno(int ret) { } // namespace template <class... Args> inline long syscall_no_intercept_wrapper(long syscall_number, Args... args) { long result; int error; result = syscall_no_intercept(syscall_number, args...); error = syscall_error_code(result); if(error != 0) { return -error; } return result; } namespace gkfs::hook { int Loading Loading @@ -103,7 +116,7 @@ hook_close(int fd) { return 0; } return syscall_no_intercept(SYS_close, fd); return syscall_no_intercept_wrapper(SYS_close, fd); } int Loading @@ -116,7 +129,8 @@ hook_stat(const char* path, struct stat* buf) { if(CTX->relativize_path(path, rel_path, false)) { return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_stat, rel_path.c_str(), buf); } #ifdef STATX_TYPE Loading Loading @@ -167,7 +181,8 @@ hook_lstat(const char* path, struct stat* buf) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_lstat, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_lstat, rel_path.c_str(), buf); ; } int Loading @@ -179,7 +194,7 @@ hook_fstat(unsigned int fd, struct stat* buf) { auto path = CTX->file_map()->get(fd)->path(); return with_errno(gkfs::syscall::gkfs_stat(path, buf)); } return syscall_no_intercept(SYS_fstat, fd, buf); return syscall_no_intercept_wrapper(SYS_fstat, fd, buf); } int Loading @@ -197,12 +212,12 @@ hook_fstatat(int dirfd, const char* cpath, struct stat* buf, int flags) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf, flags); return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd, cpath, buf, flags); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags); return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -225,7 +240,7 @@ hook_read(unsigned int fd, void* buf, size_t count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_read(fd, buf, count)); } return syscall_no_intercept(SYS_read, fd, buf, count); return syscall_no_intercept_wrapper(SYS_read, fd, buf, count); } int Loading @@ -239,7 +254,7 @@ hook_pread(unsigned int fd, char* buf, size_t count, loff_t pos) { } /* Since kernel 2.6: pread() became pread64(), and pwrite() became * pwrite64(). */ return syscall_no_intercept(SYS_pread64, fd, buf, count, pos); return syscall_no_intercept_wrapper(SYS_pread64, fd, buf, count, pos); } int Loading @@ -251,7 +266,7 @@ hook_readv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_readv(fd, iov, iovcnt)); } return syscall_no_intercept(SYS_readv, fd, iov, iovcnt); return syscall_no_intercept_wrapper(SYS_readv, fd, iov, iovcnt); } int Loading @@ -267,7 +282,7 @@ hook_preadv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_preadv(fd, iov, iovcnt, pos_l)); } return syscall_no_intercept(SYS_preadv, fd, iov, iovcnt, pos_l); return syscall_no_intercept_wrapper(SYS_preadv, fd, iov, iovcnt, pos_l); } int Loading @@ -279,7 +294,7 @@ hook_write(unsigned int fd, const char* buf, size_t count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_write(fd, buf, count)); } return syscall_no_intercept(SYS_write, fd, buf, count); return syscall_no_intercept_wrapper(SYS_write, fd, buf, count); } int Loading @@ -293,7 +308,7 @@ hook_pwrite(unsigned int fd, const char* buf, size_t count, loff_t pos) { } /* Since kernel 2.6: pread() became pread64(), and pwrite() became * pwrite64(). */ return syscall_no_intercept(SYS_pwrite64, fd, buf, count, pos); return syscall_no_intercept_wrapper(SYS_pwrite64, fd, buf, count, pos); } int Loading @@ -305,7 +320,7 @@ hook_writev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_writev(fd, iov, iovcnt)); } return syscall_no_intercept(SYS_writev, fd, iov, iovcnt); return syscall_no_intercept_wrapper(SYS_writev, fd, iov, iovcnt); } int Loading @@ -321,7 +336,7 @@ hook_pwritev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_pwritev(fd, iov, iovcnt, pos_l)); } return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt, pos_l); return syscall_no_intercept_wrapper(SYS_pwritev, fd, iov, iovcnt, pos_l); } int Loading @@ -339,11 +354,12 @@ hook_unlinkat(int dirfd, const char* cpath, int flags) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags); return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd, cpath, flags); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_unlinkat, dirfd, resolved.c_str(), flags); return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd, resolved.c_str(), flags); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading Loading @@ -378,11 +394,11 @@ hook_symlinkat(const char* oldname, int newdfd, const char* newname) { CTX->relativize_fd_path(newdfd, newname, newname_resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd, newname); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd, newname_resolved.c_str()); case gkfs::preload::RelativizeStatus::fd_not_a_dir: Loading Loading @@ -412,7 +428,7 @@ hook_access(const char* path, int mask) { } return ret; } return syscall_no_intercept(SYS_access, rel_path.c_str(), mask); return syscall_no_intercept_wrapper(SYS_access, rel_path.c_str(), mask); } int Loading @@ -425,11 +441,12 @@ hook_faccessat(int dirfd, const char* cpath, int mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_faccessat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_faccessat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_faccessat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading Loading @@ -460,7 +477,7 @@ hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { LOG(DEBUG, "{}() returning {}", __func__, off_ret); return off_ret; } return syscall_no_intercept(SYS_lseek, fd, offset, whence); return syscall_no_intercept_wrapper(SYS_lseek, fd, offset, whence); } int Loading @@ -472,7 +489,7 @@ hook_truncate(const char* path, long length) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_truncate(rel_path, length)); } return syscall_no_intercept(SYS_truncate, rel_path.c_str(), length); return syscall_no_intercept_wrapper(SYS_truncate, rel_path.c_str(), length); } int Loading @@ -484,7 +501,7 @@ hook_ftruncate(unsigned int fd, unsigned long length) { auto path = CTX->file_map()->get(fd)->path(); return with_errno(gkfs::syscall::gkfs_truncate(path, length)); } return syscall_no_intercept(SYS_ftruncate, fd, length); return syscall_no_intercept_wrapper(SYS_ftruncate, fd, length); } int Loading @@ -495,7 +512,7 @@ hook_dup(unsigned int fd) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_dup(fd)); } return syscall_no_intercept(SYS_dup, fd); return syscall_no_intercept_wrapper(SYS_dup, fd); } int Loading @@ -506,7 +523,7 @@ hook_dup2(unsigned int oldfd, unsigned int newfd) { if(CTX->file_map()->exist(oldfd)) { return with_errno(gkfs::syscall::gkfs_dup2(oldfd, newfd)); } return syscall_no_intercept(SYS_dup2, oldfd, newfd); return syscall_no_intercept_wrapper(SYS_dup2, oldfd, newfd); } int Loading @@ -521,7 +538,7 @@ hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) { LOG(WARNING, "{}() Not supported", __func__); return -ENOTSUP; } return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags); return syscall_no_intercept_wrapper(SYS_dup3, oldfd, newfd, flags); } int Loading @@ -533,7 +550,7 @@ hook_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_getdents(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents, fd, dirp, count); return syscall_no_intercept_wrapper(SYS_getdents, fd, dirp, count); } Loading @@ -547,7 +564,7 @@ hook_getdents64(unsigned int fd, struct linux_dirent64* dirp, if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_getdents64(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents64, fd, dirp, count); return syscall_no_intercept_wrapper(SYS_getdents64, fd, dirp, count); } Loading @@ -561,11 +578,12 @@ hook_mkdirat(int dirfd, const char* cpath, mode_t mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -590,11 +608,12 @@ hook_fchmodat(int dirfd, const char* cpath, mode_t mode) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode); return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd, cpath, mode); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_fchmodat, dirfd, resolved.c_str(), mode); return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd, resolved.c_str(), mode); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -618,7 +637,7 @@ hook_fchmod(unsigned int fd, mode_t mode) { LOG(WARNING, "{}() operation not supported", __func__); return -ENOTSUP; } return syscall_no_intercept(SYS_fchmod, fd, mode); return syscall_no_intercept_wrapper(SYS_fchmod, fd, mode); } int Loading Loading @@ -681,7 +700,7 @@ hook_fchdir(unsigned int fd) { return -(se.code().value()); } } else { long ret = syscall_no_intercept(SYS_fchdir, fd); long ret = syscall_no_intercept_wrapper(SYS_fchdir, fd); if(ret < 0) { throw std::system_error( syscall_error_code(ret), std::system_category(), Loading Loading @@ -719,12 +738,12 @@ hook_readlinkat(int dirfd, const char* cpath, char* buf, int bufsiz) { auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf, bufsiz); return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd, cpath, buf, bufsiz); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz); return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; Loading @@ -746,7 +765,7 @@ hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { arg); if(!CTX->file_map()->exist(fd)) { return syscall_no_intercept(SYS_fcntl, fd, cmd, arg); return syscall_no_intercept_wrapper(SYS_fcntl, fd, cmd, arg); } int ret; switch(cmd) { Loading Loading @@ -864,8 +883,8 @@ hook_renameat(int olddfd, const char* oldname, int newdfd, const char* newname, return -EINVAL; } return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); return syscall_no_intercept_wrapper(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); } int Loading @@ -878,7 +897,7 @@ hook_statfs(const char* path, struct statfs* buf) { if(CTX->relativize_path(path, rel_path)) { return with_errno(gkfs::syscall::gkfs_statfs(buf)); } return syscall_no_intercept(SYS_statfs, rel_path.c_str(), buf); return syscall_no_intercept_wrapper(SYS_statfs, rel_path.c_str(), buf); } int Loading @@ -889,7 +908,7 @@ hook_fstatfs(unsigned int fd, struct statfs* buf) { if(CTX->file_map()->exist(fd)) { return with_errno(gkfs::syscall::gkfs_statfs(buf)); } return syscall_no_intercept(SYS_fstatfs, fd, buf); return syscall_no_intercept_wrapper(SYS_fstatfs, fd, buf); } /* The function should broadcast a flush message (pmem_persist i.e.) if the Loading @@ -904,7 +923,7 @@ hook_fsync(unsigned int fd) { return 0; } return syscall_no_intercept(SYS_fsync, fd); return syscall_no_intercept_wrapper(SYS_fsync, fd); } } // namespace gkfs::hook
src/client/intercept.cpp +40 −13 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, const long args[gkfs::syscall::MAX_ARGS] = {arg0, arg1, arg2, arg3, arg4, arg5}; #endif int syserror = 0; LOG(SYSCALL, gkfs::syscall::from_internal_code | gkfs::syscall::to_hook | Loading @@ -96,9 +97,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept( syscall_number, reinterpret_cast<char*>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -107,9 +111,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept( syscall_number, reinterpret_cast<const char*>(arg0), O_WRONLY | O_CREAT | O_TRUNC, static_cast<mode_t>(arg1)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -119,19 +126,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, syscall_number, static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; case SYS_epoll_create: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -139,9 +151,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, case SYS_epoll_create1: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } else { *result = -syserror; } break; Loading @@ -149,8 +164,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, case SYS_dup: *result = syscall_no_intercept(syscall_number, static_cast<unsigned int>(arg0)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading @@ -160,8 +176,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept(syscall_number, static_cast<unsigned int>(arg0), static_cast<unsigned int>(arg1)); syserror = syscall_error_code(*result); if(*result >= 0) { if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading @@ -172,7 +189,11 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, syscall_number, static_cast<unsigned int>(arg0), static_cast<unsigned int>(arg1), static_cast<int>(arg2)); if(*result >= 0) { syserror = syscall_error_code(*result); if(syserror == 0) { *result = CTX->register_internal_fd(*result); } Loading Loading @@ -370,18 +391,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0), static_cast<int>(arg1), arg2); syserror = syscall_error_code(*result); if(*result >= 0 && (static_cast<int>(arg1) == F_DUPFD || if(syserror == 0) { if((static_cast<int>(arg1) == F_DUPFD || static_cast<int>(arg1) == F_DUPFD_CLOEXEC)) { *result = CTX->register_internal_fd(*result); } } break; case SYS_close: *result = syscall_no_intercept(syscall_number, static_cast<int>(arg0)); syserror = syscall_error_code(*result); if(*result == 0) { if(syserror == 0) { CTX->unregister_internal_fd(arg0); } break; Loading
src/client/preload_context.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -395,8 +395,8 @@ PreloadContext::protect_user_fds() { const auto fd_is_open = [](int fd) -> bool { const int ret = ::syscall_no_intercept(SYS_fcntl, fd, F_GETFD); return ::syscall_error_code(ret) == 0 || ::syscall_error_code(ret) != EBADF; const int error = ::syscall_error_code(ret); return error == 0 || error != EBADF; }; for(int fd = 0; fd < MAX_USER_FDS; ++fd) { Loading