diff --git a/capio-common/capio/constants.hpp b/capio-common/capio/constants.hpp index decf5a190..23705f856 100644 --- a/capio-common/capio/constants.hpp +++ b/capio-common/capio/constants.hpp @@ -14,9 +14,9 @@ typedef unsigned long long int capio_off64_t; constexpr size_t CAPIO_DEFAULT_DIR_INITIAL_SIZE = 1024L * 1024 * 1024; constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4; [[maybe_unused]] constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = { - std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"}, - std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}, - std::string_view("/spack/")}; + std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"}, + std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}, + std::string_view("/spack/"), std::string_view{"/usr/bin/"}}; // CAPIO default values for shared memory constexpr char CAPIO_DEFAULT_WORKFLOW_NAME[] = "CAPIO"; diff --git a/capio-common/capio/filesystem.hpp b/capio-common/capio/filesystem.hpp index 8c28e0baa..f9513c9c4 100644 --- a/capio-common/capio/filesystem.hpp +++ b/capio-common/capio/filesystem.hpp @@ -73,7 +73,8 @@ inline bool is_capio_path(const std::filesystem::path &path_to_check) { START_LOG(capio_syscall(SYS_gettid), "call(path_to_check=%s)", path_to_check.c_str()); // check if path_to_check begins with CAPIO_DIR - const auto res = is_prefix(get_capio_dir(), path_to_check); + const auto res = + is_prefix(get_capio_dir(), path_to_check) && !is_forbidden_path(path_to_check.string()); LOG("is_capio_path:%s", res ? "yes" : "no"); return res; } diff --git a/capio-posix/handlers/access.hpp b/capio-posix/handlers/access.hpp index 164ba6b31..33a312f4b 100644 --- a/capio-posix/handlers/access.hpp +++ b/capio-posix/handlers/access.hpp @@ -9,7 +9,7 @@ int access_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a const std::string_view pathname(reinterpret_cast(arg0)); auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call()"); - if (is_forbidden_path(pathname) || !is_capio_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -32,7 +32,7 @@ int faccessat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, lon auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call()"); - if (is_forbidden_path(pathname) || !is_capio_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden or is not a capio path: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } diff --git a/capio-posix/handlers/chdir.hpp b/capio-posix/handlers/chdir.hpp index cec94e812..52f542ed7 100644 --- a/capio-posix/handlers/chdir.hpp +++ b/capio-posix/handlers/chdir.hpp @@ -13,7 +13,7 @@ int chdir_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar START_LOG(tid, "call(path=%s)", pathname.data()); syscall_no_intercept_flag = true; - if (is_forbidden_path(pathname) || !is_capio_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); syscall_no_intercept_flag = false; return CAPIO_POSIX_SYSCALL_SKIP; diff --git a/capio-posix/handlers/dup.hpp b/capio-posix/handlers/dup.hpp index 8ee1e1a45..17f1a371d 100644 --- a/capio-posix/handlers/dup.hpp +++ b/capio-posix/handlers/dup.hpp @@ -19,8 +19,7 @@ int dup_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5 } dup_capio_fd(tid, fd, res, false); - *result = res; - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(res, result); } return CAPIO_POSIX_SYSCALL_SKIP; } @@ -43,8 +42,8 @@ int dup2_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg if (fd != res) { dup_capio_fd(tid, fd, res, false); } - *result = res; - return CAPIO_POSIX_SYSCALL_SUCCESS; + + return posix_return_value(res, result); } return CAPIO_POSIX_SYSCALL_SKIP; } @@ -75,8 +74,7 @@ int dup3_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg bool is_cloexec = (flags & O_CLOEXEC) == O_CLOEXEC; dup_capio_fd(tid, fd, res, is_cloexec); - *result = res; - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(res, result); } return CAPIO_POSIX_SYSCALL_SKIP; } diff --git a/capio-posix/handlers/fork.hpp b/capio-posix/handlers/fork.hpp index 0fbf1dbbf..e707c0994 100644 --- a/capio-posix/handlers/fork.hpp +++ b/capio-posix/handlers/fork.hpp @@ -14,14 +14,13 @@ int fork_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg if (pid == 0) { // child - auto child_tid = static_cast(syscall_no_intercept(SYS_gettid)); + const auto child_tid = static_cast(syscall_no_intercept(SYS_gettid)); init_process(child_tid); *result = 0; - } else { - *result = pid; + return posix_return_value(0, result); } - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(pid, result); } #endif // SYS_fork diff --git a/capio-posix/handlers/mkdir.hpp b/capio-posix/handlers/mkdir.hpp index bd78c15c2..c7303f958 100644 --- a/capio-posix/handlers/mkdir.hpp +++ b/capio-posix/handlers/mkdir.hpp @@ -7,7 +7,7 @@ inline off64_t capio_mkdirat(int dirfd, const std::string_view &pathname, mode_t mode, pid_t tid) { START_LOG(tid, "call(dirfd=%d, pathname=%s, mode=%o)", dirfd, pathname.data(), mode); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } diff --git a/capio-posix/handlers/open.hpp b/capio-posix/handlers/open.hpp index 301231297..4038b1fe5 100644 --- a/capio-posix/handlers/open.hpp +++ b/capio-posix/handlers/open.hpp @@ -40,7 +40,7 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar mode_t mode = static_cast(arg2); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -52,7 +52,12 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar LOG("Create request sent"); } - int fd = static_cast(syscall_no_intercept(SYS_creat, arg0, arg1, arg2, arg3, arg4, arg5)); + const int fd = + static_cast(syscall_no_intercept(SYS_creat, arg0, arg1, arg2, arg3, arg4, arg5)); + + if (fd < 0) { + return CAPIO_POSIX_SYSCALL_ERRNO; + } LOG("fd=%d", fd); @@ -61,8 +66,7 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar add_capio_fd(tid, path, fd, 0, (flags & O_CLOEXEC) == O_CLOEXEC); } - *result = fd; - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(fd, result); } #endif // SYS_creat @@ -76,7 +80,7 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg std::string path = compute_abs_path(pathname.data(), -1); - if (is_forbidden_path(pathname) || !is_capio_path(path)) { + if (!is_capio_path(pathname)) { LOG("Path %s is not a capio path: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -95,13 +99,15 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg const int fd = static_cast(syscall_no_intercept(SYS_open, arg0, arg1, arg2, arg3, arg4, arg5)); + if (fd < 0) { + return CAPIO_POSIX_SYSCALL_ERRNO; + } LOG("Adding capio path"); add_capio_fd(tid, resolved_path, fd, 0, (flags & O_CLOEXEC) == O_CLOEXEC); LOG("fd=%d", fd); - *result = fd; - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(fd, result); } #endif // SYS_open @@ -116,7 +122,7 @@ int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a mode); std::string path = compute_abs_path(pathname.data(), dirfd); - if (is_forbidden_path(pathname) || !is_capio_path(path)) { + if (!is_capio_path(pathname)) { LOG("Path %s is not a capio path: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -138,11 +144,14 @@ int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a static_cast(syscall_no_intercept(SYS_openat, arg0, arg1, arg2, arg3, arg4, arg5)); LOG("fd=%d", fd); + if (fd < 0) { + return CAPIO_POSIX_SYSCALL_ERRNO; + } + LOG("Adding resolved capio path (%s)", resolved_path.c_str()); add_capio_fd(tid, resolved_path, fd, 0, (flags & O_CLOEXEC) == O_CLOEXEC); - *result = fd; - return CAPIO_POSIX_SYSCALL_SUCCESS; + return posix_return_value(fd, result); } #endif // SYS_openat diff --git a/capio-posix/handlers/posix_readdir.hpp b/capio-posix/handlers/posix_readdir.hpp index 8620b6d63..7f3168725 100644 --- a/capio-posix/handlers/posix_readdir.hpp +++ b/capio-posix/handlers/posix_readdir.hpp @@ -179,14 +179,6 @@ inline struct dirent64 *capio_internal_readdir(DIR *dirp, long pid) { DIR *opendir(const char *name) { START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", name); - if (is_forbidden_path(name)) { - LOG("Path %s is forbidden: skip", name); - syscall_no_intercept_flag = true; - auto res = real_opendir(name); - syscall_no_intercept_flag = false; - return res; - } - auto absolute_path = capio_absolute(name); LOG("Resolved absolute path = %s", absolute_path.c_str()); diff --git a/capio-posix/handlers/read.hpp b/capio-posix/handlers/read.hpp index 65cdb2391..684d9f8da 100644 --- a/capio-posix/handlers/read.hpp +++ b/capio-posix/handlers/read.hpp @@ -19,14 +19,14 @@ inline off64_t capio_read_fs(int fd, size_t count, pid_t tid) { inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long *result) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); if (exists_capio_fd(fd)) { - auto computed_offset = get_capio_fd_offset(fd) + count; + const auto computed_offset = get_capio_fd_offset(fd) + count; LOG("Handling read on file %s up to byte %ld", get_capio_fd_path(fd).c_str(), computed_offset); - *result = read_request_cache_mem->read(fd, buffer, count); - LOG("Result of read is %lu", *result); - return CAPIO_POSIX_SYSCALL_SUCCESS; + const auto res = read_request_cache_mem->read(fd, buffer, count); + LOG("Result of read is %lu", res); + return posix_return_value(res, result); } return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } diff --git a/capio-posix/handlers/stat.hpp b/capio-posix/handlers/stat.hpp index 43264fb9e..a7f9028cb 100644 --- a/capio-posix/handlers/stat.hpp +++ b/capio-posix/handlers/stat.hpp @@ -21,7 +21,7 @@ inline int capio_fstat(int fd, struct stat *statbuf, pid_t tid) { inline int capio_lstat(const std::string_view &pathname, struct stat *statbuf, pid_t tid) { START_LOG(tid, "call(absolute_path=%s, statbuf=0x%08x)", pathname.data(), statbuf); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -36,7 +36,7 @@ inline int capio_lstat(const std::string_view &pathname, struct stat *statbuf, p inline int capio_lstat_wrapper(const std::string_view &pathname, struct stat *statbuf, pid_t tid) { START_LOG(tid, "call(path=%s, buf=0x%08x)", pathname.data(), statbuf); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } @@ -54,7 +54,7 @@ inline int capio_fstatat(int dirfd, const std::string_view &pathname, struct sta START_LOG(tid, "call(dirfd=%ld, pathname=%s, statbuf=0x%08x, flags=%X)", dirfd, pathname.data(), statbuf, flags); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } diff --git a/capio-posix/handlers/statx.hpp b/capio-posix/handlers/statx.hpp index e931ef2db..ba7d5bc2c 100644 --- a/capio-posix/handlers/statx.hpp +++ b/capio-posix/handlers/statx.hpp @@ -10,16 +10,13 @@ inline int capio_statx(int dirfd, const std::string_view &pathname, int flags, i START_LOG(tid, "call(dirfd=%d, pathname=%s, flags=%d, mask=%d, statxbuf=0x%08x)", dirfd, pathname.data(), flags, mask, statxbuf); - if (is_forbidden_path(pathname)) { + if (!is_capio_path(pathname)) { LOG("Path %s is forbidden: skip", pathname.data()); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } - std::filesystem::path path(pathname); + consent_request_cache_fs->consent_request(pathname, tid, __FUNCTION__); - if (is_capio_path(path)) { - consent_request_cache_fs->consent_request(path, tid, __FUNCTION__); - } return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } diff --git a/capio-posix/utils/cache/consent_request_cache.hpp b/capio-posix/utils/cache/consent_request_cache.hpp index 4d0f7c49e..54a8d6c83 100644 --- a/capio-posix/utils/cache/consent_request_cache.hpp +++ b/capio-posix/utils/cache/consent_request_cache.hpp @@ -34,12 +34,18 @@ class ConsentRequestCache { START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld, source=%s)", path.c_str(), tid, source_func.c_str()); + const auto resolved_path = resolve_possible_symlink(path); + + if (!is_capio_path(resolved_path)) { + LOG("PATH is forbidden. Skipping request!"); + return; + } + /** * If entry is not present in cache, then proceed to perform request. othrewise if present, * there is no need to perform request to server and can proceed */ - if (const auto resolved_path = resolve_possible_symlink(path); - available_consent->find(resolved_path) == available_consent->end()) { + if (!available_consent->contains(resolved_path)) { LOG("File not present in cache. performing request"); auto res = _consent_to_proceed_request(resolved_path, tid, source_func); LOG("Registering new file for consent to proceed");