Loading ifs/include/preload/hooks.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); int hook_chdir(const char* path); int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); #endif ifs/src/preload/hooks.cpp +78 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <libsyscall_intercept_hook_point.h> #include <sys/stat.h> #include <fcntl.h> #include <memory> static inline int with_errno(int ret) { return (ret < 0)? -errno : ret; Loading Loading @@ -264,3 +264,80 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { } return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode); } int hook_chdir(const char * path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; bool internal = CTX->relativize_path(path, rel_path); if (internal) { //path falls in our namespace struct stat st; if(adafs_stat(rel_path, &st) != 0) { CTX->log()->error("{}() path does not exists", __func__); return -ENOENT; } if(!S_ISDIR(st.st_mode)) { CTX->log()->error("{}() path is not a directory", __func__); return -ENOTDIR; } //TODO get complete path from relativize_path instead of // removing mountdir and then adding again here rel_path.insert(0, CTX->mountdir()); if (has_trailing_slash(rel_path)) { // open_dir is '/' rel_path.pop_back(); } } try { set_cwd(rel_path, internal); } catch (const std::system_error& se) { return -1; } return 0; } int hook_fchdir(unsigned int fd) { CTX->log()->trace("{}() called with fd {}", __func__, fd); if (CTX->file_map()->exist(fd)) { auto open_file = CTX->file_map()->get(fd); auto open_dir = std::static_pointer_cast<OpenDir>(open_file); if(!open_dir){ //Cast did not succeeded: open_file is a regular file CTX->log()->error("{}() file descriptor refers to a normal file: '{}'", __func__, open_dir->path()); return -EBADF; } std::string new_path = CTX->mountdir() + open_dir->path(); if (has_trailing_slash(new_path)) { // open_dir is '/' new_path.pop_back(); } try { set_cwd(new_path, true); } catch (const std::system_error& se) { return -1; } } else { long ret = syscall_no_intercept(SYS_fchdir, fd); if (ret < 0) { throw std::system_error(syscall_error_code(ret), std::system_category(), "Failed to change directory (fchdir syscall)"); } unset_env_cwd(); CTX->cwd(get_sys_cwd()); } return 0; } int hook_getcwd(char * buf, unsigned long size) { CTX->log()->trace("{}() called with size {}", __func__, size); if(CTX->cwd().size() + 1 > size) { CTX->log()->error("{}() buffer too small to host current working dir", __func__); return -ERANGE; } strcpy(buf, CTX->cwd().c_str()); return (CTX->cwd().size() + 1); } ifs/src/preload/intercept.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,19 @@ static inline int hook(long syscall_number, static_cast<mode_t>(arg1)); break; case SYS_chdir: *result = hook_chdir(reinterpret_cast<const char *>(arg0)); break; case SYS_fchdir: *result = hook_fchdir(static_cast<unsigned int>(arg0)); break; case SYS_getcwd: *result = hook_getcwd(reinterpret_cast<char *>(arg0), static_cast<unsigned long>(arg1)); break; default: /* * Ignore any other syscalls Loading Loading
ifs/include/preload/hooks.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); int hook_chdir(const char* path); int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); #endif
ifs/src/preload/hooks.cpp +78 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ #include <libsyscall_intercept_hook_point.h> #include <sys/stat.h> #include <fcntl.h> #include <memory> static inline int with_errno(int ret) { return (ret < 0)? -errno : ret; Loading Loading @@ -264,3 +264,80 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { } return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode); } int hook_chdir(const char * path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; bool internal = CTX->relativize_path(path, rel_path); if (internal) { //path falls in our namespace struct stat st; if(adafs_stat(rel_path, &st) != 0) { CTX->log()->error("{}() path does not exists", __func__); return -ENOENT; } if(!S_ISDIR(st.st_mode)) { CTX->log()->error("{}() path is not a directory", __func__); return -ENOTDIR; } //TODO get complete path from relativize_path instead of // removing mountdir and then adding again here rel_path.insert(0, CTX->mountdir()); if (has_trailing_slash(rel_path)) { // open_dir is '/' rel_path.pop_back(); } } try { set_cwd(rel_path, internal); } catch (const std::system_error& se) { return -1; } return 0; } int hook_fchdir(unsigned int fd) { CTX->log()->trace("{}() called with fd {}", __func__, fd); if (CTX->file_map()->exist(fd)) { auto open_file = CTX->file_map()->get(fd); auto open_dir = std::static_pointer_cast<OpenDir>(open_file); if(!open_dir){ //Cast did not succeeded: open_file is a regular file CTX->log()->error("{}() file descriptor refers to a normal file: '{}'", __func__, open_dir->path()); return -EBADF; } std::string new_path = CTX->mountdir() + open_dir->path(); if (has_trailing_slash(new_path)) { // open_dir is '/' new_path.pop_back(); } try { set_cwd(new_path, true); } catch (const std::system_error& se) { return -1; } } else { long ret = syscall_no_intercept(SYS_fchdir, fd); if (ret < 0) { throw std::system_error(syscall_error_code(ret), std::system_category(), "Failed to change directory (fchdir syscall)"); } unset_env_cwd(); CTX->cwd(get_sys_cwd()); } return 0; } int hook_getcwd(char * buf, unsigned long size) { CTX->log()->trace("{}() called with size {}", __func__, size); if(CTX->cwd().size() + 1 > size) { CTX->log()->error("{}() buffer too small to host current working dir", __func__); return -ERANGE; } strcpy(buf, CTX->cwd().c_str()); return (CTX->cwd().size() + 1); }
ifs/src/preload/intercept.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,19 @@ static inline int hook(long syscall_number, static_cast<mode_t>(arg1)); break; case SYS_chdir: *result = hook_chdir(reinterpret_cast<const char *>(arg0)); break; case SYS_fchdir: *result = hook_fchdir(static_cast<unsigned int>(arg0)); break; case SYS_getcwd: *result = hook_getcwd(reinterpret_cast<char *>(arg0), static_cast<unsigned long>(arg1)); break; default: /* * Ignore any other syscalls Loading