From 0cbaae3981cc3ed67e1f72640ee7eac1e5bc897f Mon Sep 17 00:00:00 2001 From: Marc Vef Date: Thu, 10 Mar 2022 18:43:11 +0100 Subject: [PATCH 1/2] Adding faccess2() syscall support Added in kernel 5.8 --- include/client/hooks.hpp | 10 +++++++ src/client/hooks.cpp | 34 +++++++++++++++++++++++ src/client/intercept.cpp | 8 +++++- src/client/syscalls/detail/syscall_info.c | 6 ++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index c99f60858..d3dcd0a84 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -30,8 +30,13 @@ #ifndef GEKKOFS_HOOKS_HPP #define GEKKOFS_HOOKS_HPP +extern "C" { #include #include +#include +#include +} + struct statfs; struct linux_dirent; @@ -101,6 +106,11 @@ hook_access(const char* path, int mask); int hook_faccessat(int dirfd, const char* cpath, int mode); +#ifdef SYS_faccessat2 +int +hook_faccessat2(int dirfd, const char* cpath, int mode, int flags); +#endif + off_t hook_lseek(unsigned int fd, off_t offset, unsigned int whence); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index d58302373..52734801d 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -455,6 +455,40 @@ hook_faccessat(int dirfd, const char* cpath, int mode) { } } +#ifdef SYS_faccessat2 +int +hook_faccessat2(int dirfd, const char* cpath, int mode, int flags) { + + LOG(DEBUG, + "{}() called with dirfd: '{}', path: '{}', mode: '{}', flags: '{}'", + __func__, dirfd, cpath, mode, flags); + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case gkfs::preload::RelativizeStatus::fd_unknown: + return syscall_no_intercept_wrapper(SYS_faccessat2, dirfd, cpath, + mode, flags); + + case gkfs::preload::RelativizeStatus::external: + return syscall_no_intercept_wrapper(SYS_faccessat2, dirfd, + resolved.c_str(), mode, flags); + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + // we do not use permissions and therefore do not handle `flags` for + // now + return with_errno(gkfs::syscall::gkfs_access(resolved, mode)); + + default: + LOG(ERROR, "{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} +#endif + off_t hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index a403ddd05..0016d8a1b 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -622,7 +622,13 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, static_cast(arg0), reinterpret_cast(arg1), static_cast(arg2)); break; - +#ifdef SYS_faccessat2 + case SYS_faccessat2: + *result = gkfs::hook::hook_faccessat2( + static_cast(arg0), reinterpret_cast(arg1), + static_cast(arg2), static_cast(arg3)); + break; +#endif case SYS_lseek: *result = gkfs::hook::hook_lseek(static_cast(arg0), static_cast(arg1), diff --git a/src/client/syscalls/detail/syscall_info.c b/src/client/syscalls/detail/syscall_info.c index 29ff2c3d6..a74666da8 100644 --- a/src/client/syscalls/detail/syscall_info.c +++ b/src/client/syscalls/detail/syscall_info.c @@ -382,6 +382,9 @@ const struct syscall_info syscall_table[] = { SYSCALL(readlinkat, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(ptr, "buf"), S_NARG(arg, "bufsiz")), SYSCALL(fchmodat, 3, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "filename"), S_NARG(octal_mode, "mode")), SYSCALL(faccessat, 3, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode")), +#ifdef SYS_faccessat2 + SYSCALL(faccessat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode"), S_NARG(arg, "flags")), +#endif SYSCALL(pselect6, 6, S_RET(rdec), S_NARG(dec, "nfds"), S_NARG(ptr, "readfds"), S_NARG(ptr, "writefds"), S_NARG(ptr, "exceptfds"), S_NARG(ptr, "timeval"), S_NARG(ptr, "sigmask")), SYSCALL(ppoll, 5, S_RET(rdec), S_NARG(ptr, "fds"), S_NARG(dec, "nfds"), S_NARG(ptr, "tmo_p"), S_NARG(ptr, "sigmask"), S_NARG(dec, "sigsetsize")), SYSCALL(unshare, 1, S_RET(rdec), S_NARG(arg, "unshare_flags")), @@ -658,6 +661,9 @@ const struct named_syscall_entry syscalls_by_name[] = { SYSCALL_BY_NAME(exit), SYSCALL_BY_NAME(exit_group), SYSCALL_BY_NAME(faccessat), +#ifdef SYS_faccessat2 + SYSCALL_BY_NAME(faccessat2), +#endif SYSCALL_BY_NAME(fadvise64), SYSCALL_BY_NAME(fallocate), SYSCALL_BY_NAME(fanotify_init), -- GitLab From 68be5b2d383e3538378dab83f9a5711df1328a64 Mon Sep 17 00:00:00 2001 From: Marc Vef Date: Thu, 10 Mar 2022 17:14:01 +0100 Subject: [PATCH 2/2] Adding getxattr() syscall support --- include/client/hooks.hpp | 3 +++ src/client/hooks.cpp | 14 +++++++++++++- src/client/intercept.cpp | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index d3dcd0a84..9e16287df 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -173,6 +173,9 @@ hook_fstatfs(unsigned int fd, struct statfs* buf); int hook_fsync(unsigned int fd); +int +hook_getxattr(const char* path, const char* name, void* value, size_t size); + } // namespace gkfs::hook #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 52734801d..037d6c8ee 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -182,7 +182,6 @@ hook_lstat(const char* path, struct stat* buf) { return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf)); } return syscall_no_intercept_wrapper(SYS_lstat, rel_path.c_str(), buf); - ; } int @@ -955,4 +954,17 @@ hook_fsync(unsigned int fd) { return syscall_no_intercept_wrapper(SYS_fsync, fd); } +int +hook_getxattr(const char* path, const char* name, void* value, size_t size) { + + LOG(DEBUG, "{}() called with path '{}' name '{}' value '{}' size '{}'", + __func__, path, name, fmt::ptr(value), size); + + std::string rel_path; + if(CTX->relativize_path(path, rel_path)) { + return -ENOTSUP; + } + return syscall_no_intercept_wrapper(SYS_getxattr, path, name, value, size); +} + } // namespace gkfs::hook diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 0016d8a1b..57c587343 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -774,6 +774,13 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, *result = gkfs::hook::hook_fsync(static_cast(arg0)); break; + case SYS_getxattr: + *result = gkfs::hook::hook_getxattr( + reinterpret_cast(arg0), + reinterpret_cast(arg1), + reinterpret_cast(arg2), static_cast(arg4)); + break; + default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in -- GitLab