Loading include/client/hooks.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -18,5 +18,11 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_read(int fd, void* buf, size_t count); int hook_write(int fd, void* buf, size_t count); int hook_unlink(const char* path); #endif src/client/hooks.cpp +68 −33 Original line number Diff line number Diff line Loading @@ -30,47 +30,82 @@ static inline int with_errno(int ret) { int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { if(cpath == nullptr || cpath[0] == '\0') { CTX->log()->error("{}() path is invalid", __func__); CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); std::string resolved; auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); case RelativizeStatus::external: return syscall_no_intercept(SYS_openat, dirfd, resolved.c_str(), flags, mode); case RelativizeStatus::fd_not_a_dir: return -ENOTDIR; case RelativizeStatus::internal: return with_errno(adafs_open(resolved, mode, flags)); default: CTX->log()->error("{}() relativize status unknown: {}", __func__); return -EINVAL; } } CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); int hook_close(int fd) { CTX->log()->trace("{}() called with fd {}", __func__, fd); if(CTX->file_map()->exist(fd)) { // No call to the daemon is required CTX->file_map()->remove(fd); return 0; } return syscall_no_intercept(SYS_close, fd); } std::string resolved; int hook_stat(const char* path, struct stat* buf) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; if (CTX->relativize_path(path, rel_path, false)) { return with_errno(adafs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); } if((cpath[0] == PSP) || (dirfd == AT_FDCWD)) { // cpath is absolute or relative to CWD if (CTX->relativize_path(cpath, resolved)) { int ret = adafs_open(resolved, mode, flags); int hook_read(int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { auto ret = adafs_read(fd, buf, count); if(ret < 0) { return -errno; } return ret; } } else { // cpath is relative if(!(CTX->file_map()->exist(dirfd))) { //TODO relative cpath could still lead to our FS return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); return syscall_no_intercept(SYS_read, fd, buf, count); } auto dir = CTX->file_map()->get_dir(dirfd); if(dir == nullptr) { CTX->log()->error("{}() dirfd is not a directory ", __func__); errno = ENOTDIR; return -1; int hook_write(int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { auto ret = adafs_write(fd, buf, count); if(ret < 0) { return -errno; } return ret; } return syscall_no_intercept(SYS_write, fd, buf, count); } std::string path = CTX->mountdir(); path.append(dir->path()); path.push_back(PSP); path.append(cpath); if(resolve_path(path, resolved)) { int ret = adafs_open(resolved, mode, flags); int hook_unlink(const char* path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; if (CTX->relativize_path(path, rel_path)) { auto ret = adafs_rm_node(rel_path); if(ret < 0) { return -errno; } return ret; } } return 0; return syscall_no_intercept(SYS_unlink, rel_path.c_str()); } src/client/intercept.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,38 @@ static inline int hook(long syscall_number, static_cast<mode_t>(arg2)); break; case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; case SYS_close: *result = hook_close(static_cast<int>(arg0)); break; case SYS_stat: *result = hook_stat(reinterpret_cast<char*>(arg0), reinterpret_cast<struct stat*>(arg1)); break; case SYS_read: *result = hook_read(static_cast<int>(arg0), reinterpret_cast<void*>(arg1), static_cast<size_t>(arg2)); break; case SYS_write: *result = hook_write(static_cast<int>(arg0), reinterpret_cast<void*>(arg1), static_cast<size_t>(arg2)); break; case SYS_unlink: *result = hook_unlink(reinterpret_cast<char*>(arg0)); break; default: /* * Ignore any other syscalls Loading Loading
include/client/hooks.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -18,5 +18,11 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_read(int fd, void* buf, size_t count); int hook_write(int fd, void* buf, size_t count); int hook_unlink(const char* path); #endif
src/client/hooks.cpp +68 −33 Original line number Diff line number Diff line Loading @@ -30,47 +30,82 @@ static inline int with_errno(int ret) { int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { if(cpath == nullptr || cpath[0] == '\0') { CTX->log()->error("{}() path is invalid", __func__); CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); std::string resolved; auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); switch(rstatus) { case RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); case RelativizeStatus::external: return syscall_no_intercept(SYS_openat, dirfd, resolved.c_str(), flags, mode); case RelativizeStatus::fd_not_a_dir: return -ENOTDIR; case RelativizeStatus::internal: return with_errno(adafs_open(resolved, mode, flags)); default: CTX->log()->error("{}() relativize status unknown: {}", __func__); return -EINVAL; } } CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); int hook_close(int fd) { CTX->log()->trace("{}() called with fd {}", __func__, fd); if(CTX->file_map()->exist(fd)) { // No call to the daemon is required CTX->file_map()->remove(fd); return 0; } return syscall_no_intercept(SYS_close, fd); } std::string resolved; int hook_stat(const char* path, struct stat* buf) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; if (CTX->relativize_path(path, rel_path, false)) { return with_errno(adafs_stat(rel_path, buf)); } return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); } if((cpath[0] == PSP) || (dirfd == AT_FDCWD)) { // cpath is absolute or relative to CWD if (CTX->relativize_path(cpath, resolved)) { int ret = adafs_open(resolved, mode, flags); int hook_read(int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { auto ret = adafs_read(fd, buf, count); if(ret < 0) { return -errno; } return ret; } } else { // cpath is relative if(!(CTX->file_map()->exist(dirfd))) { //TODO relative cpath could still lead to our FS return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); return syscall_no_intercept(SYS_read, fd, buf, count); } auto dir = CTX->file_map()->get_dir(dirfd); if(dir == nullptr) { CTX->log()->error("{}() dirfd is not a directory ", __func__); errno = ENOTDIR; return -1; int hook_write(int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { auto ret = adafs_write(fd, buf, count); if(ret < 0) { return -errno; } return ret; } return syscall_no_intercept(SYS_write, fd, buf, count); } std::string path = CTX->mountdir(); path.append(dir->path()); path.push_back(PSP); path.append(cpath); if(resolve_path(path, resolved)) { int ret = adafs_open(resolved, mode, flags); int hook_unlink(const char* path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; if (CTX->relativize_path(path, rel_path)) { auto ret = adafs_rm_node(rel_path); if(ret < 0) { return -errno; } return ret; } } return 0; return syscall_no_intercept(SYS_unlink, rel_path.c_str()); }
src/client/intercept.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,38 @@ static inline int hook(long syscall_number, static_cast<mode_t>(arg2)); break; case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; case SYS_close: *result = hook_close(static_cast<int>(arg0)); break; case SYS_stat: *result = hook_stat(reinterpret_cast<char*>(arg0), reinterpret_cast<struct stat*>(arg1)); break; case SYS_read: *result = hook_read(static_cast<int>(arg0), reinterpret_cast<void*>(arg1), static_cast<size_t>(arg2)); break; case SYS_write: *result = hook_write(static_cast<int>(arg0), reinterpret_cast<void*>(arg1), static_cast<size_t>(arg2)); break; case SYS_unlink: *result = hook_unlink(reinterpret_cast<char*>(arg0)); break; default: /* * Ignore any other syscalls Loading