diff --git a/capio/posix/handlers/chdir.hpp b/capio/posix/handlers/chdir.hpp index 179beb196..f8139a314 100644 --- a/capio/posix/handlers/chdir.hpp +++ b/capio/posix/handlers/chdir.hpp @@ -33,7 +33,8 @@ int chdir_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar if (is_capio_path(path)) { set_current_dir(path); - errno = 0; + errno = 0; + *result = 0; return CAPIO_POSIX_SYSCALL_SUCCESS; } diff --git a/capio/posix/handlers/rename.hpp b/capio/posix/handlers/rename.hpp index 8bdaa4941..d62fcb970 100644 --- a/capio/posix/handlers/rename.hpp +++ b/capio/posix/handlers/rename.hpp @@ -1,33 +1,45 @@ #ifndef CAPIO_POSIX_HANDLERS_RENAME_HPP #define CAPIO_POSIX_HANDLERS_RENAME_HPP -#if defined(SYS_rename) - #include "utils/filesystem.hpp" -int rename_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - const std::filesystem::path oldpath(reinterpret_cast(arg0)); - const std::filesystem::path newpath(reinterpret_cast(arg1)); - long tid = syscall_no_intercept(SYS_gettid); - START_LOG(tid, "call(oldpath=%s, newpath=%s)", oldpath.c_str(), newpath.c_str()); +int renameat2_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, + long *result) { + const auto flags = arg4; + const std::filesystem::path old_dir_fd_path = get_dir_path(static_cast(arg0)); + const std::filesystem::path old_path(reinterpret_cast(arg1)); + const std::filesystem::path new_dir_fd_path = get_dir_path(static_cast(arg2)); + const std::filesystem::path new_path(reinterpret_cast(arg3)); + const long tid = syscall_no_intercept(SYS_gettid); + + // TODO: implement handling of FLAGS + + START_LOG(tid, + "call(old_dir_fd_path=%s, old_path=%s, new_dir_fd_path=%s, newpath=%s, flags=%d)", + old_dir_fd_path.c_str(), old_path.c_str(), new_dir_fd_path.c_str(), new_path.c_str(), + flags); + + // Resolve paths relative to path of dir_fd ONLY if input path is not absolute + const auto old_path_abs = + old_path.is_absolute() ? old_path : capio_absolute(old_dir_fd_path / old_path); - auto oldpath_abs = capio_absolute(oldpath); - auto newpath_abs = capio_absolute(newpath); + const auto new_path_abs = + new_path.is_absolute() ? new_path : capio_absolute(new_dir_fd_path / new_path); - if (is_prefix(oldpath_abs, newpath_abs)) { // TODO: The check is more complex + if (is_prefix(old_path_abs, new_path_abs)) { // TODO: The check is more complex errno = EINVAL; *result = -errno; return CAPIO_POSIX_SYSCALL_SUCCESS; } - if (is_capio_path(oldpath_abs)) { - rename_capio_path(oldpath_abs, newpath_abs); - auto res = rename_request(tid, oldpath_abs, newpath_abs); + if (is_capio_path(old_path_abs)) { + rename_capio_path(old_path_abs, new_path_abs); + auto res = rename_request(tid, old_path_abs, new_path_abs); *result = (res < 0 ? -errno : res); return CAPIO_POSIX_SYSCALL_SUCCESS; } else { - if (is_capio_path(newpath_abs)) { - std::filesystem::copy(oldpath_abs, newpath_abs); + if (is_capio_path(new_path_abs)) { + std::filesystem::copy(old_path_abs, new_path_abs); *result = -errno; return CAPIO_POSIX_SYSCALL_SUCCESS; } else { @@ -36,5 +48,15 @@ int rename_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a } } -#endif // SYS_rename +int rename_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { + // Force flags to zero to ensure that spurious data is being passed to handler + return renameat2_handler(AT_FDCWD, arg0, AT_FDCWD, arg1, 0, 0, result); +} + +int renameat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, + long *result) { + // Force flags to zero to ensure that spurious data is being passed to handler + return renameat2_handler(arg0, arg1, arg2, arg3, 0, arg5, result); +} + #endif // CAPIO_POSIX_HANDLERS_RENAME_HPP diff --git a/capio/posix/libcapio_posix.cpp b/capio/posix/libcapio_posix.cpp index 9382c05a9..3aedd1a46 100644 --- a/capio/posix/libcapio_posix.cpp +++ b/capio/posix/libcapio_posix.cpp @@ -293,6 +293,12 @@ static constexpr std::array build_syscall_table( #ifdef SYS_rename _syscallTable[SYS_rename] = rename_handler; #endif +#ifdef SYS_renameat + _syscallTable[SYS_renameat] = renameat_handler; +#endif +#ifdef SYS_renameat2 + _syscallTable[SYS_renameat2] = renameat2_handler; +#endif #ifdef SYS_rmdir _syscallTable[SYS_rmdir] = rmdir_handler; #endif diff --git a/capio/posix/utils/filesystem.hpp b/capio/posix/utils/filesystem.hpp index cc6c22d09..04f13dff2 100644 --- a/capio/posix/utils/filesystem.hpp +++ b/capio/posix/utils/filesystem.hpp @@ -229,6 +229,11 @@ inline std::vector get_capio_fds() { std::filesystem::path get_dir_path(int dirfd) { START_LOG(syscall_no_intercept(SYS_gettid), "call(dirfd=%d)", dirfd); + if (dirfd == AT_FDCWD) { + LOG("Returning current CWD"); + return get_current_dir(); + } + auto it = capio_files_descriptors->find(dirfd); if (it != capio_files_descriptors->end()) { LOG("dirfd %d points to path %s", dirfd, it->second.c_str());