From 4852749dd3d5853cab6c69ff2cc2ad863c5aa38c Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 25 Sep 2024 11:58:27 +0200 Subject: [PATCH 01/32] Add: new Syscalls, syscall number on syscalls, removes O_PATH on gkfs_open, add close_range support --- include/client/syscalls/decoder.hpp | 2 +- src/client/gkfs_functions.cpp | 11 +-- src/client/intercept.cpp | 28 ++++++ src/client/preload_context.cpp | 2 +- src/client/syscalls/detail/syscall_info.c | 111 +++++++++++++++++++++- 5 files changed, 140 insertions(+), 14 deletions(-) diff --git a/include/client/syscalls/decoder.hpp b/include/client/syscalls/decoder.hpp index 3172cc2df..dc3dd94d7 100644 --- a/include/client/syscalls/decoder.hpp +++ b/include/client/syscalls/decoder.hpp @@ -60,7 +60,7 @@ decode(FmtBuffer& buffer, const long syscall_number, const auto sc = lookup_by_number(syscall_number, argv); - fmt::format_to(std::back_inserter(buffer), "{}(", sc.name()); + fmt::format_to(std::back_inserter(buffer), "{} {}(", sc.name(), syscall_number); for(int i = 0; i < sc.num_args(); ++i) { const auto arg = sc.args().at(i); diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index 17dd46480..f755f0cb0 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -139,13 +139,7 @@ namespace gkfs::syscall { */ int gkfs_open(const std::string& path, mode_t mode, int flags) { - - if(flags & O_PATH) { - LOG(ERROR, "`O_PATH` flag is not supported"); - errno = ENOTSUP; - return -1; - } - + // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { @@ -1643,7 +1637,8 @@ gkfs_close(unsigned int fd) { if(CTX->is_internal_fd(fd)) { // the client application (for some reason) is trying to close an // internal fd: ignore it - return 0; + return -1; + // Maybe we should return -1? } return -1; diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 1086010e8..94f7b6be3 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -409,6 +409,22 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, } break; + case SYS_close_range: + *result = syscall_no_intercept_wrapper( + syscall_number, static_cast(arg0), + static_cast(arg1), static_cast(arg2)); + if(*result >= 0) { + for(auto i = arg0; i < arg1; i++) { + if(arg1 == 2147483647) { + if(i >= GKFS_MAX_INTERNAL_FDS) + break; + } + + CTX->unregister_internal_fd(i); + } + } + break; + default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in @@ -486,6 +502,18 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, case SYS_close: *result = gkfs::hook::hook_close(static_cast(arg0)); break; + case SYS_close_range: + for(auto i = arg0; i <= arg1; i++) { + if ( i >= GKFS_MAX_OPEN_FDS) break; + *result = gkfs::hook::hook_close(i); + + if(*result == -1) { + *result = 0; + break; + }; + } + *result = 0; + break; #ifdef SYS_stat case SYS_stat: *result = diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index ff3851492..909fde2c2 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -541,7 +541,7 @@ PreloadContext::register_internal_fd(int fd) { void PreloadContext::unregister_internal_fd(int fd) { - LOG(DEBUG, "unregistering internal fd {}", fd); + LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, fd >= MIN_INTERNAL_FD); assert(fd >= MIN_INTERNAL_FD); diff --git a/src/client/syscalls/detail/syscall_info.c b/src/client/syscalls/detail/syscall_info.c index 8c6ca4fee..954486f54 100644 --- a/src/client/syscalls/detail/syscall_info.c +++ b/src/client/syscalls/detail/syscall_info.c @@ -478,9 +478,6 @@ SYSCALL(getpmsg, 5, S_RET(rdec), S_NARG(arg, "arg0"), 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")), @@ -596,8 +593,108 @@ SYSCALL(getpmsg, 5, S_RET(rdec), S_NARG(arg, "arg0"), #endif // SYS_io_pgetevents #ifdef SYS_rseq - SYSCALL(rseq, 4, S_RET(rdec), S_NARG(ptr, "rseq"), S_NARG(dec, "rseq_len"), S_NARG(arg, "flags"), S_NARG(signum, "sig")) + SYSCALL(rseq, 4, S_RET(rdec), S_NARG(ptr, "rseq"), S_NARG(dec, "rseq_len"), S_NARG(arg, "flags"), S_NARG(signum, "sig")), #endif // SYS_rseq +// ifdef the next syscalls +#ifdef SYS_pidfd_send_signal + SYSCALL(pidfd_send_signal, 3, S_RET(rdec), S_NARG(dec, "pidfd"), S_NARG(signum, "sig"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_io_uring_setup + SYSCALL(io_uring_setup, 2, S_RET(rdec), S_NARG(arg, "entries"), S_NARG(ptr, "ring_addr")), +#endif +#ifdef SYS_io_uring_enter + SYSCALL(io_uring_enter, 4, S_RET(rdec), S_NARG(arg, "ring_fd"), S_NARG(dec, "to_submit"), S_NARG(dec, "min_complete"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_io_uring_register + SYSCALL(io_uring_register, 4, S_RET(rdec), S_NARG(arg, "ring_fd"), S_NARG(arg, "opcode"), S_NARG(ptr, "arg"), S_NARG(arg, "nr_args")), +#endif +#ifdef SYS_open_tree + SYSCALL(open_tree, 2, S_RET(rdec), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags")), +#endif +#ifdef SYS_move_mount + SYSCALL(move_mount, 3, S_RET(rdec), S_NARG(cstr, "src"), S_NARG(cstr, "dst"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_fsopen + SYSCALL(fsopen, 3, S_RET(rdec), S_NARG(cstr, "fs_type"), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags")), +#endif +#ifdef SYS_fsconfig + SYSCALL(fsconfig, 3, S_RET(rdec), S_NARG(arg, "cmd"), S_NARG(ptr, "argp"), S_NARG(ptr, "resp")), +#endif +#ifdef SYS_fsmount + SYSCALL(fsmount, 5, S_RET(rdec), S_NARG(cstr, "fs_type"), S_NARG(cstr, "pathname"), S_NARG(cstr, "type"), S_NARG(arg, "flags"), S_NARG(ptr, "data")), +#endif +#ifdef SYS_fspick + SYSCALL(fspick, 4, S_RET(rdec), S_NARG(arg, "arg0"), S_NARG(arg, "arg1"), S_NARG(arg, "arg2"), S_NARG(arg, "arg3")), +#endif +#ifdef SYS_pidfd_open + SYSCALL(pidfd_open, 2, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_clone3 + SYSCALL(clone3, 4, S_RET(rdec), S_NARG(arg, "flags"), S_NARG(ptr, "child_tid"), S_NARG(ptr, "parent_tid"), S_NARG(ptr, "tls")), +#endif +#ifdef SYS_close_range + SYSCALL(close_range, 3, S_RET(rdec), S_NARG(dec, "low"), S_NARG(dec, "high"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_openat2 + SYSCALL(openat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags"), S_NARG(ptr, "how")), +#endif +#ifdef SYS_pidfd_getfd + SYSCALL(pidfd_getfd, 3, S_RET(rdec), S_NARG(dec, "pidfd"), S_NARG(arg, "fd"), S_NARG(arg, "flags")), +#endif +#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 +#ifdef SYS_process_madvise + SYSCALL(process_madvise, 4, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(ptr, "addr"), S_NARG(dec, "length"), S_NARG(arg, "advice")), +#endif +#ifdef SYS_epoll_pwait2 + SYSCALL(epoll_pwait2, 6, S_RET(rdec), S_NARG(fd, "epfd"), S_NARG(ptr, "events"), S_NARG(dec, "maxevents"), S_NARG(dec, "timeout"), S_NARG(ptr, "sigmask"), S_NARG(dec, "sigsetsize")), +#endif +#ifdef SYS_mount_setattr + SYSCALL(mount_setattr, 3, S_RET(rdec), S_NARG(cstr, "path"), S_NARG(ptr, "attr"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_quotactl_fd + SYSCALL(quotactl_fd, 4, S_RET(rdec), S_NARG(arg, "cmd"), S_NARG(fd, "fd"), S_NARG(arg, "id"), S_NARG(ptr, "addr")), +#endif +#ifdef SYS_landlock_create_ruleset + SYSCALL(landlock_create_ruleset, 1, S_RET(rdec), S_NARG(arg, "flags")), +#endif +#ifdef SYS_landlock_add_rule + SYSCALL(landlock_add_rule, 3, S_RET(rdec), S_NARG(dec, "ruleset"), S_NARG(arg, "rule"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_landlock_restrict_self + SYSCALL(landlock_restrict_self, 1, S_RET(rdec), S_NARG(dec, "ruleset")), +#endif +#ifdef SYS_memfd_secret + SYSCALL(memfd_secret, 3, S_RET(rdec), S_NARG(cstr, "name"), S_NARG(arg, "flags"), S_NARG(ptr, "secret")), +#endif +#ifdef SYS_process_mrelease + SYSCALL(process_mrelease, 2, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(ptr, "addr")), +#endif +#ifdef SYS_futex_waitv + SYSCALL(futex_waitv, 5, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout"), S_NARG(dec, "flags")), +#endif +#ifdef SYS_set_mempolicy_home_node + SYSCALL(set_mempolicy_home_node, 1, S_RET(rdec), S_NARG(arg, "node")), +#endif +#ifdef SYS_cachestat + SYSCALL(cachestat, 1, S_RET(rdec), S_NARG(ptr, "cs")), +#endif +#ifdef SYS_fchmodat2 + SYSCALL(fchmodat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_map_shadow_stack + SYSCALL(map_shadow_stack, 1, S_RET(rdec), S_NARG(arg, "flags")), +#endif +#ifdef SYS_futex_wake + SYSCALL(futex_wake, 3, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(dec, "nr_wake"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_futex_wait + SYSCALL(futex_wait, 4, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout")), +#endif +#ifdef SYS_futex_requeue + SYSCALL(futex_requeue, 5, S_RET(rdec), S_NARG(ptr, "uaddr1"), S_NARG(ptr, "uaddr2"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout")) +#endif }; static const struct syscall_info unknown_syscall = { @@ -742,7 +839,13 @@ const struct named_syscall_entry syscalls_by_name[] = { SYSCALL_BY_NAME(clock_nanosleep), SYSCALL_BY_NAME(clock_settime), SYSCALL_BY_NAME(clone), +#ifdef SYS_clone3 + SYSCALL_BY_NAME(clone3), +#endif SYSCALL_BY_NAME(close), +#ifdef SYS_close_range + SYSCALL_BY_NAME(close_range), +#endif SYSCALL_BY_NAME(connect), #ifdef SYS_copy_file_range SYSCALL_BY_NAME(copy_file_range), -- GitLab From b8f1db88c6c53c00a082c1cf747636049a14c93e Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 25 Sep 2024 12:02:45 +0200 Subject: [PATCH 02/32] Fix lint --- include/client/syscalls/decoder.hpp | 3 ++- src/client/gkfs_functions.cpp | 2 +- src/client/intercept.cpp | 21 +++++++++++---------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/client/syscalls/decoder.hpp b/include/client/syscalls/decoder.hpp index dc3dd94d7..04d4ecb1b 100644 --- a/include/client/syscalls/decoder.hpp +++ b/include/client/syscalls/decoder.hpp @@ -60,7 +60,8 @@ decode(FmtBuffer& buffer, const long syscall_number, const auto sc = lookup_by_number(syscall_number, argv); - fmt::format_to(std::back_inserter(buffer), "{} {}(", sc.name(), syscall_number); + fmt::format_to(std::back_inserter(buffer), "{} {}(", sc.name(), + syscall_number); for(int i = 0; i < sc.num_args(); ++i) { const auto arg = sc.args().at(i); diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index f755f0cb0..438afbe69 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -139,7 +139,7 @@ namespace gkfs::syscall { */ int gkfs_open(const std::string& path, mode_t mode, int flags) { - + // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 94f7b6be3..f3e81075f 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -503,16 +503,17 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, *result = gkfs::hook::hook_close(static_cast(arg0)); break; case SYS_close_range: - for(auto i = arg0; i <= arg1; i++) { - if ( i >= GKFS_MAX_OPEN_FDS) break; - *result = gkfs::hook::hook_close(i); - - if(*result == -1) { - *result = 0; - break; - }; - } - *result = 0; + for(auto i = arg0; i <= arg1; i++) { + if(i >= GKFS_MAX_OPEN_FDS) + break; + *result = gkfs::hook::hook_close(i); + + if(*result == -1) { + *result = 0; + break; + }; + } + *result = 0; break; #ifdef SYS_stat case SYS_stat: -- GitLab From 627f5ec639e4c5cde03fd0db7906eeb53feeda0a Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 25 Sep 2024 12:15:53 +0200 Subject: [PATCH 03/32] IFDEF close_range (only appears on newer kernels) --- src/client/intercept.cpp | 6 ++++-- src/client/preload_context.cpp | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index f3e81075f..e33d3d578 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -408,7 +408,7 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, CTX->unregister_internal_fd(arg0); } break; - +#ifdef SYS_close_range case SYS_close_range: *result = syscall_no_intercept_wrapper( syscall_number, static_cast(arg0), @@ -424,7 +424,7 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, } } break; - +#endif default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in @@ -502,6 +502,7 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, case SYS_close: *result = gkfs::hook::hook_close(static_cast(arg0)); break; +#ifdef SYS_close_range case SYS_close_range: for(auto i = arg0; i <= arg1; i++) { if(i >= GKFS_MAX_OPEN_FDS) @@ -515,6 +516,7 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, } *result = 0; break; +#endif SYS_close_range #ifdef SYS_stat case SYS_stat: *result = diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index 909fde2c2..a15813b25 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -541,7 +541,8 @@ PreloadContext::register_internal_fd(int fd) { void PreloadContext::unregister_internal_fd(int fd) { - LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, fd >= MIN_INTERNAL_FD); + LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, + fd >= MIN_INTERNAL_FD); assert(fd >= MIN_INTERNAL_FD); -- GitLab From 4da21ea0c9f942e50632e9b9590e1c270cd43c30 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 25 Sep 2024 12:48:09 +0200 Subject: [PATCH 04/32] Removed O_PATH error test --- src/client/intercept.cpp | 2 +- tests/integration/syscalls/test_error_operations.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index e33d3d578..b1c50006e 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -516,7 +516,7 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, } *result = 0; break; -#endif SYS_close_range +#endif // SYS_close_range #ifdef SYS_stat case SYS_stat: *result = diff --git a/tests/integration/syscalls/test_error_operations.py b/tests/integration/syscalls/test_error_operations.py index 97ae68889..f8c3285cb 100644 --- a/tests/integration/syscalls/test_error_operations.py +++ b/tests/integration/syscalls/test_error_operations.py @@ -46,8 +46,8 @@ def test_open_error(gkfs_daemon, gkfs_client): file = gkfs_daemon.mountdir / "file" file2 = gkfs_daemon.mountdir / "file2" file3 = gkfs_daemon.mountdir / "file3" - - flags = [os.O_PATH, os.O_CREAT | os.O_DIRECTORY] + # O_PATH is now supported as cp uses it.. + flags = [os.O_CREAT | os.O_DIRECTORY] # create a file in gekkofs for flag in flags: -- GitLab From 15a222fbdbd64aebf0846f0056698b807a5fe293 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 15:12:05 +0200 Subject: [PATCH 05/32] Better behaviour in app close_range --- src/client/intercept.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index b1c50006e..e70d61aac 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include @@ -507,12 +507,10 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, for(auto i = arg0; i <= arg1; i++) { if(i >= GKFS_MAX_OPEN_FDS) break; - *result = gkfs::hook::hook_close(i); - - if(*result == -1) { + if(CTX->file_map()->exist(i)) { + gkfs::syscall::gkfs_close(i); + } *result = 0; - break; - }; } *result = 0; break; -- GitLab From 824eaf128b2e04c997c1a0e9b67179d40b0c7390 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 24 Jul 2024 12:56:25 +0200 Subject: [PATCH 06/32] Trying fd workaround --- include/client/preload_context.hpp | 5 +++++ src/client/open_file_map.cpp | 10 +++++++++- src/client/preload.cpp | 7 +++++-- src/client/preload_context.cpp | 12 +++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index d818ca21e..3d2a16976 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -128,6 +128,7 @@ private: std::bitset protected_fds_; std::string hostname; int replicas_; + bool protect_fds_{false}; std::shared_ptr write_metrics_; std::shared_ptr read_metrics_; @@ -301,6 +302,10 @@ public: int get_replicas(); + bool protect_fds() const; + + void protect_fds(bool protect); + const std::shared_ptr write_metrics(); diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 60f0c4781..059c82d48 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -132,7 +132,9 @@ OpenFileMap::exist(const int fd) { int OpenFileMap::safe_generate_fd_idx_() { - auto fd = generate_fd_idx(); + int fd = 0; + if (CTX->protect_fds()) { + fd = generate_fd_idx(); /* * Check if fd is still in use and generate another if yes * Note that this can only happen once the all fd indices within the int has @@ -149,6 +151,12 @@ OpenFileMap::safe_generate_fd_idx_() { fd = generate_fd_idx(); } } + } + else { + fd = syscall_no_intercept( + SYS_open, "/dev/null", + O_RDWR, S_IRUSR | S_IWUSR); + } return fd; } diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 67926fbb3..31ef3cee7 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -364,7 +364,9 @@ init_preload() { // To prevent this for our internal // initialization code, we forcefully occupy the user fd range to force // such modules to create fds in our private range. - CTX->protect_user_fds(); + if (CTX->protect_fds()) { + CTX->protect_user_fds(); + } log_prog_name(); gkfs::path::init_cwd(); @@ -374,7 +376,8 @@ init_preload() { gkfs::preload::init_environment(); CTX->enable_interception(); - CTX->unprotect_user_fds(); + if(CTX->protect_fds()) + CTX->unprotect_user_fds(); auto forwarding_map_file = gkfs::env::get_var( gkfs::env::FORWARDING_MAP_FILE, gkfs::config::forwarding_file_path); diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index a15813b25..4b028d676 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -469,11 +469,19 @@ PreloadContext::interception_enabled() const { return interception_enabled_; } +bool PreloadContext::protect_fds() const { + return protect_fds_; +}; + +void PreloadContext::protect_fds(bool protect) { + protect_fds_ = protect; +} + int PreloadContext::register_internal_fd(int fd) { assert(fd >= 0); - + if (!protect_fds()) return fd; if(!internal_fds_must_relocate_) { LOG(DEBUG, "registering fd {} as internal (no relocation needed)", fd); assert(fd >= MIN_INTERNAL_FD); @@ -541,6 +549,8 @@ PreloadContext::register_internal_fd(int fd) { void PreloadContext::unregister_internal_fd(int fd) { + if (!protect_fds()) return; + LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, fd >= MIN_INTERNAL_FD); -- GitLab From b0bb6e91d4c326e0d96442aa00a5f4667fb6071d Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 8 Aug 2024 11:46:13 +0200 Subject: [PATCH 07/32] libc example --- include/client/gkfs_libc.hpp | 142 ++++++++++++++++++++++++++++++++ src/client/CMakeLists.txt | 32 ++++++++ src/client/gkfs_libc.cpp | 155 +++++++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+) create mode 100644 include/client/gkfs_libc.hpp create mode 100644 src/client/gkfs_libc.cpp diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp new file mode 100644 index 000000000..8f8c3c80b --- /dev/null +++ b/include/client/gkfs_libc.hpp @@ -0,0 +1,142 @@ + /* + * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra + * + * This file is part of Expand. + * + * Expand is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Expand is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Expand. If not, see . + * + */ + + + #ifdef __cplusplus + extern "C" { + #endif + + + /* ... Include / Inclusion ........................................... */ + + #include + #include + #include + #include + + /* ... Const / Const ................................................. */ + + + /* ... Data structures / Estructuras de datos ........................ */ + + + /* ... Functions / Funciones ......................................... */ + + // File API + int dlsym_open (char *path, int flags); + int dlsym_open2 (char *path, int flags, mode_t mode); + int dlsym_open64 (char *path, int flags, mode_t mode); + int dlsym_openat (int fd, const char *pathname, int flags, mode_t mode); + int dlsym___open_2 (char *path, int flags); + int dlsym_close (int fd); + + int dlsym_creat (const char *path, mode_t mode); + int dlsym_ftruncate (int fd, off_t length); + int dlsym_mkstemp (char *templates); + + ssize_t dlsym_read (int fd, void *buf, size_t nbyte); + ssize_t dlsym_write (int fd, void *buf, size_t nbyte); + + ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset); + ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset); + ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset); + ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset); + + off_t dlsym_lseek (int fd, off_t offset, int whence); + off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); + + int dlsym_fstat (int ver, int fd, struct stat *buf); + int dlsym_fxstat64 (int ver, int fd, struct stat64 *buf); + int dlsym_stat (int ver, const char *path, struct stat *buf); + int dlsym_lstat (int ver, const char *path, struct stat *buf); + int dlsym_lxstat64 (int ver, const char *path, struct stat64 *buf); + int dlsym_xstat64 (int ver, const char *path, struct stat64 *buf); + int dlsym_fstatat (int dfd, const char *path, struct stat *buf, int flags); + int dlsym_fstatat64 (int dfd, const char *path, struct stat64 *buf, int flags); + + int dlsym_rename (const char *old_path, const char *new_path); + int dlsym_unlink (char *path); + int dlsym_remove (char *path); + + + // File API (stdio) + FILE* dlsym_fopen (const char *filename, const char *mode); + FILE* dlsym_fdopen (int fd, const char *mode); + int dlsym_fclose (FILE *stream); + + size_t dlsym_fread (void *ptr, size_t size, size_t nmemb, FILE *stream); + size_t dlsym_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream); + + int dlsym_fseek (FILE *stream, long int offset, int whence); + long dlsym_ftell (FILE *stream); + void dlsym_rewind (FILE *stream); + int dlsym_feof (FILE *stream); + + + // Directory API + DIR* dlsym_opendir (char *dirname); + DIR* dlsym_opendir64 (char *dirname); + int dlsym_closedir (DIR* dirp); + + long dlsym_telldir (DIR *dirp); + void dlsym_seekdir (DIR *dirp, long loc); + + struct dirent * dlsym_readdir (DIR *dirp); + struct dirent64 * dlsym_readdir64 (DIR *dirp); + + int dlsym_mkdir (char *path, mode_t mode); + int dlsym_rmdir (char *path); + + + // Proccess API + int dlsym_fork (void); + + int dlsym_pipe (int pipefd[2]); + + int dlsym_dup (int fd); + int dlsym_dup2 (int fd, int fd2); + + void dlsym_exit (int status); + + + // Manager API + int dlsym_chdir (char * path); + int dlsym_chmod ( char *path, mode_t mode); + int dlsym_fchmod (int fd, mode_t mode); + int dlsym_chown (char *path, uid_t owner, gid_t group); + int dlsym_fcntl (int fd, int cmd, long arg); + int dlsym_access (const char *path, int mode); + int dlsym_fsync (int fd); + int dlsym_flock (int fd, int operation); + + + // Memory API + void *dlsym_mmap (void *addr, size_t length, int prot, int flags, int fd, off_t offset); +int open64 ( const char *path, int flags, ... ); +int open ( const char *path, int flags, ... ); + + + /* ................................................................... */ + + #ifdef __cplusplus + } + #endif + + diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index c31abeedc..3645e392c 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(gkfs_intercept SHARED) add_library(gkfs_user_lib SHARED) +add_library(gkfs_libc_intercept SHARED) target_sources(gkfs_intercept @@ -80,6 +81,13 @@ target_sources( syscalls/detail/syscall_info.c syscalls/util.S ) +target_sources( + gkfs_libc_intercept + PRIVATE + gkfs_libc.cpp + +) + target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL) target_link_options(gkfs_user_lib PRIVATE -z noexecstack) @@ -120,6 +128,17 @@ target_link_libraries( Microsoft.GSL::GSL ) +target_link_libraries( + gkfs_libc_intercept + PRIVATE metadata distributor env_util arithmetic path_util rpc_utils + PUBLIC dl + Mercury::Mercury + hermes + fmt::fmt + Threads::Threads +) + + install( TARGETS gkfs_intercept LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -141,3 +160,16 @@ install( ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gkfs ) + +set_target_properties(gkfs_libc_intercept + PROPERTIES + PUBLIC_HEADER "../../include/client/void_syscall_intercept.hpp" + PUBLIC_HEADER "../../include/client/user_functions.hpp" +) + +install( + TARGETS gkfs_libc_intercept + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gkfs +) \ No newline at end of file diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp new file mode 100644 index 000000000..7f7b1527d --- /dev/null +++ b/src/client/gkfs_libc.cpp @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include + +#define debug_info printf + +int (*real_open )(char *, int, mode_t) = NULL; +int (*real_open64 )(char *, int, mode_t) = NULL; +int (*real___open_2)(char *, int) = NULL; +int (*real_openat )(int, char *, int, mode_t) = NULL; + +// File API +int dlsym_open (char *path, int flags) +{ + debug_info("[SYSCALL_PROXIES] [dlsym_open] >> Begin\n"); + + if (real_open == NULL) { + real_open = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char *)path, flags, 0); + + debug_info("[SYSCALL_PROXIES] [dlsym_open] >> End\n"); + + return fd; +} + +int dlsym_open2 (char *path, int flags, mode_t mode) +{ + debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> Begin\n"); + + if (real_open == NULL) { + real_open = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char *)path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> End\n"); + + return fd; +} + +int dlsym_openat (int fd,char *path, int flags, mode_t mode) +{ + debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> Begin\n"); +std::cout << "XXX" << std::endl; + if (real_openat == NULL) { + real_openat = (int (*)(int,char *, int, mode_t)) dlsym(RTLD_NEXT, "openat"); + } + + int fd2 = real_openat(fd,(char *)path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> End\n"); + + return fd2; +} + +int dlsym_open64 (char *path, int flags, mode_t mode) +{ + debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> Begin\n"); + + if (real_open64 == NULL){ + real_open64 = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open64"); + } + + int fd = real_open64((char *)path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> End\n"); + + return fd; +} + +int dlsym___open_2 (char *path, int flags) +{ + debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> Begin\n"); + + if (real___open_2 == NULL) { + real___open_2 = (int (*)(char *, int)) dlsym(RTLD_NEXT, "__open"); + } + + int fd = real___open_2((char *)path, flags); + + debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> End\n"); + + return fd; +} + +// File API +int open ( const char *path, int flags, ... ) +{ + int ret, fd; + va_list ap; + mode_t mode = 0; + + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + + debug_info("[BYPASS] >> Begin open....\n"); + debug_info("[BYPASS] 1) Path => %s\n", path); + debug_info("[BYPASS] 2) Flags => %d\n", flags); + debug_info("[BYPASS] 3) Mode => %d\n", mode); + + + debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); + + ret = dlsym_open2((char *)path, flags, mode); + + debug_info("[BYPASS]\t dlsym_open (%s,%o,%o) -> %d\n", path, flags, mode, ret); + + + va_end(ap); + + debug_info("[BYPASS] << After open....\n"); + + return ret; +} + + +int open64 ( const char *path, int flags, ... ) +{ + int fd, ret; + va_list ap; + mode_t mode = 0; + + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + + debug_info("[BYPASS] >> Begin open64....\n"); + debug_info("[BYPASS] 1) Path => %s\n", path); + debug_info("[BYPASS] 2) flags => %d\n", flags); + debug_info("[BYPASS] 3) mode => %d\n", mode); + + + debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o)\n", path, flags, mode); + + ret = dlsym_open64((char *)path, flags, mode); + + debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o) -> %d\n", path, flags, mode, ret); + + + va_end(ap); + + debug_info("[BYPASS] << After open64....\n"); + + return ret; +} + +// Generate the rest of the functions to build a libc io interception + + + -- GitLab From 6f5ab44e60752ae4e60f81249cc025c1c4420527 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Fri, 16 Aug 2024 13:31:49 +0200 Subject: [PATCH 08/32] more functions --- include/client/gkfs_libc.hpp | 322 ++++++++++++++++++++------------- src/client/gkfs_libc.cpp | 339 +++++++++++++++++++++++++---------- 2 files changed, 447 insertions(+), 214 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 8f8c3c80b..f644ee621 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -1,5 +1,6 @@ - /* - * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra +/* + * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, + * Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra * * This file is part of Expand. * @@ -18,125 +19,200 @@ * */ - - #ifdef __cplusplus - extern "C" { - #endif - - - /* ... Include / Inclusion ........................................... */ - - #include - #include - #include - #include - - /* ... Const / Const ................................................. */ - - - /* ... Data structures / Estructuras de datos ........................ */ - - - /* ... Functions / Funciones ......................................... */ - - // File API - int dlsym_open (char *path, int flags); - int dlsym_open2 (char *path, int flags, mode_t mode); - int dlsym_open64 (char *path, int flags, mode_t mode); - int dlsym_openat (int fd, const char *pathname, int flags, mode_t mode); - int dlsym___open_2 (char *path, int flags); - int dlsym_close (int fd); - - int dlsym_creat (const char *path, mode_t mode); - int dlsym_ftruncate (int fd, off_t length); - int dlsym_mkstemp (char *templates); - - ssize_t dlsym_read (int fd, void *buf, size_t nbyte); - ssize_t dlsym_write (int fd, void *buf, size_t nbyte); - - ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset); - ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset); - ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset); - ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset); - - off_t dlsym_lseek (int fd, off_t offset, int whence); - off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); - - int dlsym_fstat (int ver, int fd, struct stat *buf); - int dlsym_fxstat64 (int ver, int fd, struct stat64 *buf); - int dlsym_stat (int ver, const char *path, struct stat *buf); - int dlsym_lstat (int ver, const char *path, struct stat *buf); - int dlsym_lxstat64 (int ver, const char *path, struct stat64 *buf); - int dlsym_xstat64 (int ver, const char *path, struct stat64 *buf); - int dlsym_fstatat (int dfd, const char *path, struct stat *buf, int flags); - int dlsym_fstatat64 (int dfd, const char *path, struct stat64 *buf, int flags); - - int dlsym_rename (const char *old_path, const char *new_path); - int dlsym_unlink (char *path); - int dlsym_remove (char *path); - - - // File API (stdio) - FILE* dlsym_fopen (const char *filename, const char *mode); - FILE* dlsym_fdopen (int fd, const char *mode); - int dlsym_fclose (FILE *stream); - - size_t dlsym_fread (void *ptr, size_t size, size_t nmemb, FILE *stream); - size_t dlsym_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream); - - int dlsym_fseek (FILE *stream, long int offset, int whence); - long dlsym_ftell (FILE *stream); - void dlsym_rewind (FILE *stream); - int dlsym_feof (FILE *stream); - - - // Directory API - DIR* dlsym_opendir (char *dirname); - DIR* dlsym_opendir64 (char *dirname); - int dlsym_closedir (DIR* dirp); - - long dlsym_telldir (DIR *dirp); - void dlsym_seekdir (DIR *dirp, long loc); - - struct dirent * dlsym_readdir (DIR *dirp); - struct dirent64 * dlsym_readdir64 (DIR *dirp); - - int dlsym_mkdir (char *path, mode_t mode); - int dlsym_rmdir (char *path); - - - // Proccess API - int dlsym_fork (void); - - int dlsym_pipe (int pipefd[2]); - - int dlsym_dup (int fd); - int dlsym_dup2 (int fd, int fd2); - - void dlsym_exit (int status); - - - // Manager API - int dlsym_chdir (char * path); - int dlsym_chmod ( char *path, mode_t mode); - int dlsym_fchmod (int fd, mode_t mode); - int dlsym_chown (char *path, uid_t owner, gid_t group); - int dlsym_fcntl (int fd, int cmd, long arg); - int dlsym_access (const char *path, int mode); - int dlsym_fsync (int fd); - int dlsym_flock (int fd, int operation); - - - // Memory API - void *dlsym_mmap (void *addr, size_t length, int prot, int flags, int fd, off_t offset); -int open64 ( const char *path, int flags, ... ); -int open ( const char *path, int flags, ... ); - - - /* ................................................................... */ - - #ifdef __cplusplus - } - #endif - +#ifdef __cplusplus +extern "C" { +#endif + + +/* ... Include / Inclusion ........................................... */ + +#include +#include +#include +#include + +/* ... Const / Const ................................................. */ + + +/* ... Data structures / Estructuras de datos ........................ */ + + +/* ... Functions / Funciones ......................................... */ + +// File API +int +dlsym_open(char* path, int flags); +int +dlsym_open2(char* path, int flags, mode_t mode); +int +dlsym_open64(char* path, int flags, mode_t mode); +int +dlsym_openat(int fd, const char* pathname, int flags, mode_t mode); +int +dlsym___open_2(char* path, int flags); +int +dlsym_close(int fd); + +int +dlsym_creat(const char* path, mode_t mode); +int +dlsym_ftruncate(int fd, off_t length); +int +dlsym_mkstemp(char* templates); + +ssize_t +dlsym_read(int fd, void* buf, size_t nbyte); +ssize_t +dlsym_write(int fd, void* buf, size_t nbyte); + +ssize_t +dlsym_pread(int fd, void* buf, size_t count, off_t offset); +ssize_t +dlsym_pwrite(int fd, const void* buf, size_t count, off_t offset); +ssize_t +dlsym_pread64(int fd, void* buf, size_t count, off_t offset); +ssize_t +dlsym_pwrite64(int fd, const void* buf, size_t count, off_t offset); + +off_t +dlsym_lseek(int fd, off_t offset, int whence); +off64_t +dlsym_lseek64(int fd, off64_t offset, int whence); + +int +dlsym_fstat(int ver, int fd, struct stat* buf); +int +dlsym_fxstat64(int ver, int fd, struct stat64* buf); +int +dlsym_stat(int ver, const char* path, struct stat* buf); +int +dlsym_lstat(int ver, const char* path, struct stat* buf); +int +dlsym_lxstat64(int ver, const char* path, struct stat64* buf); +int +dlsym_xstat64(int ver, const char* path, struct stat64* buf); +int +dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags); +int +dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags); + +int +dlsym_rename(const char* old_path, const char* new_path); +int +dlsym_unlink(char* path); +int +dlsym_remove(char* path); + + +// File API (stdio) +FILE* +dlsym_fopen(const char* filename, const char* mode); +FILE* +dlsym_fdopen(int fd, const char* mode); +int +dlsym_fclose(FILE* stream); + +size_t +dlsym_fread(void* ptr, size_t size, size_t nmemb, FILE* stream); +size_t +dlsym_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream); + +int +dlsym_fseek(FILE* stream, long int offset, int whence); +long +dlsym_ftell(FILE* stream); +void +dlsym_rewind(FILE* stream); +int +dlsym_feof(FILE* stream); + + +// Directory API +DIR* +dlsym_opendir(char* dirname); +DIR* +dlsym_opendir64(char* dirname); +int +dlsym_closedir(DIR* dirp); + +long +dlsym_telldir(DIR* dirp); +void +dlsym_seekdir(DIR* dirp, long loc); + +struct dirent* +dlsym_readdir(DIR* dirp); +struct dirent64* +dlsym_readdir64(DIR* dirp); + +int +dlsym_mkdir(char* path, mode_t mode); +int +dlsym_rmdir(char* path); + + +// Proccess API +int +dlsym_fork(void); + +int +dlsym_pipe(int pipefd[2]); + +int +dlsym_dup(int fd); +int +dlsym_dup2(int fd, int fd2); + +void +dlsym_exit(int status); + + +// Manager API +int +dlsym_chdir(char* path); +int +dlsym_chmod(char* path, mode_t mode); +int +dlsym_fchmod(int fd, mode_t mode); +int +dlsym_chown(char* path, uid_t owner, gid_t group); +int +dlsym_fcntl(int fd, int cmd, long arg); +int +dlsym_access(const char* path, int mode); +int +dlsym_fsync(int fd); +int +dlsym_flock(int fd, int operation); + + +// Memory API +void* +dlsym_mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset); + +int +open64(const char* path, int flags, ...); +int +open(const char* path, int flags, ...); +int +close(int fd); +int +creat(const char* path, mode_t mode); +int +ftruncate(int fd, off_t length); +int +mkstemp(char* templates); + +ssize_t +read(int fd, void* buf, size_t nbyte); +ssize_t +write(int fd, void* buf, size_t nbyte); + + +/* ................................................................... */ + +#ifdef __cplusplus +} +#endif diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 7f7b1527d..88a9e6d8c 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -6,150 +6,307 @@ #define debug_info printf -int (*real_open )(char *, int, mode_t) = NULL; -int (*real_open64 )(char *, int, mode_t) = NULL; -int (*real___open_2)(char *, int) = NULL; -int (*real_openat )(int, char *, int, mode_t) = NULL; +int (*real_open)(char*, int, mode_t) = NULL; +int (*real_open64)(char*, int, mode_t) = NULL; +int (*real___open_2)(char*, int) = NULL; +int (*real_openat)(int, char*, int, mode_t) = NULL; +int (*real_close)(int) = NULL; +int (*real_creat)(const char*, mode_t) = NULL; +int (*real_ftruncate)(int, off_t) = NULL; +int (*real_mkstemp)(char*) = NULL; +ssize_t (*real_read)(int, void*, size_t) = NULL; +ssize_t (*real_write)(int, void*, size_t) = NULL; + // File API -int dlsym_open (char *path, int flags) -{ - debug_info("[SYSCALL_PROXIES] [dlsym_open] >> Begin\n"); +int +dlsym_open(char* path, int flags) { + debug_info("[SYSCALL_PROXIES] [dlsym_open] >> Begin\n"); + + if(real_open == NULL) { + real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char*) path, flags, 0); + + debug_info("[SYSCALL_PROXIES] [dlsym_open] >> End\n"); + + return fd; +} + +int +dlsym_open2(char* path, int flags, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> Begin\n"); + + if(real_open == NULL) { + real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char*) path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> End\n"); + + return fd; +} + +int +dlsym_openat(int fd, char* path, int flags, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> Begin\n"); + std::cout << "XXX" << std::endl; + if(real_openat == NULL) { + real_openat = + (int (*)(int, char*, int, mode_t)) dlsym(RTLD_NEXT, "openat"); + } + + int fd2 = real_openat(fd, (char*) path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> End\n"); + + return fd2; +} - if (real_open == NULL) { - real_open = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open"); - } - - int fd = real_open((char *)path, flags, 0); +int +dlsym_open64(char* path, int flags, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> Begin\n"); - debug_info("[SYSCALL_PROXIES] [dlsym_open] >> End\n"); + if(real_open64 == NULL) { + real_open64 = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open64"); + } - return fd; + int fd = real_open64((char*) path, flags, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> End\n"); + + return fd; } -int dlsym_open2 (char *path, int flags, mode_t mode) -{ - debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> Begin\n"); +int +dlsym___open_2(char* path, int flags) { + debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> Begin\n"); + + if(real___open_2 == NULL) { + real___open_2 = (int (*)(char*, int)) dlsym(RTLD_NEXT, "__open"); + } - if (real_open == NULL) { - real_open = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open"); - } - - int fd = real_open((char *)path, flags, mode); + int fd = real___open_2((char*) path, flags); - debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> End\n"); + debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> End\n"); - return fd; + return fd; } -int dlsym_openat (int fd,char *path, int flags, mode_t mode) -{ - debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> Begin\n"); -std::cout << "XXX" << std::endl; - if (real_openat == NULL) { - real_openat = (int (*)(int,char *, int, mode_t)) dlsym(RTLD_NEXT, "openat"); - } - - int fd2 = real_openat(fd,(char *)path, flags, mode); +int +dlsym_close(int fd) { + debug_info("[SYSCALL_PROXIES] [dlsym_close] >> Begin\n"); + + if(real_close == NULL) { + real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); + } + + int ret = real_close(fd); - debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> End\n"); + debug_info("[SYSCALL_PROXIES] [dlsym_close] >> End\n"); - return fd2; + return ret; } -int dlsym_open64 (char *path, int flags, mode_t mode) -{ - debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> Begin\n"); +int +dlsym_creat(const char* path, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_creat] >> Begin\n"); - if (real_open64 == NULL){ - real_open64 = (int (*)(char *, int, mode_t)) dlsym(RTLD_NEXT, "open64"); - } - - int fd = real_open64((char *)path, flags, mode); + if(real_creat == NULL) { + real_creat = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "creat"); + } - debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> End\n"); + int fd = real_creat((char*) path, mode); - return fd; + debug_info("[SYSCALL_PROXIES] [dlsym_creat] >> End\n"); + + return fd; } -int dlsym___open_2 (char *path, int flags) -{ - debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> Begin\n"); +int +dlsym_ftruncate(int fd, off_t length) { + debug_info("[SYSCALL_PROXIES] [dlsym_ftruncate] >> Begin\n"); + + if(real_ftruncate == NULL) { + real_ftruncate = (int (*)(int, off_t)) dlsym(RTLD_NEXT, "ftruncate"); + } - if (real___open_2 == NULL) { - real___open_2 = (int (*)(char *, int)) dlsym(RTLD_NEXT, "__open"); - } - - int fd = real___open_2((char *)path, flags); + int ret = real_ftruncate(fd, length); - debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> End\n"); - return fd; + return ret; } +ssize_t +dlsym_read(int fd, void* buf, size_t nbyte) { + debug_info("[SYSCALL_PROXIES] [dlsym_read] >> Begin\n"); + + if(real_read == NULL) { + real_read = (ssize_t(*)(int, void*, size_t)) dlsym(RTLD_NEXT, "read"); + } + + ssize_t ret = real_read(fd, buf, nbyte); + + debug_info("[SYSCALL_PROXIES] [dlsym_read] >> End\n"); + + return ret; +} + +ssize_t +dlsym_write(int fd, void* buf, size_t nbyte) { + debug_info("[SYSCALL_PROXIES] [dlsym_write] >> Begin\n"); + + if(real_write == NULL) { + real_write = (ssize_t(*)(int, void*, size_t)) dlsym(RTLD_NEXT, "write"); + } + + ssize_t ret = real_write(fd, buf, nbyte); + + debug_info("[SYSCALL_PROXIES] [dlsym_write] >> End\n"); + + return ret; +} + + +/* + + +ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset); +ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset); +ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset); +ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset); +int dlsym_mkstemp (char *templates); + + + +off_t dlsym_lseek (int fd, off_t offset, int whence); +off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); +*/ + // File API -int open ( const char *path, int flags, ... ) -{ - int ret, fd; - va_list ap; - mode_t mode = 0; +int +open(const char* path, int flags, ...) { + int ret, fd; + va_list ap; + mode_t mode = 0; - va_start(ap, flags); + va_start(ap, flags); - mode = va_arg(ap, mode_t); + mode = va_arg(ap, mode_t); + + debug_info("[BYPASS] >> Begin open....\n"); + debug_info("[BYPASS] 1) Path => %s\n", path); + debug_info("[BYPASS] 2) Flags => %d\n", flags); + debug_info("[BYPASS] 3) Mode => %d\n", mode); - debug_info("[BYPASS] >> Begin open....\n"); - debug_info("[BYPASS] 1) Path => %s\n", path); - debug_info("[BYPASS] 2) Flags => %d\n", flags); - debug_info("[BYPASS] 3) Mode => %d\n", mode); - debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); - ret = dlsym_open2((char *)path, flags, mode); + ret = dlsym_open2((char*) path, flags, mode); + + debug_info("[BYPASS]\t dlsym_open (%s,%o,%o) -> %d\n", path, flags, mode, + ret); - debug_info("[BYPASS]\t dlsym_open (%s,%o,%o) -> %d\n", path, flags, mode, ret); - - va_end(ap); + va_end(ap); - debug_info("[BYPASS] << After open....\n"); + debug_info("[BYPASS] << After open....\n"); - return ret; + return ret; } -int open64 ( const char *path, int flags, ... ) -{ - int fd, ret; - va_list ap; - mode_t mode = 0; +int +open64(const char* path, int flags, ...) { + int fd, ret; + va_list ap; + mode_t mode = 0; - va_start(ap, flags); + va_start(ap, flags); - mode = va_arg(ap, mode_t); + mode = va_arg(ap, mode_t); + + debug_info("[BYPASS] >> Begin open64....\n"); + debug_info("[BYPASS] 1) Path => %s\n", path); + debug_info("[BYPASS] 2) flags => %d\n", flags); + debug_info("[BYPASS] 3) mode => %d\n", mode); - debug_info("[BYPASS] >> Begin open64....\n"); - debug_info("[BYPASS] 1) Path => %s\n", path); - debug_info("[BYPASS] 2) flags => %d\n", flags); - debug_info("[BYPASS] 3) mode => %d\n", mode); - debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o)\n", path, flags, mode); - ret = dlsym_open64((char *)path, flags, mode); + ret = dlsym_open64((char*) path, flags, mode); + + debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o) -> %d\n", path, flags, mode, + ret); - debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o) -> %d\n", path, flags, mode, ret); - - va_end(ap); + va_end(ap); - debug_info("[BYPASS] << After open64....\n"); + debug_info("[BYPASS] << After open64....\n"); - return ret; + return ret; } // Generate the rest of the functions to build a libc io interception +int +close(int fd) { + debug_info("[BYPASS] >> Begin close....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + int ret = dlsym_close(fd); + + debug_info("[BYPASS] << After close....\n"); + + return ret; +} + +int +creat(const char* path, mode_t mode) { + debug_info("[BYPASS] >> Begin creat....\n"); + debug_info("[BYPASS] 1) path => %s\n", path); + debug_info("[BYPASS] 2) mode => %d\n", mode); + + int ret = dlsym_creat(path, mode); + + debug_info("[BYPASS] << After creat....\n"); + + return ret; +} + +int +ftruncate(int fd, off_t length) { + debug_info("[BYPASS] >> Begin ftruncate....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] 2) length => %d\n", length); + + int ret = dlsym_ftruncate(fd, length); + + debug_info("[BYPASS] << After ftruncate....\n"); + + return ret; +} + +ssize_t +read(int fd, void* buf, size_t nbyte) { + debug_info("[BYPASS] >> Begin read....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + ssize_t ret = dlsym_read(fd, buf, nbyte); + + debug_info("[BYPASS] << After read....\n"); + + return ret; +} + +ssize_t +write(int fd, void* buf, size_t nbyte) { + debug_info("[BYPASS] >> Begin write....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + ssize_t ret = dlsym_write(fd, buf, nbyte); + debug_info("[BYPASS] << After write....\n"); + return ret; -- GitLab From 077e8ce331e1c318e9245d210b28ea241dbdf86d Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Fri, 16 Aug 2024 13:35:17 +0200 Subject: [PATCH 09/32] fd --- src/client/gkfs_libc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 88a9e6d8c..d539a3691 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -279,7 +279,7 @@ int ftruncate(int fd, off_t length) { debug_info("[BYPASS] >> Begin ftruncate....\n"); debug_info("[BYPASS] 1) fd => %d\n", fd); - debug_info("[BYPASS] 2) length => %d\n", length); + debug_info("[BYPASS] 2) length => %ld\n", length); int ret = dlsym_ftruncate(fd, length); @@ -310,3 +310,4 @@ write(int fd, void* buf, size_t nbyte) { debug_info("[BYPASS] << After write....\n"); return ret; +} -- GitLab From 857752151cc7d364ec013b0506e9d805ab59b56b Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Fri, 6 Sep 2024 19:32:37 +0200 Subject: [PATCH 10/32] wip --- include/client/gkfs_libc.hpp | 5 ++ src/client/gkfs_libc.cpp | 91 +++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index f644ee621..53d75e87c 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -210,6 +210,11 @@ read(int fd, void* buf, size_t nbyte); ssize_t write(int fd, void* buf, size_t nbyte); +int +mkdir(char* path, mode_t mode); + +int +rmdir(char* path); /* ................................................................... */ diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index d539a3691..5301a64b9 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -3,6 +3,10 @@ #include #include #include +#include +#include +#include +#include #define debug_info printf @@ -14,9 +18,12 @@ int (*real_close)(int) = NULL; int (*real_creat)(const char*, mode_t) = NULL; int (*real_ftruncate)(int, off_t) = NULL; int (*real_mkstemp)(char*) = NULL; +int (*real_mkdir)(char*, mode_t) = NULL; +int (*real_rmdir)(char*) = NULL; ssize_t (*real_read)(int, void*, size_t) = NULL; ssize_t (*real_write)(int, void*, size_t) = NULL; +std::atomic gkfs_initialized = false; // File API int @@ -169,6 +176,36 @@ dlsym_write(int fd, void* buf, size_t nbyte) { return ret; } +int +dlsym_mkdir(char* path, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_mkdir] >> Begin\n"); + + if(real_mkdir == NULL) { + real_mkdir = (int (*)(char*, mode_t)) dlsym(RTLD_NEXT, "mkdir"); + } + + int ret = real_mkdir(path, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_mkdir] >> End\n"); + + return ret; +} + +int +dlsym_rmdir(char* path){ + debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> Begin\n"); + + if(real_rmdir == NULL) { + real_rmdir = (int (*)(char*)) dlsym(RTLD_NEXT, "rmdir"); + } + + int ret = real_rmdir(path); + + debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> End\n"); + + return ret; +} + /* @@ -183,6 +220,7 @@ int dlsym_mkstemp (char *templates); off_t dlsym_lseek (int fd, off_t offset, int whence); off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); + */ // File API @@ -201,6 +239,33 @@ open(const char* path, int flags, ...) { debug_info("[BYPASS] 2) Flags => %d\n", flags); debug_info("[BYPASS] 3) Mode => %d\n", mode); + if (!gkfs_initialized) { + gkfs_init(); + gkfs_initialized = true; + } + + // Analyze if path is inside virtual point or not + /* *result = gkfs::hook::hook_openat( + AT_FDCWD, reinterpret_cast(arg0), + static_cast(arg1), static_cast(arg2)); + */ + // Could we access CTX? + + // Basically we need to do this when using paths: + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_open(resolved, mode, flags); + + default: + // Try normal open. + break; + } debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); @@ -227,7 +292,7 @@ open64(const char* path, int flags, ...) { va_start(ap, flags); mode = va_arg(ap, mode_t); - + debug_info("[BYPASS] >> Begin open64....\n"); debug_info("[BYPASS] 1) Path => %s\n", path); debug_info("[BYPASS] 2) flags => %d\n", flags); @@ -311,3 +376,27 @@ write(int fd, void* buf, size_t nbyte) { return ret; } + +int +mkdir(char* path, mode_t mode){ + debug_info("[BYPASS] >> Begin mkdir....\n"); + debug_info("[BYPASS] 1) path => %s\n", path); + + int ret = dlsym_mkdir(path, mode); + + debug_info("[BYPASS] << After mkdir....\n"); + + return ret; +} + +int +rmdir(char* path){ + debug_info("[BYPASS] >> Begin rmdir....\n"); + debug_info("[BYPASS] 1) path => %s\n", path); + + int ret = dlsym_rmdir(path); + + debug_info("[BYPASS] << After rmdir....\n"); + + return ret; +} \ No newline at end of file -- GitLab From 4c1abe6f58bd24af062c511d1ae0b781fd8e5271 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 12:04:09 +0200 Subject: [PATCH 11/32] First working libc interception version, init_libc should be still ifdef if we use the user library --- include/client/gkfs_libc.hpp | 20 ++---- src/client/gkfs_libc.cpp | 134 ++++++++++++++++++++++------------- src/client/logging.cpp | 3 +- src/client/open_file_map.cpp | 25 +------ 4 files changed, 96 insertions(+), 86 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 53d75e87c..446a21c84 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -20,25 +20,17 @@ */ + #ifdef __cplusplus extern "C" { #endif - -/* ... Include / Inclusion ........................................... */ - #include #include #include #include +#include -/* ... Const / Const ................................................. */ - - -/* ... Data structures / Estructuras de datos ........................ */ - - -/* ... Functions / Funciones ......................................... */ // File API int @@ -201,20 +193,20 @@ close(int fd); int creat(const char* path, mode_t mode); int -ftruncate(int fd, off_t length); +ftruncate(int fd, off_t length) noexcept; int mkstemp(char* templates); ssize_t read(int fd, void* buf, size_t nbyte); ssize_t -write(int fd, void* buf, size_t nbyte); +write(int fd, const void* buf, size_t nbyte); int -mkdir(char* path, mode_t mode); +mkdir(const char* path, mode_t mode); int -rmdir(char* path); +rmdir(const char* path) noexcept; /* ................................................................... */ diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 5301a64b9..d87b9e161 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -7,9 +7,12 @@ #include #include #include +#include -#define debug_info printf +// #define debug_info printf +#define debug_info(...) +thread_local std::atomic reentrant = false; int (*real_open)(char*, int, mode_t) = NULL; int (*real_open64)(char*, int, mode_t) = NULL; int (*real___open_2)(char*, int) = NULL; @@ -18,12 +21,12 @@ int (*real_close)(int) = NULL; int (*real_creat)(const char*, mode_t) = NULL; int (*real_ftruncate)(int, off_t) = NULL; int (*real_mkstemp)(char*) = NULL; -int (*real_mkdir)(char*, mode_t) = NULL; -int (*real_rmdir)(char*) = NULL; +int (*real_mkdir)(const char*, mode_t) = NULL; +int (*real_rmdir)(const char*) = NULL; ssize_t (*real_read)(int, void*, size_t) = NULL; -ssize_t (*real_write)(int, void*, size_t) = NULL; +ssize_t (*real_write)(int, const void*, size_t) = NULL; -std::atomic gkfs_initialized = false; +thread_local std::atomic gkfs_initialized = false; // File API int @@ -43,7 +46,6 @@ dlsym_open(char* path, int flags) { int dlsym_open2(char* path, int flags, mode_t mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> Begin\n"); if(real_open == NULL) { real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); @@ -51,8 +53,6 @@ dlsym_open2(char* path, int flags, mode_t mode) { int fd = real_open((char*) path, flags, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_open2] >> End\n"); - return fd; } @@ -148,25 +148,22 @@ dlsym_ftruncate(int fd, off_t length) { ssize_t dlsym_read(int fd, void* buf, size_t nbyte) { - debug_info("[SYSCALL_PROXIES] [dlsym_read] >> Begin\n"); - if(real_read == NULL) { real_read = (ssize_t(*)(int, void*, size_t)) dlsym(RTLD_NEXT, "read"); } ssize_t ret = real_read(fd, buf, nbyte); - debug_info("[SYSCALL_PROXIES] [dlsym_read] >> End\n"); - return ret; } ssize_t -dlsym_write(int fd, void* buf, size_t nbyte) { +dlsym_write(int fd, const void* buf, size_t nbyte) { debug_info("[SYSCALL_PROXIES] [dlsym_write] >> Begin\n"); if(real_write == NULL) { - real_write = (ssize_t(*)(int, void*, size_t)) dlsym(RTLD_NEXT, "write"); + real_write = (ssize_t(*)(int, const void*, size_t)) dlsym(RTLD_NEXT, + "write"); } ssize_t ret = real_write(fd, buf, nbyte); @@ -177,11 +174,11 @@ dlsym_write(int fd, void* buf, size_t nbyte) { } int -dlsym_mkdir(char* path, mode_t mode) { +dlsym_mkdir(const char* path, mode_t mode) { debug_info("[SYSCALL_PROXIES] [dlsym_mkdir] >> Begin\n"); if(real_mkdir == NULL) { - real_mkdir = (int (*)(char*, mode_t)) dlsym(RTLD_NEXT, "mkdir"); + real_mkdir = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "mkdir"); } int ret = real_mkdir(path, mode); @@ -192,11 +189,11 @@ dlsym_mkdir(char* path, mode_t mode) { } int -dlsym_rmdir(char* path){ - debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> Begin\n"); +dlsym_rmdir(const char* path) { + debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> Begin\n"); if(real_rmdir == NULL) { - real_rmdir = (int (*)(char*)) dlsym(RTLD_NEXT, "rmdir"); + real_rmdir = (int (*)(const char*)) dlsym(RTLD_NEXT, "rmdir"); } int ret = real_rmdir(path); @@ -223,6 +220,7 @@ off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); */ + // File API int open(const char* path, int flags, ...) { @@ -234,24 +232,11 @@ open(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open....\n"); - debug_info("[BYPASS] 1) Path => %s\n", path); - debug_info("[BYPASS] 2) Flags => %d\n", flags); - debug_info("[BYPASS] 3) Mode => %d\n", mode); - - if (!gkfs_initialized) { - gkfs_init(); - gkfs_initialized = true; - } - - // Analyze if path is inside virtual point or not - /* *result = gkfs::hook::hook_openat( - AT_FDCWD, reinterpret_cast(arg0), - static_cast(arg1), static_cast(arg2)); - */ - // Could we access CTX? + debug_info("[BYPASS] >> Begin open.... %s %d %d\n", path, flags, mode); - // Basically we need to do this when using paths: + // We have a infinite loop, with logging as it is initialized an issues an open that gets intercepted here. + // Maybe we need a variable to stop this internal loops? or bypass with tmp. + if (CTX->interception_enabled()) { std::string resolved; auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); switch(rstatus) { @@ -266,7 +251,7 @@ open(const char* path, int flags, ...) { // Try normal open. break; } - + } debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); ret = dlsym_open2((char*) path, flags, mode); @@ -292,12 +277,26 @@ open64(const char* path, int flags, ...) { va_start(ap, flags); mode = va_arg(ap, mode_t); - + debug_info("[BYPASS] >> Begin open64....\n"); debug_info("[BYPASS] 1) Path => %s\n", path); debug_info("[BYPASS] 2) flags => %d\n", flags); debug_info("[BYPASS] 3) mode => %d\n", mode); + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_open(resolved, mode, flags); + + default: + // Try normal open. + break; + } debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o)\n", path, flags, mode); @@ -317,12 +316,18 @@ open64(const char* path, int flags, ...) { // Generate the rest of the functions to build a libc io interception int close(int fd) { - debug_info("[BYPASS] >> Begin close....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); - int ret = dlsym_close(fd); + // Is fd from gekkofs ? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_close(fd); + } + + debug_info("[BYPASS]\t dlsym_close (%d)\n", fd); - debug_info("[BYPASS] << After close....\n"); + // Try normal close. + auto ret = dlsym_close(fd); + + debug_info("[BYPASS]\t dlsym_close (%d) -> %d\n", fd, ret); return ret; } @@ -333,6 +338,25 @@ creat(const char* path, mode_t mode) { debug_info("[BYPASS] 1) path => %s\n", path); debug_info("[BYPASS] 2) mode => %d\n", mode); + // Is path from gekkofs? + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_create(resolved, mode); + + default: + // Try normal open. + break; + } + + debug_info("[BYPASS]\t dlsym_creat (%s,%o)\n", path, mode); + + int ret = dlsym_creat(path, mode); debug_info("[BYPASS] << After creat....\n"); @@ -355,12 +379,19 @@ ftruncate(int fd, off_t length) { ssize_t read(int fd, void* buf, size_t nbyte) { - debug_info("[BYPASS] >> Begin read....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] >> Begin read....%d - %ld\n", fd, nbyte); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[READ from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_read(fd, buf, nbyte); + } + + debug_info("[BYPASS]\t dlsym_read (%d,%p,%zu)\n", fd, buf, nbyte); ssize_t ret = dlsym_read(fd, buf, nbyte); - debug_info("[BYPASS] << After read....\n"); + debug_info("[BYPASS] << After read....\n"); return ret; } @@ -369,16 +400,23 @@ ssize_t write(int fd, void* buf, size_t nbyte) { debug_info("[BYPASS] >> Begin write....\n"); debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_write(fd, buf, nbyte); + } + + debug_info("[BYPASS]\t dlsym_write (%d,%p,%zu)\n", fd, buf, nbyte); ssize_t ret = dlsym_write(fd, buf, nbyte); - debug_info("[BYPASS] << After write....\n"); + debug_info("[BYPASS] << After write....\n"); return ret; } int -mkdir(char* path, mode_t mode){ +mkdir(const char* path, mode_t mode) { debug_info("[BYPASS] >> Begin mkdir....\n"); debug_info("[BYPASS] 1) path => %s\n", path); @@ -390,7 +428,7 @@ mkdir(char* path, mode_t mode){ } int -rmdir(char* path){ +rmdir(const char* path) { debug_info("[BYPASS] >> Begin rmdir....\n"); debug_info("[BYPASS] 1) path => %s\n", path); diff --git a/src/client/logging.cpp b/src/client/logging.cpp index 830d5691e..1276ef88b 100644 --- a/src/client/logging.cpp +++ b/src/client/logging.cpp @@ -317,7 +317,8 @@ logger::logger(const std::string& opts, const std::string& path, // because we want the call to be intercepted by our hooks, which // allows us to categorize the resulting fd as 'internal' and // relocate it to our private range - int fd = ::open(file_path.c_str(), flags, 0600); + //int fd = ::open(file_path.c_str(), flags, 0600); + int fd = ::syscall_no_intercept(SYS_open,file_path.c_str(), flags, 0600); if(fd == -1) { log(gkfs::log::error, __func__, __LINE__, diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 059c82d48..72d5fa8b5 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -133,30 +133,9 @@ OpenFileMap::exist(const int fd) { int OpenFileMap::safe_generate_fd_idx_() { int fd = 0; - if (CTX->protect_fds()) { - fd = generate_fd_idx(); - /* - * Check if fd is still in use and generate another if yes - * Note that this can only happen once the all fd indices within the int has - * been used to the int::max Once this limit is exceeded, we set fd_idx back - * to 3 and begin anew. Only then, if a file was open for a long time will - * we have to generate another index. - * - * This situation can only occur when all fd indices have been given away - * once and we start again, in which case the fd_validation_needed flag is - * set. fd_validation is set to false, if - */ - if(fd_validation_needed) { - while(exist(fd)) { - fd = generate_fd_idx(); - } - } - } - else { - fd = syscall_no_intercept( + fd = syscall_no_intercept( SYS_open, "/dev/null", O_RDWR, S_IRUSR | S_IWUSR); - } return fd; } @@ -235,7 +214,7 @@ OpenFileMap::generate_fd_idx() { * which tells can tell the OpenFileMap that it should check if this fd * is really safe to use. */ - fd_idx = 100000; + fd_idx = 10000; fd_validation_needed = true; } return fd_idx++; -- GitLab From 7e3d273f32895ba319e684156ace208761112327 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 13:09:30 +0200 Subject: [PATCH 12/32] added hpp --- include/client/preload.hpp | 5 +++++ include/client/preload_context.hpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/client/preload.hpp b/include/client/preload.hpp index afad97c68..17e951cff 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -47,6 +47,11 @@ init_preload() __attribute__((constructor)); void destroy_preload() __attribute__((destructor)); +#else +void init_libc() __attribute__((constructor)); + +void destroy_libc() __attribute__((destructor)); + #endif #endif // IOINTERCEPT_PRELOAD_HPP diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index 3d2a16976..6f638b879 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -128,7 +128,7 @@ private: std::bitset protected_fds_; std::string hostname; int replicas_; - bool protect_fds_{false}; + bool protect_fds_{true}; std::shared_ptr write_metrics_; std::shared_ptr read_metrics_; -- GitLab From 9c97485da334141784c991757dda1a6e135761de Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 13:10:20 +0200 Subject: [PATCH 13/32] cpp --- src/client/preload.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 31ef3cee7..b4fc8abb2 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -462,3 +462,29 @@ gkfs_end() { return 0; } + + +/** + * @brief Automatically launch init/destroy + * + */ + +void init_libc() { + CTX->enable_interception(); + CTX->init_logging(); + + // from here ownwards it is safe to print messages + LOG(DEBUG, "Logging subsystem initialized"); + + gkfs::preload::init_environment(); +} + +void destroy_libc() { + CTX->clear_hosts(); + LOG(DEBUG, "Peer information deleted"); + + ld_network_service.reset(); + LOG(DEBUG, "RPC subsystem shut down"); + + LOG(INFO, "All subsystems shut down. Client shutdown complete."); +} -- GitLab From c3b2e3088573b6940d9b933429ae33006ac4f19f Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 14:50:42 +0200 Subject: [PATCH 14/32] Added closes_range libc implementation for ssh --- include/client/gkfs_libc.hpp | 3 ++- include/client/preload_context.hpp | 2 +- src/client/gkfs_libc.cpp | 42 ++++++++++++++++++++++++++++-- src/client/open_file_map.cpp | 24 ++++++++++++++++- src/client/preload.cpp | 2 +- 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 446a21c84..99bd637f0 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -45,7 +45,8 @@ int dlsym___open_2(char* path, int flags); int dlsym_close(int fd); - +int +dlsym_close_range(unsigned int low, unsigned int high, int flags); int dlsym_creat(const char* path, mode_t mode); int diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index 6f638b879..3d2a16976 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -128,7 +128,7 @@ private: std::bitset protected_fds_; std::string hostname; int replicas_; - bool protect_fds_{true}; + bool protect_fds_{false}; std::shared_ptr write_metrics_; std::shared_ptr read_metrics_; diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index d87b9e161..87809add0 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -9,8 +9,8 @@ #include #include -// #define debug_info printf -#define debug_info(...) +#define debug_info printf +// #define debug_info(...) thread_local std::atomic reentrant = false; int (*real_open)(char*, int, mode_t) = NULL; @@ -18,6 +18,7 @@ int (*real_open64)(char*, int, mode_t) = NULL; int (*real___open_2)(char*, int) = NULL; int (*real_openat)(int, char*, int, mode_t) = NULL; int (*real_close)(int) = NULL; +int (*real_close_range)(unsigned int, unsigned int, int) = NULL; int (*real_creat)(const char*, mode_t) = NULL; int (*real_ftruncate)(int, off_t) = NULL; int (*real_mkstemp)(char*) = NULL; @@ -117,6 +118,21 @@ dlsym_close(int fd) { return ret; } +int +dlsym_close_range(unsigned int low, unsigned int high, int flags) { + debug_info("[SYSCALL_PROXIES] [dlsym_close_range] >> Begin\n"); + + if(real_close_range == NULL) { + real_close_range = (int (*)(unsigned int, unsigned int, int)) dlsym(RTLD_NEXT, "close_range"); + } + + int ret = real_close_range(low, high, flags); + + debug_info("[SYSCALL_PROXIES] [dlsym_close_range] >> End\n"); + + return ret; +} + int dlsym_creat(const char* path, mode_t mode) { debug_info("[SYSCALL_PROXIES] [dlsym_creat] >> Begin\n"); @@ -332,6 +348,28 @@ close(int fd) { return ret; } +int +close_range(unsigned low, unsigned high, int flags) { + + // Is fd from gekkofs ? + for (unsigned int i = low; i <= high; i++) { + if (i > GKFS_MAX_OPEN_FDS) break; + if(CTX->file_map()->exist(i)) { + gkfs::syscall::gkfs_close(i); + } + return 0; + } + + debug_info("[BYPASS]\t dlsym_close_range (%d)\n", low); + + // Try normal close. + auto ret = dlsym_close_range(low, high, flags); + + debug_info("[BYPASS]\t dlsym_close_range (%d) -> %d\n", low, ret); + + return ret; +} + int creat(const char* path, mode_t mode) { debug_info("[BYPASS] >> Begin creat....\n"); diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 72d5fa8b5..627f4521f 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -133,9 +133,31 @@ OpenFileMap::exist(const int fd) { int OpenFileMap::safe_generate_fd_idx_() { int fd = 0; - fd = syscall_no_intercept( + + if (CTX->protect_fds()) { + fd = generate_fd_idx(); + /* + * Check if fd is still in use and generate another if yes + * Note that this can only happen once the all fd indices within the int has + * been used to the int::max Once this limit is exceeded, we set fd_idx back + * to 3 and begin anew. Only then, if a file was open for a long time will + * we have to generate another index. + * + * This situation can only occur when all fd indices have been given away + * once and we start again, in which case the fd_validation_needed flag is + * set. fd_validation is set to false, if + */ + if(fd_validation_needed) { + while(exist(fd)) { + fd = generate_fd_idx(); + } + } + } + else { + fd = syscall_no_intercept( SYS_open, "/dev/null", O_RDWR, S_IRUSR | S_IWUSR); + } return fd; } diff --git a/src/client/preload.cpp b/src/client/preload.cpp index b4fc8abb2..4bce1e742 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -466,7 +466,7 @@ gkfs_end() { /** * @brief Automatically launch init/destroy - * + * TODO: Check if this works with the user library! */ void init_libc() { -- GitLab From a66fb6463f3b9568cbd72023bc721d6c16de7d6d Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Tue, 1 Oct 2024 14:51:22 +0200 Subject: [PATCH 15/32] Cmake update --- src/client/CMakeLists.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 3645e392c..303fd772d 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -83,14 +83,36 @@ target_sources( target_sources( gkfs_libc_intercept - PRIVATE + PRIVATE gkfs_functions.cpp gkfs_libc.cpp + intercept.cpp + hooks.cpp + logging.cpp + open_file_map.cpp + open_dir.cpp + path.cpp + preload.cpp + preload_context.cpp + preload_util.cpp + malleability.cpp + cache.cpp + rpc/rpc_types.cpp + rpc/forward_data.cpp + rpc/forward_data_proxy.cpp + rpc/forward_management.cpp + rpc/forward_metadata.cpp + rpc/forward_metadata_proxy.cpp + rpc/forward_malleability.cpp + syscalls/detail/syscall_info.c syscalls/util.S ) target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL) target_link_options(gkfs_user_lib PRIVATE -z noexecstack) +target_compile_definitions(gkfs_libc_intercept PUBLIC BYPASS_SYSCALL) +target_link_options(gkfs_libc_intercept PRIVATE) #-z noexecstack + if (GKFS_ENABLE_AGIOS) target_compile_definitions(gkfs_intercept PUBLIC GKFS_ENABLE_AGIOS) endif () -- GitLab From 0e95562a1d79ea15bc04a7ec661fb920c9695205 Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 12:10:02 +0200 Subject: [PATCH 16/32] moving CTX->interception at the end of the initialization (MN5 issue) --- include/client/gkfs_libc.hpp | 1 - src/client/gkfs_libc.cpp | 41 ++++++++++++++++++------------------ src/client/preload.cpp | 11 ++++++---- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 99bd637f0..54bc4f930 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -20,7 +20,6 @@ */ - #ifdef __cplusplus extern "C" { #endif diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 87809add0..a4b9d4009 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -27,8 +27,6 @@ int (*real_rmdir)(const char*) = NULL; ssize_t (*real_read)(int, void*, size_t) = NULL; ssize_t (*real_write)(int, const void*, size_t) = NULL; -thread_local std::atomic gkfs_initialized = false; - // File API int dlsym_open(char* path, int flags) { @@ -123,7 +121,8 @@ dlsym_close_range(unsigned int low, unsigned int high, int flags) { debug_info("[SYSCALL_PROXIES] [dlsym_close_range] >> Begin\n"); if(real_close_range == NULL) { - real_close_range = (int (*)(unsigned int, unsigned int, int)) dlsym(RTLD_NEXT, "close_range"); + real_close_range = (int (*)(unsigned int, unsigned int, int)) dlsym( + RTLD_NEXT, "close_range"); } int ret = real_close_range(low, high, flags); @@ -250,23 +249,24 @@ open(const char* path, int flags, ...) { debug_info("[BYPASS] >> Begin open.... %s %d %d\n", path, flags, mode); - // We have a infinite loop, with logging as it is initialized an issues an open that gets intercepted here. - // Maybe we need a variable to stop this internal loops? or bypass with tmp. - if (CTX->interception_enabled()) { - std::string resolved; - auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); - switch(rstatus) { + // We have a infinite loop, with logging as it is initialized an issues an + // open that gets intercepted here. Maybe we need a variable to stop this + // internal loops? or bypass with tmp. + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { - case gkfs::preload::RelativizeStatus::fd_not_a_dir: - return -ENOTDIR; + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; - case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_open(resolved, mode, flags); + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_open(resolved, mode, flags); - default: - // Try normal open. - break; - } + default: + // Try normal open. + break; + } } debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); @@ -352,8 +352,9 @@ int close_range(unsigned low, unsigned high, int flags) { // Is fd from gekkofs ? - for (unsigned int i = low; i <= high; i++) { - if (i > GKFS_MAX_OPEN_FDS) break; + for(unsigned int i = low; i <= high; i++) { + if(i > GKFS_MAX_OPEN_FDS) + break; if(CTX->file_map()->exist(i)) { gkfs::syscall::gkfs_close(i); } @@ -438,7 +439,7 @@ ssize_t write(int fd, void* buf, size_t nbyte) { debug_info("[BYPASS] >> Begin write....\n"); debug_info("[BYPASS] 1) fd => %d\n", fd); - + // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { return gkfs::syscall::gkfs_write(fd, buf, nbyte); diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 4bce1e742..30d94365c 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -364,7 +364,7 @@ init_preload() { // To prevent this for our internal // initialization code, we forcefully occupy the user fd range to force // such modules to create fds in our private range. - if (CTX->protect_fds()) { + if(CTX->protect_fds()) { CTX->protect_user_fds(); } @@ -469,17 +469,20 @@ gkfs_end() { * TODO: Check if this works with the user library! */ -void init_libc() { - CTX->enable_interception(); +void +init_libc() { + CTX->init_logging(); // from here ownwards it is safe to print messages LOG(DEBUG, "Logging subsystem initialized"); gkfs::preload::init_environment(); + CTX->enable_interception(); } -void destroy_libc() { +void +destroy_libc() { CTX->clear_hosts(); LOG(DEBUG, "Peer information deleted"); -- GitLab From 5ad2196fc458c0f1191e329bdbe0c86d6070095e Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 12:41:50 +0200 Subject: [PATCH 17/32] removed some debug --- src/client/gkfs_libc.cpp | 47 ++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index a4b9d4009..e86c0d2ce 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -30,7 +30,7 @@ ssize_t (*real_write)(int, const void*, size_t) = NULL; // File API int dlsym_open(char* path, int flags) { - debug_info("[SYSCALL_PROXIES] [dlsym_open] >> Begin\n"); + if(real_open == NULL) { real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); @@ -38,7 +38,6 @@ dlsym_open(char* path, int flags) { int fd = real_open((char*) path, flags, 0); - debug_info("[SYSCALL_PROXIES] [dlsym_open] >> End\n"); return fd; } @@ -57,8 +56,7 @@ dlsym_open2(char* path, int flags, mode_t mode) { int dlsym_openat(int fd, char* path, int flags, mode_t mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> Begin\n"); - std::cout << "XXX" << std::endl; + if(real_openat == NULL) { real_openat = (int (*)(int, char*, int, mode_t)) dlsym(RTLD_NEXT, "openat"); @@ -66,14 +64,13 @@ dlsym_openat(int fd, char* path, int flags, mode_t mode) { int fd2 = real_openat(fd, (char*) path, flags, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_openat] >> End\n"); return fd2; } int dlsym_open64(char* path, int flags, mode_t mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> Begin\n"); + if(real_open64 == NULL) { real_open64 = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open64"); @@ -81,14 +78,13 @@ dlsym_open64(char* path, int flags, mode_t mode) { int fd = real_open64((char*) path, flags, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_open64] >> End\n"); return fd; } int dlsym___open_2(char* path, int flags) { - debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> Begin\n"); + if(real___open_2 == NULL) { real___open_2 = (int (*)(char*, int)) dlsym(RTLD_NEXT, "__open"); @@ -96,14 +92,13 @@ dlsym___open_2(char* path, int flags) { int fd = real___open_2((char*) path, flags); - debug_info("[SYSCALL_PROXIES] [dlsym___open_2] >> End\n"); return fd; } int dlsym_close(int fd) { - debug_info("[SYSCALL_PROXIES] [dlsym_close] >> Begin\n"); + if(real_close == NULL) { real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); @@ -111,7 +106,6 @@ dlsym_close(int fd) { int ret = real_close(fd); - debug_info("[SYSCALL_PROXIES] [dlsym_close] >> End\n"); return ret; } @@ -174,7 +168,7 @@ dlsym_read(int fd, void* buf, size_t nbyte) { ssize_t dlsym_write(int fd, const void* buf, size_t nbyte) { - debug_info("[SYSCALL_PROXIES] [dlsym_write] >> Begin\n"); + if(real_write == NULL) { real_write = (ssize_t(*)(int, const void*, size_t)) dlsym(RTLD_NEXT, @@ -183,7 +177,6 @@ dlsym_write(int fd, const void* buf, size_t nbyte) { ssize_t ret = real_write(fd, buf, nbyte); - debug_info("[SYSCALL_PROXIES] [dlsym_write] >> End\n"); return ret; } @@ -294,26 +287,24 @@ open64(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open64....\n"); - debug_info("[BYPASS] 1) Path => %s\n", path); - debug_info("[BYPASS] 2) flags => %d\n", flags); - debug_info("[BYPASS] 3) mode => %d\n", mode); + debug_info("[BYPASS] >> Begin open64.... %s %d %d\n", path, flags, mode); - std::string resolved; - auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); - switch(rstatus) { + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { - case gkfs::preload::RelativizeStatus::fd_not_a_dir: - return -ENOTDIR; + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; - case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_open(resolved, mode, flags); + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_open(resolved, mode, flags); - default: - // Try normal open. - break; + default: + // Try normal open. + break; + } } - debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o)\n", path, flags, mode); ret = dlsym_open64((char*) path, flags, mode); -- GitLab From 5643c60b6643fd6849416a3068ad9f7a8f3ea65a Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 13:06:15 +0200 Subject: [PATCH 18/32] Added missing interception (pread/pwrite) --- include/client/gkfs_libc.hpp | 56 +++++++ src/client/gkfs_libc.cpp | 296 ++++++++++++++++++++++++++++++++++- 2 files changed, 350 insertions(+), 2 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 54bc4f930..08d117c0c 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -208,6 +208,62 @@ mkdir(const char* path, mode_t mode); int rmdir(const char* path) noexcept; +ssize_t +pread(int fd, void* buf, size_t count, off_t offset); +ssize_t +pwrite(int fd, const void* buf, size_t count, off_t offset); +ssize_t +pread64(int fd, void* buf, size_t count, off_t offset); +ssize_t +pwrite64(int fd, const void* buf, size_t count, off_t offset); + +off_t +lseek(int fd, off_t offset, int whence); +off64_t +lseek64(int fd, off64_t offset, int whence); + +int +fstat(int fd, struct stat* buf); +int +fstat64(int fd, struct stat64* buf); +int +stat(const char* path, struct stat* buf); +int +lstat(const char* path, struct stat* buf); +int +stat64(const char* path, struct stat64* buf); +int +lstat64(const char* path, struct stat64* buf); +int +fstatat(int dfd, const char* path, struct stat* buf, int flags); +int +fstatat64(int dfd, const char* path, struct stat64* buf, int flags); + +int +rename(const char* old_path, const char* new_path); +int +unlink(const char* path); +int +remove(const char* path); + +DIR* +opendir(const char* dirname); +DIR* +opendir64(const char* dirname); +int +closedir(DIR* dirp); + +long +telldir(DIR* dirp); +void +seekdir(DIR* dirp, long loc); + +struct dirent* +readdir(DIR* dirp); +struct dirent64* +readdir64(DIR* dirp); + + /* ................................................................... */ #ifdef __cplusplus diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index e86c0d2ce..4c40a3a6a 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -211,11 +211,165 @@ dlsym_rmdir(const char* path) { return ret; } +ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_pread] >> Begin\n"); + + if(real_pread == NULL) { + real_pread = (ssize_t(*)(int, void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pread"); + } + + ssize_t ret = real_pread(fd, buf, count, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_pread] >> End\n"); + + return ret; +} + +ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_pwrite] >> Begin\n"); + + if(real_pwrite == NULL) { + real_pwrite = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pwrite"); + } + + ssize_t ret = real_pwrite(fd, buf, count, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_pwrite] >> End\n"); + + return ret; +} + +ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_pread64] >> Begin\n"); + + if(real_pread64 == NULL) { + real_pread64 = (ssize_t(*)(int, void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pread64"); + } + + ssize_t ret = real_pread64(fd, buf, count, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_pread64] >> End\n"); + + return ret; +} + +ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_pwrite64] >> Begin\n"); + + if(real_pwrite64 == NULL) { + real_pwrite64 = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pwrite64"); + } + + ssize_t ret = real_pwrite64(fd, buf, count, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_pwrite64] >> End\n"); + + return ret; +} + +int +dlsym_mkstemp(char* templates) { + debug_info("[SYSCALL_PROXIES] [dlsym_mkstemp] >> Begin\n"); + + if(real_mkstemp == NULL) { + real_mkstemp = (int (*)(char*)) dlsym(RTLD_NEXT, "mkstemp"); + } + + int ret = real_mkstemp(templates); + + debug_info("[SYSCALL_PROXIES] [dlsym_mkstemp] >> End\n"); + + return ret; +} + +off_t +dlsym_lseek(int fd, off_t offset, int whence) { + debug_info("[SYSCALL_PROXIES] [dlsym_lseek] >> Begin\n"); + + if(real_lseek == NULL) { + real_lseek = (off_t(*)(int, off_t, int)) dlsym(RTLD_NEXT, "lseek"); + } + + off_t ret = real_lseek(fd, offset, whence); + + debug_info("[SYSCALL_PROXIES] [dlsym_lseek] >> End\n"); + + return ret; +} + +off64_t +dlsym_lseek64(int fd, off64_t offset, int whence) { + debug_info("[SYSCALL_PROXIES] [dlsym_lseek64] >> Begin\n"); + + if(real_lseek64 == NULL) { + real_lseek64 = (off64_t(*)(int, off64_t, int)) dlsym(RTLD_NEXT, "lseek64"); + } + + off64_t ret = real_lseek64(fd, offset, whence); + + debug_info("[SYSCALL_PROXIES] [dlsym_lseek64] >> End\n"); + + return ret; +} + +int +dlsym_fstat(int ver, int fd, struct stat* buf) { + debug_info("[SYSCALL_PROXIES] [dlsym_fstat] >> Begin\n"); + + if(real_fstat == NULL) { + real_fstat = (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, + "fstat"); + } + + int ret = real_fstat(ver, fd, buf); + + debug_info("[SYSCALL_PROXIES] [dlsym_fstat] >> End\n"); + + return ret; +} + +int +dlsym_fxstat64(int ver, int fd, struct stat64* buf) { + debug_info("[SYSCALL_PROXIES] [dlsym_fxstat64] >> Begin\n"); + + if(real_fxstat64 == NULL) { + real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym( + RTLD_NEXT, "fxstat64"); + } + + int ret = real_fxstat64(ver, fd, buf); + + debug_info("[SYSCALL_PROXIES] [dlsym_fxstat64] >> End\n"); + + return ret; +} + +int +dlsym_stat(int ver, const char* path, struct stat* buf) { + debug_info("[SYSCALL_PROXIES] [dlsym_stat] >> Begin\n"); + + if(real_stat == NULL) { + real_stat = (int (*)(int, const char*, struct stat*)) dlsym( + RTLD_NEXT, "stat"); + } + + int ret = real_stat(ver, path, buf); + + debug_info("[SYSCALL_PROXIES] [dlsym_stat] >> End\n"); + + return ret; +} + + /* -ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset); + ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset); ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset); ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset); @@ -467,4 +621,142 @@ rmdir(const char* path) { debug_info("[BYPASS] << After rmdir....\n"); return ret; -} \ No newline at end of file +} + +// Add pread +ssize_t +pread(int fd, void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pread....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pread (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pread(fd, buf, count, offset); + + debug_info("[BYPASS] << After pread....\n"); + + return ret; +} + +// Add pwrite +ssize_t +pwrite(int fd, const void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pwrite....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pwrite (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pwrite(fd, buf, count, offset); + + debug_info("[BYPASS] << After pwrite....\n"); + + return ret; +} + +// Add mkstemp +int +mkstemp(char* templates) { + debug_info("[BYPASS] >> Begin mkstemp....\n"); + debug_info("[BYPASS] 1) templates => %s\n", templates); + + int ret = dlsym_mkstemp(templates); + + debug_info("[BYPASS] << After mkstemp....\n"); + + return ret; +} + +// Add lseek +off_t +lseek(int fd, off_t offset, int whence) { + debug_info("[BYPASS] >> Begin lseek....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_lseek(fd, offset, whence); + } + + debug_info("[BYPASS]\t dlsym_lseek (%d,%ld,%d)\n", fd, offset, whence); + + off_t ret = dlsym_lseek(fd, offset, whence); + + debug_info("[BYPASS] << After lseek....\n"); + + return ret; +} + +// Add lseek64 +off64_t +lseek64(int fd, off64_t offset, int whence) { + debug_info("[BYPASS] >> Begin lseek64....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_lseek(fd, offset, whence); + } + + debug_info("[BYPASS]\t dlsym_lseek64 (%d,%ld,%d)\n", fd, offset, whence); + + off64_t ret = dlsym_lseek64(fd, offset, whence); + + debug_info("[BYPASS] << After lseek64....\n"); + + return ret; +} + +// add pread64 +ssize_t +pread64(int fd, void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pread64....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pread64 (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pread64(fd, buf, count, offset); + + debug_info("[BYPASS] << After pread64....\n"); + + return ret; +} + +// add pwrite64 +ssize_t +pwrite64(int fd, const void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pwrite64....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pwrite64 (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pwrite64(fd, buf, count, offset); + + debug_info("[BYPASS] << After pwrite64....\n"); + + return ret; +} + -- GitLab From 57996ce736538b5c527a005bb33b5859b8fec5ca Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 13:08:32 +0200 Subject: [PATCH 19/32] missing functions variables --- src/client/gkfs_libc.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 4c40a3a6a..4304b484c 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -26,6 +26,37 @@ int (*real_mkdir)(const char*, mode_t) = NULL; int (*real_rmdir)(const char*) = NULL; ssize_t (*real_read)(int, void*, size_t) = NULL; ssize_t (*real_write)(int, const void*, size_t) = NULL; +ssize_t (*real_pread)(int, void*, size_t, off_t) = NULL; +ssize_t (*real_pwrite)(int, const void*, size_t, off_t) = NULL; +ssize_t (*real_pread64)(int, void*, size_t, off_t) = NULL; +ssize_t (*real_pwrite64)(int, const void*, size_t, off_t) = NULL; +off_t (*real_lseek)(int, off_t, int) = NULL; +off64_t (*real_lseek64)(int, off64_t, int) = NULL; +int (*real_fstat)(int, int, struct stat*) = NULL; +int (*real_fxstat64)(int, int, struct stat64*) = NULL; +int (*real_stat)(int, const char*, struct stat*) = NULL; +int (*real_lstat)(int, const char*, struct stat*) = NULL; +int (*real_stat64)(int, const char*, struct stat64*) = NULL; +int (*real_lstat64)(int, const char*, struct stat64*) = NULL; +int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; +int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; +int (*real_rename)(const char*, const char*) = NULL; +int (*real_unlink)(char*) = NULL; +int (*real_remove)(char*) = NULL; + +// Directory API +DIR* (*real_opendir)(char*) = NULL; +DIR* (*real_opendir64)(char*) = NULL; +int (*real_closedir)(DIR*) = NULL; +long (*real_telldir)(DIR*) = NULL; +void (*real_seekdir)(DIR*, long) = NULL; +struct dirent* (*real_readdir)(DIR*) = NULL; +struct dirent64* (*real_readdir64)(DIR*) = NULL; + +// Proccess API +int (*real_fork)(void) = NULL; +int (*real_pipe)(int[2]) = NULL; +int (*real_dup)(int) = NULL; // File API int -- GitLab From e9e1c837f3bb3bf6a70a822a00c686d9e60550a6 Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 13:10:47 +0200 Subject: [PATCH 20/32] missing throw --- include/client/gkfs_libc.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 08d117c0c..97ea28171 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -218,9 +218,9 @@ ssize_t pwrite64(int fd, const void* buf, size_t count, off_t offset); off_t -lseek(int fd, off_t offset, int whence); +lseek(int fd, off_t offset, int whence) __THROW; off64_t -lseek64(int fd, off64_t offset, int whence); +lseek64(int fd, off64_t offset, int whence) __THROW; int fstat(int fd, struct stat* buf); @@ -242,7 +242,7 @@ fstatat64(int dfd, const char* path, struct stat64* buf, int flags); int rename(const char* old_path, const char* new_path); int -unlink(const char* path); +unlink(const char* path) __THROW __nonnull ((1)); int remove(const char* path); -- GitLab From df5738e40681fa87e696d4fee161be118fee46b6 Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 2 Oct 2024 13:38:04 +0200 Subject: [PATCH 21/32] debug info --- src/client/gkfs_libc.cpp | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 4304b484c..805c5fcd3 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -439,7 +439,9 @@ open(const char* path, int flags, ...) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_open(resolved, mode, flags); + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + va_end(ap); + debug_info("[BYPASS] >> End open.... %s %d %d\n", path, fd); default: // Try normal open. @@ -483,7 +485,9 @@ open64(const char* path, int flags, ...) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_open(resolved, mode, flags); + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + va_end(ap); + debug_info("[BYPASS] >> End open64.... %s %d %d\n", path, fd); default: // Try normal open. @@ -602,11 +606,8 @@ read(int fd, void* buf, size_t nbyte) { return gkfs::syscall::gkfs_read(fd, buf, nbyte); } - debug_info("[BYPASS]\t dlsym_read (%d,%p,%zu)\n", fd, buf, nbyte); - ssize_t ret = dlsym_read(fd, buf, nbyte); - - debug_info("[BYPASS] << After read....\n"); + return ret; } @@ -621,12 +622,8 @@ write(int fd, void* buf, size_t nbyte) { return gkfs::syscall::gkfs_write(fd, buf, nbyte); } - debug_info("[BYPASS]\t dlsym_write (%d,%p,%zu)\n", fd, buf, nbyte); - ssize_t ret = dlsym_write(fd, buf, nbyte); - debug_info("[BYPASS] << After write....\n"); - return ret; } @@ -712,40 +709,33 @@ mkstemp(char* templates) { // Add lseek off_t lseek(int fd, off_t offset, int whence) { - debug_info("[BYPASS] >> Begin lseek....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] >> Begin lseek.... %d\n",fd); + // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[LSEEK GEKKO]....\n"); return gkfs::syscall::gkfs_lseek(fd, offset, whence); } - debug_info("[BYPASS]\t dlsym_lseek (%d,%ld,%d)\n", fd, offset, whence); - off_t ret = dlsym_lseek(fd, offset, whence); - debug_info("[BYPASS] << After lseek....\n"); - return ret; } // Add lseek64 off64_t lseek64(int fd, off64_t offset, int whence) { - debug_info("[BYPASS] >> Begin lseek64....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] >> Begin lseek64....%d\n", fd); // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[LSEEK GEKKO]....\n"); return gkfs::syscall::gkfs_lseek(fd, offset, whence); } - debug_info("[BYPASS]\t dlsym_lseek64 (%d,%ld,%d)\n", fd, offset, whence); - off64_t ret = dlsym_lseek64(fd, offset, whence); - debug_info("[BYPASS] << After lseek64....\n"); - return ret; } -- GitLab From 085fbbfc0cd13ed1271b469057779e9a947cdff8 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 3 Oct 2024 10:49:19 +0200 Subject: [PATCH 22/32] Finished missing libc calls (mkdir, pread...unlink), bypass fd protection --- include/client/gkfs_libc.hpp | 13 +- include/client/preload.hpp | 6 +- include/client/preload_context.hpp | 10 +- src/client/gkfs_libc.cpp | 272 ++++++++++++++++------------- src/client/intercept.cpp | 2 +- src/client/logging.cpp | 3 +- src/client/open_file_map.cpp | 44 +++-- src/client/preload_context.cpp | 16 +- 8 files changed, 212 insertions(+), 154 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 97ea28171..d0cf5c3dd 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -17,6 +17,17 @@ * You should have received a copy of the GNU Lesser General Public License * along with Expand. If not, see . * + * Modifications to support GekkoFS done by : + * Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany + * + * This software was partially supported by the + * EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + * + * This software was partially supported by the + * ADA-FS project under the SPPEXA project funded by the DFG. + * + * SPDX-License-Identifier: LGPL-3.0-or-later */ @@ -242,7 +253,7 @@ fstatat64(int dfd, const char* path, struct stat64* buf, int flags); int rename(const char* old_path, const char* new_path); int -unlink(const char* path) __THROW __nonnull ((1)); +unlink(const char* path) __THROW __nonnull((1)); int remove(const char* path); diff --git a/include/client/preload.hpp b/include/client/preload.hpp index 17e951cff..f7d35206a 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -48,9 +48,11 @@ init_preload() __attribute__((constructor)); void destroy_preload() __attribute__((destructor)); #else -void init_libc() __attribute__((constructor)); +void +init_libc() __attribute__((constructor)); -void destroy_libc() __attribute__((destructor)); +void +destroy_libc() __attribute__((destructor)); #endif diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index 3d2a16976..ef3c4da2b 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -128,7 +128,11 @@ private: std::bitset protected_fds_; std::string hostname; int replicas_; +#ifdef BYPASS_SYSCALL bool protect_fds_{false}; +#else + bool protect_fds_{true}; +#endif std::shared_ptr write_metrics_; std::shared_ptr read_metrics_; @@ -302,9 +306,11 @@ public: int get_replicas(); - bool protect_fds() const; + bool + protect_fds() const; - void protect_fds(bool protect); + void + protect_fds(bool protect); const std::shared_ptr write_metrics(); diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 805c5fcd3..97c2a8e68 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -1,3 +1,35 @@ +/* + * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, + * Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra + * + * This file is part of Expand. + * + * Expand is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Expand is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Expand. If not, see . + * + * Modifications to support GekkoFS done by : + * Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany + * + * This software was partially supported by the + * EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + * + * This software was partially supported by the + * ADA-FS project under the SPPEXA project funded by the DFG. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + #include #include #include @@ -8,6 +40,7 @@ #include #include #include +#include #define debug_info printf // #define debug_info(...) @@ -41,7 +74,7 @@ int (*real_lstat64)(int, const char*, struct stat64*) = NULL; int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; int (*real_rename)(const char*, const char*) = NULL; -int (*real_unlink)(char*) = NULL; +int (*real_unlink)(const char*) = NULL; int (*real_remove)(char*) = NULL; // Directory API @@ -143,46 +176,34 @@ dlsym_close(int fd) { int dlsym_close_range(unsigned int low, unsigned int high, int flags) { - debug_info("[SYSCALL_PROXIES] [dlsym_close_range] >> Begin\n"); - if(real_close_range == NULL) { real_close_range = (int (*)(unsigned int, unsigned int, int)) dlsym( RTLD_NEXT, "close_range"); } int ret = real_close_range(low, high, flags); - - debug_info("[SYSCALL_PROXIES] [dlsym_close_range] >> End\n"); - return ret; } int dlsym_creat(const char* path, mode_t mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_creat] >> Begin\n"); - if(real_creat == NULL) { real_creat = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "creat"); } int fd = real_creat((char*) path, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_creat] >> End\n"); - return fd; } int dlsym_ftruncate(int fd, off_t length) { - debug_info("[SYSCALL_PROXIES] [dlsym_ftruncate] >> Begin\n"); - if(real_ftruncate == NULL) { real_ftruncate = (int (*)(int, off_t)) dlsym(RTLD_NEXT, "ftruncate"); } int ret = real_ftruncate(fd, length); - return ret; } @@ -214,7 +235,6 @@ dlsym_write(int fd, const void* buf, size_t nbyte) { int dlsym_mkdir(const char* path, mode_t mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_mkdir] >> Begin\n"); if(real_mkdir == NULL) { real_mkdir = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "mkdir"); @@ -222,14 +242,11 @@ dlsym_mkdir(const char* path, mode_t mode) { int ret = real_mkdir(path, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_mkdir] >> End\n"); - return ret; } int dlsym_rmdir(const char* path) { - debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> Begin\n"); if(real_rmdir == NULL) { real_rmdir = (int (*)(const char*)) dlsym(RTLD_NEXT, "rmdir"); @@ -237,29 +254,23 @@ dlsym_rmdir(const char* path) { int ret = real_rmdir(path); - debug_info("[SYSCALL_PROXIES] [dlsym_rmdir] >> End\n"); - return ret; } -ssize_t dlsym_pread (int fd, void *buf, size_t count, off_t offset) { - debug_info("[SYSCALL_PROXIES] [dlsym_pread] >> Begin\n"); - +ssize_t +dlsym_pread(int fd, void* buf, size_t count, off_t offset) { if(real_pread == NULL) { - real_pread = (ssize_t(*)(int, void*, size_t, off_t)) dlsym( - RTLD_NEXT, "pread"); + real_pread = (ssize_t(*)(int, void*, size_t, off_t)) dlsym(RTLD_NEXT, + "pread"); } ssize_t ret = real_pread(fd, buf, count, offset); - debug_info("[SYSCALL_PROXIES] [dlsym_pread] >> End\n"); - return ret; } -ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset) { - debug_info("[SYSCALL_PROXIES] [dlsym_pwrite] >> Begin\n"); - +ssize_t +dlsym_pwrite(int fd, const void* buf, size_t count, off_t offset) { if(real_pwrite == NULL) { real_pwrite = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( RTLD_NEXT, "pwrite"); @@ -267,28 +278,24 @@ ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset) { ssize_t ret = real_pwrite(fd, buf, count, offset); - debug_info("[SYSCALL_PROXIES] [dlsym_pwrite] >> End\n"); - return ret; } -ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset) { - debug_info("[SYSCALL_PROXIES] [dlsym_pread64] >> Begin\n"); +ssize_t +dlsym_pread64(int fd, void* buf, size_t count, off_t offset) { if(real_pread64 == NULL) { - real_pread64 = (ssize_t(*)(int, void*, size_t, off_t)) dlsym( - RTLD_NEXT, "pread64"); + real_pread64 = (ssize_t(*)(int, void*, size_t, off_t)) dlsym(RTLD_NEXT, + "pread64"); } ssize_t ret = real_pread64(fd, buf, count, offset); - debug_info("[SYSCALL_PROXIES] [dlsym_pread64] >> End\n"); - return ret; } -ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset) { - debug_info("[SYSCALL_PROXIES] [dlsym_pwrite64] >> Begin\n"); +ssize_t +dlsym_pwrite64(int fd, const void* buf, size_t count, off_t offset) { if(real_pwrite64 == NULL) { real_pwrite64 = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( @@ -297,14 +304,11 @@ ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset) { ssize_t ret = real_pwrite64(fd, buf, count, offset); - debug_info("[SYSCALL_PROXIES] [dlsym_pwrite64] >> End\n"); - return ret; } int dlsym_mkstemp(char* templates) { - debug_info("[SYSCALL_PROXIES] [dlsym_mkstemp] >> Begin\n"); if(real_mkstemp == NULL) { real_mkstemp = (int (*)(char*)) dlsym(RTLD_NEXT, "mkstemp"); @@ -312,14 +316,11 @@ dlsym_mkstemp(char* templates) { int ret = real_mkstemp(templates); - debug_info("[SYSCALL_PROXIES] [dlsym_mkstemp] >> End\n"); - return ret; } off_t dlsym_lseek(int fd, off_t offset, int whence) { - debug_info("[SYSCALL_PROXIES] [dlsym_lseek] >> Begin\n"); if(real_lseek == NULL) { real_lseek = (off_t(*)(int, off_t, int)) dlsym(RTLD_NEXT, "lseek"); @@ -327,91 +328,71 @@ dlsym_lseek(int fd, off_t offset, int whence) { off_t ret = real_lseek(fd, offset, whence); - debug_info("[SYSCALL_PROXIES] [dlsym_lseek] >> End\n"); - return ret; } off64_t dlsym_lseek64(int fd, off64_t offset, int whence) { - debug_info("[SYSCALL_PROXIES] [dlsym_lseek64] >> Begin\n"); if(real_lseek64 == NULL) { - real_lseek64 = (off64_t(*)(int, off64_t, int)) dlsym(RTLD_NEXT, "lseek64"); + real_lseek64 = + (off64_t(*)(int, off64_t, int)) dlsym(RTLD_NEXT, "lseek64"); } off64_t ret = real_lseek64(fd, offset, whence); - debug_info("[SYSCALL_PROXIES] [dlsym_lseek64] >> End\n"); - return ret; } int dlsym_fstat(int ver, int fd, struct stat* buf) { - debug_info("[SYSCALL_PROXIES] [dlsym_fstat] >> Begin\n"); - if(real_fstat == NULL) { - real_fstat = (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, - "fstat"); + real_fstat = + (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, "fstat"); } int ret = real_fstat(ver, fd, buf); - debug_info("[SYSCALL_PROXIES] [dlsym_fstat] >> End\n"); - return ret; } int dlsym_fxstat64(int ver, int fd, struct stat64* buf) { - debug_info("[SYSCALL_PROXIES] [dlsym_fxstat64] >> Begin\n"); if(real_fxstat64 == NULL) { - real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym( - RTLD_NEXT, "fxstat64"); + real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym(RTLD_NEXT, + "fxstat64"); } int ret = real_fxstat64(ver, fd, buf); - debug_info("[SYSCALL_PROXIES] [dlsym_fxstat64] >> End\n"); - return ret; } int dlsym_stat(int ver, const char* path, struct stat* buf) { - debug_info("[SYSCALL_PROXIES] [dlsym_stat] >> Begin\n"); if(real_stat == NULL) { - real_stat = (int (*)(int, const char*, struct stat*)) dlsym( - RTLD_NEXT, "stat"); + real_stat = (int (*)(int, const char*, struct stat*)) dlsym(RTLD_NEXT, + "stat"); } int ret = real_stat(ver, path, buf); - debug_info("[SYSCALL_PROXIES] [dlsym_stat] >> End\n"); - return ret; } +// generate unlink +int +dlsym_unlink(const char* path) { + if(real_unlink == NULL) { + real_unlink = (int (*)(const char*)) dlsym(RTLD_NEXT, "unlink"); + } + int ret = real_unlink(path); -/* - - - -ssize_t dlsym_pwrite (int fd, const void *buf, size_t count, off_t offset); -ssize_t dlsym_pread64 (int fd, void *buf, size_t count, off_t offset); -ssize_t dlsym_pwrite64 (int fd, const void *buf, size_t count, off_t offset); -int dlsym_mkstemp (char *templates); - - - -off_t dlsym_lseek (int fd, off_t offset, int whence); -off64_t dlsym_lseek64 (int fd, off64_t offset, int whence); - -*/ + return ret; +} // File API @@ -425,7 +406,7 @@ open(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open.... %s %d %d\n", path, flags, mode); + debug_info("[BYPASS] >> Begin open.... %s %o %o\n", path, flags, mode); // We have a infinite loop, with logging as it is initialized an issues an // open that gets intercepted here. Maybe we need a variable to stop this @@ -441,8 +422,8 @@ open(const char* path, int flags, ...) { case gkfs::preload::RelativizeStatus::internal: fd = gkfs::syscall::gkfs_open(resolved, mode, flags); va_end(ap); - debug_info("[BYPASS] >> End open.... %s %d %d\n", path, fd); - + debug_info("[BYPASS] >> End open.... %s %d\n", path, fd); + return fd; default: // Try normal open. break; @@ -454,8 +435,6 @@ open(const char* path, int flags, ...) { debug_info("[BYPASS]\t dlsym_open (%s,%o,%o) -> %d\n", path, flags, mode, ret); - - va_end(ap); debug_info("[BYPASS] << After open....\n"); @@ -474,7 +453,7 @@ open64(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open64.... %s %d %d\n", path, flags, mode); + debug_info("[BYPASS] >> Begin open64.... %s %o %o\n", path, flags, mode); if(CTX->interception_enabled()) { std::string resolved; @@ -487,8 +466,8 @@ open64(const char* path, int flags, ...) { case gkfs::preload::RelativizeStatus::internal: fd = gkfs::syscall::gkfs_open(resolved, mode, flags); va_end(ap); - debug_info("[BYPASS] >> End open64.... %s %d %d\n", path, fd); - + debug_info("[BYPASS] >> End open64.... %s %d\n", path, fd); + return fd; default: // Try normal open. break; @@ -553,9 +532,7 @@ close_range(unsigned low, unsigned high, int flags) { int creat(const char* path, mode_t mode) { - debug_info("[BYPASS] >> Begin creat....\n"); - debug_info("[BYPASS] 1) path => %s\n", path); - debug_info("[BYPASS] 2) mode => %d\n", mode); + debug_info("[BYPASS] >> Begin creat....%s %o\n", path, mode); // Is path from gekkofs? std::string resolved; @@ -585,9 +562,7 @@ creat(const char* path, mode_t mode) { int ftruncate(int fd, off_t length) { - debug_info("[BYPASS] >> Begin ftruncate....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); - debug_info("[BYPASS] 2) length => %ld\n", length); + debug_info("[BYPASS] >> Begin ftruncate.... %d %ld\n", fd, length); int ret = dlsym_ftruncate(fd, length); @@ -598,8 +573,6 @@ ftruncate(int fd, off_t length) { ssize_t read(int fd, void* buf, size_t nbyte) { - debug_info("[BYPASS] >> Begin read....%d - %ld\n", fd, nbyte); - // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { debug_info("[READ from GKFS]....%d \n", fd); @@ -607,16 +580,13 @@ read(int fd, void* buf, size_t nbyte) { } ssize_t ret = dlsym_read(fd, buf, nbyte); - + return ret; } ssize_t write(int fd, void* buf, size_t nbyte) { - debug_info("[BYPASS] >> Begin write....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); - // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { return gkfs::syscall::gkfs_write(fd, buf, nbyte); @@ -627,35 +597,56 @@ write(int fd, void* buf, size_t nbyte) { return ret; } +// add mkdir int mkdir(const char* path, mode_t mode) { - debug_info("[BYPASS] >> Begin mkdir....\n"); - debug_info("[BYPASS] 1) path => %s\n", path); + debug_info("[BYPASS] >> Begin mkdir....%s\n", path); + int ret = 0; + // if path is inside gekkofs + if(CTX->interception_enabled()) { + std::string resolved; - int ret = dlsym_mkdir(path, mode); + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + ret = gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR); + debug_info("[BYPASS] >> End mkdir.... %s\n", path); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_mkdir(path, mode); debug_info("[BYPASS] << After mkdir....\n"); return ret; } +// add rmdir int rmdir(const char* path) { - debug_info("[BYPASS] >> Begin rmdir....\n"); - debug_info("[BYPASS] 1) path => %s\n", path); + debug_info("[BYPASS] >> Begin rmdir.... %s\n", path); - int ret = dlsym_rmdir(path); + return unlink(path); + /* int ret = dlsym_rmdir(path); + */ + // debug_info("[BYPASS] << After rmdir....\n"); - debug_info("[BYPASS] << After rmdir....\n"); - - return ret; + // return ret; } + // Add pread ssize_t pread(int fd, void* buf, size_t count, off_t offset) { - debug_info("[BYPASS] >> Begin pread....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] >> Begin pread....%d\n", fd); // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { @@ -675,8 +666,7 @@ pread(int fd, void* buf, size_t count, off_t offset) { // Add pwrite ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) { - debug_info("[BYPASS] >> Begin pwrite....\n"); - debug_info("[BYPASS] 1) fd => %d\n", fd); + debug_info("[BYPASS] >> Begin pwrite....%d\n", fd); // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { @@ -709,8 +699,8 @@ mkstemp(char* templates) { // Add lseek off_t lseek(int fd, off_t offset, int whence) { - debug_info("[BYPASS] >> Begin lseek.... %d\n",fd); - + debug_info("[BYPASS] >> Begin lseek.... %d\n", fd); + // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { @@ -781,3 +771,51 @@ pwrite64(int fd, const void* buf, size_t count, off_t offset) { return ret; } + +// add fstat +int +fstat(int fd, struct stat* buf) { + debug_info("[BYPASS] >> Begin fstat....%d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); + } + + int ret = dlsym_fstat(0, fd, buf); + + debug_info("[BYPASS] << After fstat....\n"); + + return ret; +} + +int +unlink(const char* path) { + debug_info("[BYPASS] >> Begin unlink....%s\n", path); + int ret = 0; + // if path is inside gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + ret = gkfs::syscall::gkfs_remove(resolved); + debug_info("[BYPASS] >> End unlink.... %s\n", path); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_unlink(path); + + debug_info("[BYPASS] << After unlink....\n"); + + return ret; +} \ No newline at end of file diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index e70d61aac..9993c1780 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -510,7 +510,7 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, if(CTX->file_map()->exist(i)) { gkfs::syscall::gkfs_close(i); } - *result = 0; + *result = 0; } *result = 0; break; diff --git a/src/client/logging.cpp b/src/client/logging.cpp index 1276ef88b..830d5691e 100644 --- a/src/client/logging.cpp +++ b/src/client/logging.cpp @@ -317,8 +317,7 @@ logger::logger(const std::string& opts, const std::string& path, // because we want the call to be intercepted by our hooks, which // allows us to categorize the resulting fd as 'internal' and // relocate it to our private range - //int fd = ::open(file_path.c_str(), flags, 0600); - int fd = ::syscall_no_intercept(SYS_open,file_path.c_str(), flags, 0600); + int fd = ::open(file_path.c_str(), flags, 0600); if(fd == -1) { log(gkfs::log::error, __func__, __LINE__, diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 627f4521f..d9334002d 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -133,31 +133,29 @@ OpenFileMap::exist(const int fd) { int OpenFileMap::safe_generate_fd_idx_() { int fd = 0; - - if (CTX->protect_fds()) { - fd = generate_fd_idx(); - /* - * Check if fd is still in use and generate another if yes - * Note that this can only happen once the all fd indices within the int has - * been used to the int::max Once this limit is exceeded, we set fd_idx back - * to 3 and begin anew. Only then, if a file was open for a long time will - * we have to generate another index. - * - * This situation can only occur when all fd indices have been given away - * once and we start again, in which case the fd_validation_needed flag is - * set. fd_validation is set to false, if - */ - if(fd_validation_needed) { - while(exist(fd)) { - fd = generate_fd_idx(); + + if(CTX->protect_fds()) { + fd = generate_fd_idx(); + /* + * Check if fd is still in use and generate another if yes + * Note that this can only happen once the all fd indices within the int + * has been used to the int::max Once this limit is exceeded, we set + * fd_idx back to 3 and begin anew. Only then, if a file was open for a + * long time will we have to generate another index. + * + * This situation can only occur when all fd indices have been given + * away once and we start again, in which case the fd_validation_needed + * flag is set. fd_validation is set to false, if + */ + if(fd_validation_needed) { + while(exist(fd)) { + fd = generate_fd_idx(); + } } + } else { + fd = syscall_no_intercept(SYS_open, "/dev/null", O_RDWR, + S_IRUSR | S_IWUSR); } - } - else { - fd = syscall_no_intercept( - SYS_open, "/dev/null", - O_RDWR, S_IRUSR | S_IWUSR); - } return fd; } diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index 4b028d676..b0707f8aa 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -469,11 +469,13 @@ PreloadContext::interception_enabled() const { return interception_enabled_; } -bool PreloadContext::protect_fds() const { +bool +PreloadContext::protect_fds() const { return protect_fds_; -}; +} -void PreloadContext::protect_fds(bool protect) { +void +PreloadContext::protect_fds(bool protect) { protect_fds_ = protect; } @@ -481,7 +483,8 @@ int PreloadContext::register_internal_fd(int fd) { assert(fd >= 0); - if (!protect_fds()) return fd; + if(!protect_fds()) + return fd; if(!internal_fds_must_relocate_) { LOG(DEBUG, "registering fd {} as internal (no relocation needed)", fd); assert(fd >= MIN_INTERNAL_FD); @@ -549,8 +552,9 @@ PreloadContext::register_internal_fd(int fd) { void PreloadContext::unregister_internal_fd(int fd) { - if (!protect_fds()) return; - + if(!protect_fds()) + return; + LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, fd >= MIN_INTERNAL_FD); -- GitLab From 4a8b0849421bd30391e1fbe1c568d76b7cd6c58b Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 3 Oct 2024 12:18:04 +0200 Subject: [PATCH 23/32] add GSL --- src/client/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 303fd772d..94ca9cba9 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -158,6 +158,7 @@ target_link_libraries( hermes fmt::fmt Threads::Threads + Microsoft.GSL::GSL ) -- GitLab From 9804649f7ca0f9c9ee1a27d97d864c8f8b38952f Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 3 Oct 2024 12:34:01 +0200 Subject: [PATCH 24/32] restores noexecstack --- src/client/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 94ca9cba9..31c84cd30 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -111,7 +111,7 @@ target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL) target_link_options(gkfs_user_lib PRIVATE -z noexecstack) target_compile_definitions(gkfs_libc_intercept PUBLIC BYPASS_SYSCALL) -target_link_options(gkfs_libc_intercept PRIVATE) #-z noexecstack +target_link_options(gkfs_libc_intercept PRIVATE -z noexecstack) if (GKFS_ENABLE_AGIOS) target_compile_definitions(gkfs_intercept PUBLIC GKFS_ENABLE_AGIOS) -- GitLab From c11c4549011192bf40e0ae982be34f568aff46dc Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 3 Oct 2024 12:45:21 +0200 Subject: [PATCH 25/32] Avoids the constructor with ENABLE INIT with the user library --- include/client/preload.hpp | 3 +-- src/client/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/client/preload.hpp b/include/client/preload.hpp index f7d35206a..ff685d919 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -47,13 +47,12 @@ init_preload() __attribute__((constructor)); void destroy_preload() __attribute__((destructor)); -#else +#elif ENABLE_INIT void init_libc() __attribute__((constructor)); void destroy_libc() __attribute__((destructor)); - #endif #endif // IOINTERCEPT_PRELOAD_HPP diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 31c84cd30..62d6fb17a 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -110,7 +110,7 @@ target_sources( target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL) target_link_options(gkfs_user_lib PRIVATE -z noexecstack) -target_compile_definitions(gkfs_libc_intercept PUBLIC BYPASS_SYSCALL) +target_compile_definitions(gkfs_libc_intercept PUBLIC BYPASS_SYSCALL ENABLE_INIT) target_link_options(gkfs_libc_intercept PRIVATE -z noexecstack) if (GKFS_ENABLE_AGIOS) -- GitLab From 4e693614705351a07efea43ae47f9c82f6b840d4 Mon Sep 17 00:00:00 2001 From: rnou Date: Wed, 9 Oct 2024 14:33:06 +0200 Subject: [PATCH 26/32] adding more stubs --- include/client/gkfs_libc.hpp | 4 +- src/client/gkfs_libc.cpp | 100 ++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index d0cf5c3dd..ed11a5cd6 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -218,7 +218,9 @@ mkdir(const char* path, mode_t mode); int rmdir(const char* path) noexcept; - +int dup(int oldfd) __THROW __wur; + int dup2(int oldfd, int newfd) __THROW; + int dup3(int oldfd, int newfd, int flags) __THROW; ssize_t pread(int fd, void* buf, size_t count, off_t offset); ssize_t diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 97c2a8e68..f86a1f4b9 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -43,7 +43,7 @@ #include #define debug_info printf -// #define debug_info(...) +//#define debug_info(...) thread_local std::atomic reentrant = false; int (*real_open)(char*, int, mode_t) = NULL; @@ -406,11 +406,6 @@ open(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open.... %s %o %o\n", path, flags, mode); - - // We have a infinite loop, with logging as it is initialized an issues an - // open that gets intercepted here. Maybe we need a variable to stop this - // internal loops? or bypass with tmp. if(CTX->interception_enabled()) { std::string resolved; auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); @@ -429,15 +424,10 @@ open(const char* path, int flags, ...) { break; } } - debug_info("[BYPASS]\t dlsym_open (%s,%o,%o)\n", path, flags, mode); ret = dlsym_open2((char*) path, flags, mode); - - debug_info("[BYPASS]\t dlsym_open (%s,%o,%o) -> %d\n", path, flags, mode, - ret); va_end(ap); - debug_info("[BYPASS] << After open....\n"); return ret; } @@ -453,8 +443,6 @@ open64(const char* path, int flags, ...) { mode = va_arg(ap, mode_t); - debug_info("[BYPASS] >> Begin open64.... %s %o %o\n", path, flags, mode); - if(CTX->interception_enabled()) { std::string resolved; auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); @@ -473,18 +461,10 @@ open64(const char* path, int flags, ...) { break; } } - debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o)\n", path, flags, mode); - ret = dlsym_open64((char*) path, flags, mode); - debug_info("[BYPASS]\t dlsym_open64 (%s,%o,%o) -> %d\n", path, flags, mode, - ret); - - va_end(ap); - debug_info("[BYPASS] << After open64....\n"); - return ret; } @@ -497,13 +477,9 @@ close(int fd) { return gkfs::syscall::gkfs_close(fd); } - debug_info("[BYPASS]\t dlsym_close (%d)\n", fd); - // Try normal close. auto ret = dlsym_close(fd); - debug_info("[BYPASS]\t dlsym_close (%d) -> %d\n", fd, ret); - return ret; } @@ -575,7 +551,7 @@ ssize_t read(int fd, void* buf, size_t nbyte) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[READ from GKFS]....%d \n", fd); + debug_info("[READ from GKFS]....%d %ld\n", fd, nbyte); return gkfs::syscall::gkfs_read(fd, buf, nbyte); } @@ -586,10 +562,11 @@ read(int fd, void* buf, size_t nbyte) { } ssize_t -write(int fd, void* buf, size_t nbyte) { +write(int fd, const void* buf, size_t nbyte) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - return gkfs::syscall::gkfs_write(fd, buf, nbyte); + debug_info("[WRITE from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_write(fd, buf, nbyte); } ssize_t ret = dlsym_write(fd, buf, nbyte); @@ -624,7 +601,6 @@ mkdir(const char* path, mode_t mode) { ret = dlsym_mkdir(path, mode); - debug_info("[BYPASS] << After mkdir....\n"); return ret; } @@ -637,7 +613,6 @@ rmdir(const char* path) { return unlink(path); /* int ret = dlsym_rmdir(path); */ - // debug_info("[BYPASS] << After rmdir....\n"); // return ret; } @@ -650,6 +625,7 @@ pread(int fd, void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[PREAD from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pread(fd, buf, count, offset); } @@ -670,6 +646,7 @@ pwrite(int fd, const void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[PWRITE from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); } @@ -699,12 +676,10 @@ mkstemp(char* templates) { // Add lseek off_t lseek(int fd, off_t offset, int whence) { - debug_info("[BYPASS] >> Begin lseek.... %d\n", fd); - // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[LSEEK GEKKO]....\n"); + debug_info("[xLSEEK GEKKO]....%ld %d\n", offset, whence); return gkfs::syscall::gkfs_lseek(fd, offset, whence); } @@ -716,11 +691,9 @@ lseek(int fd, off_t offset, int whence) { // Add lseek64 off64_t lseek64(int fd, off64_t offset, int whence) { - debug_info("[BYPASS] >> Begin lseek64....%d\n", fd); - // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[LSEEK GEKKO]....\n"); + debug_info("[LSEEK64 GEKKO]... %d.%ld %d\n",fd, offset, whence); return gkfs::syscall::gkfs_lseek(fd, offset, whence); } @@ -737,7 +710,8 @@ pread64(int fd, void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + debug_info("[PREAD64 from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); } debug_info("[BYPASS]\t dlsym_pread64 (%d,%p,%zu,%ld)\n", fd, buf, count, @@ -758,6 +732,7 @@ pwrite64(int fd, const void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[PWRITE64 from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); } @@ -779,6 +754,7 @@ fstat(int fd, struct stat* buf) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { + debug_info("[FSTAT from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } @@ -818,4 +794,52 @@ unlink(const char* path) { debug_info("[BYPASS] << After unlink....\n"); return ret; -} \ No newline at end of file +} + +int dup(int oldfd){ +debug_info("DUP %d\n", oldfd); +return oldfd; +} + +int dup2(int oldfd, int newfd){ +debug_info("DUP2 %d %d\n", oldfd, newfd); +return oldfd; +} + +int dup3(int oldfd, int newfd, int flags){ +debug_info("DUP3 %d %d\n", oldfd, newfd); +return oldfd; +} + +int stat(const char *pathname, struct stat *statbuf) { +debug_info("STAT %s\n", pathname); +} +int lstat(const char *pathname, struct stat *statbuf){ + debug_info("LSTAT %s\n", pathname); +} + + +int fstatat(int dirfd, const char *pathname, struct stat *statbuf, + int flags){ +debug_info("FSTATAT %s\n", pathname); +} + + +int +fstat64(int fd, struct stat64* buf) { +} + +int +stat64(const char* path, struct stat64* buf){ +} +int +lstat64(const char* path, struct stat64* buf){ +} +int +fstatat(int dfd, const char* path, struct stat* buf, int flags){ +} +int +fstatat64(int dfd, const char* path, struct stat64* buf, int flags) +{ + +} -- GitLab From 88dd2844e2e75e049754d972eb8376e6a757e60c Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 9 Oct 2024 14:42:46 +0200 Subject: [PATCH 27/32] stat functions --- src/client/gkfs_libc.cpp | 285 +++++++++++++++++++++++++++++++++------ 1 file changed, 246 insertions(+), 39 deletions(-) diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index f86a1f4b9..d5dc569cb 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -43,7 +43,7 @@ #include #define debug_info printf -//#define debug_info(...) +// #define debug_info(...) thread_local std::atomic reentrant = false; int (*real_open)(char*, int, mode_t) = NULL; @@ -381,6 +381,103 @@ dlsym_stat(int ver, const char* path, struct stat* buf) { return ret; } +/* Add missing functions +int (*real_lstat)(int, const char*, struct stat*) = NULL; +int (*real_stat64)(int, const char*, struct stat64*) = NULL; +int (*real_lstat64)(int, const char*, struct stat64*) = NULL; +int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; +int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; +*/ + +int +dlsym_lstat(int ver, const char* path, struct stat* buf) { + if(real_lstat == NULL) { + real_lstat = (int (*)(int, const char*, struct stat*)) dlsym(RTLD_NEXT, + "lstat"); + } + + int ret = real_lstat(ver, path, buf); + + return ret; +} + +int +dlsym_stat64(int ver, const char* path, struct stat64* buf) { + + if(real_stat64 == NULL) { + real_stat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "stat64"); + } + + int ret = real_stat64(ver, path, buf); + + return ret; +} + +int +dlsym_lstat64(int ver, const char* path, struct stat64* buf) { + + if(real_lstat64 == NULL) { + real_lstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "lstat64"); + } + + int ret = real_lstat64(ver, path, buf); + + return ret; +} + +int +dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags) { + + if(real_fstatat == NULL) { + real_fstatat = (int (*)(int, const char*, struct stat*, int)) dlsym( + RTLD_NEXT, "fstatat"); + } + + int ret = real_fstatat(dfd, path, buf, flags); + + return ret; +} + +int +dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags) { + + if(real_fstatat64 == NULL) { + real_fstatat64 = (int (*)(int, const char*, struct stat64*, int)) dlsym( + RTLD_NEXT, "fstatat64"); + } + + int ret = real_fstatat64(dfd, path, buf, flags); + + return ret; +} + +int +dlsym_rename(const char* oldpath, const char* newpath) { + + if(real_rename == NULL) { + real_rename = + (int (*)(const char*, const char*)) dlsym(RTLD_NEXT, "rename"); + } + + int ret = real_rename(oldpath, newpath); + + return ret; +} + +// generate remove +int +dlsym_remove(char* path) { + if(real_remove == NULL) { + real_remove = (int (*)(char*)) dlsym(RTLD_NEXT, "remove"); + } + + int ret = real_remove(path); + + return ret; +} + // generate unlink int @@ -565,8 +662,8 @@ ssize_t write(int fd, const void* buf, size_t nbyte) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[WRITE from GKFS]....%d \n", fd); - return gkfs::syscall::gkfs_write(fd, buf, nbyte); + debug_info("[WRITE from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_write(fd, buf, nbyte); } ssize_t ret = dlsym_write(fd, buf, nbyte); @@ -625,7 +722,7 @@ pread(int fd, void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[PREAD from GKFS]....%d \n", fd); + debug_info("[PREAD from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pread(fd, buf, count, offset); } @@ -646,7 +743,7 @@ pwrite(int fd, const void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[PWRITE from GKFS]....%d \n", fd); + debug_info("[PWRITE from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); } @@ -693,7 +790,7 @@ off64_t lseek64(int fd, off64_t offset, int whence) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[LSEEK64 GEKKO]... %d.%ld %d\n",fd, offset, whence); + debug_info("[LSEEK64 GEKKO]... %d.%ld %d\n", fd, offset, whence); return gkfs::syscall::gkfs_lseek(fd, offset, whence); } @@ -710,8 +807,8 @@ pread64(int fd, void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[PREAD64 from GKFS]....%d \n", fd); - return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + debug_info("[PREAD64 from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); } debug_info("[BYPASS]\t dlsym_pread64 (%d,%p,%zu,%ld)\n", fd, buf, count, @@ -732,7 +829,7 @@ pwrite64(int fd, const void* buf, size_t count, off_t offset) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[PWRITE64 from GKFS]....%d \n", fd); + debug_info("[PWRITE64 from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); } @@ -754,7 +851,7 @@ fstat(int fd, struct stat* buf) { // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { - debug_info("[FSTAT from GKFS]....%d \n", fd); + debug_info("[FSTAT from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } @@ -796,50 +893,160 @@ unlink(const char* path) { return ret; } -int dup(int oldfd){ -debug_info("DUP %d\n", oldfd); -return oldfd; +int +dup(int oldfd) { + debug_info("DUP %d\n", oldfd); + return oldfd; } -int dup2(int oldfd, int newfd){ -debug_info("DUP2 %d %d\n", oldfd, newfd); -return oldfd; +int +dup2(int oldfd, int newfd) { + debug_info("DUP2 %d %d\n", oldfd, newfd); + return oldfd; } -int dup3(int oldfd, int newfd, int flags){ -debug_info("DUP3 %d %d\n", oldfd, newfd); -return oldfd; +int +dup3(int oldfd, int newfd, int flags) { + debug_info("DUP3 %d %d\n", oldfd, newfd); + return oldfd; } -int stat(const char *pathname, struct stat *statbuf) { -debug_info("STAT %s\n", pathname); -} -int lstat(const char *pathname, struct stat *statbuf){ - debug_info("LSTAT %s\n", pathname); -} +// fill missing stat functions +int +stat(const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin stat....%s\n", path); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; -int fstatat(int dirfd, const char *pathname, struct stat *statbuf, - int flags){ -debug_info("FSTATAT %s\n", pathname); -} + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; -int -fstat64(int fd, struct stat64* buf) { -} + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_stat(resolved, buf); -int -stat64(const char* path, struct stat64* buf){ + default: + // Try normal open. + break; + } + } + + int ret = dlsym_stat(0, path, buf); + + debug_info("[BYPASS] << After stat....\n"); + + return ret; } + int -lstat64(const char* path, struct stat64* buf){ +lstat(const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin lstat....%s\n", path); + + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } + + int ret = dlsym_lstat(0, path, buf); + + debug_info("[BYPASS] << After lstat....\n"); + + return ret; } + int -fstatat(int dfd, const char* path, struct stat* buf, int flags){ +fstatat(int dfd, const char* path, struct stat* buf, int flags) { + debug_info("[BYPASS] >> Begin fstatat....%s\n", path); + + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(dfd, path, resolved, flags); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::fd_unknown: + return -EBADF; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } + + int ret = dlsym_fstatat(dfd, path, buf, flags); + + debug_info("[BYPASS] << After fstatat....\n"); + + return ret; } + int -fstatat64(int dfd, const char* path, struct stat64* buf, int flags) -{ +rename(const char* oldpath, const char* newpath) { + debug_info("[BYPASS] >> Begin rename....%s %s\n", oldpath, newpath); -} + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved_old; + std::string resolved_new; + + auto rstatus_old = + CTX->relativize_fd_path(AT_FDCWD, oldpath, resolved_old); + auto rstatus_new = + CTX->relativize_fd_path(AT_FDCWD, newpath, resolved_new); + + switch(rstatus_old) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + switch(rstatus_new) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_rename(resolved_old, + resolved_new); + + default: + // Try normal open. + break; + } + default: + // Try normal open. + break; + } + } + + int ret = dlsym_rename(oldpath, newpath); + + debug_info("[BYPASS] << After rename....\n"); + + return ret; +} \ No newline at end of file -- GitLab From 55ec48209920654aafe9ea4ed3444f680335c2a4 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 10 Oct 2024 13:55:38 +0200 Subject: [PATCH 28/32] more functions --- include/client/gkfs_libc.hpp | 18 +- include/client/user_functions.hpp | 9 + src/client/gkfs_libc.cpp | 659 +++++++++++++++++++++++++++--- 3 files changed, 624 insertions(+), 62 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index ed11a5cd6..3052d96a6 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -84,17 +84,17 @@ off64_t dlsym_lseek64(int fd, off64_t offset, int whence); int -dlsym_fstat(int ver, int fd, struct stat* buf); +dlsym_fstat(int fd, struct stat* buf); int -dlsym_fxstat64(int ver, int fd, struct stat64* buf); +dlsym_fxstat64(int fd, struct stat64* buf); int -dlsym_stat(int ver, const char* path, struct stat* buf); +dlsym_stat(const char* path, struct stat* buf); int -dlsym_lstat(int ver, const char* path, struct stat* buf); +dlsym_lstat(const char* path, struct stat* buf); int -dlsym_lxstat64(int ver, const char* path, struct stat64* buf); +dlsym_lxstat64( const char* path, struct stat64* buf); int -dlsym_xstat64(int ver, const char* path, struct stat64* buf); +dlsym_xstat64( const char* path, struct stat64* buf); int dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags); int @@ -189,6 +189,12 @@ dlsym_fsync(int fd); int dlsym_flock(int fd, int operation); + // Manager API + +char *dlsym_realpath (const char * path, char * resolved_path); + + + // Memory API void* diff --git a/include/client/user_functions.hpp b/include/client/user_functions.hpp index 5f96ab3c1..dca3da867 100644 --- a/include/client/user_functions.hpp +++ b/include/client/user_functions.hpp @@ -76,6 +76,15 @@ gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); int gkfs_remove(const std::string& path); +int +gkfs_dup(const int oldfd); + +int +gkfs_dup2(const int oldfd, const int newfd); + +int +gkfs_access(const std::string& path, const int mask, bool follow_links); + std::vector gkfs_get_file_list(const std::string& path); } // namespace syscall diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index d5dc569cb..c37da61bc 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -65,12 +65,12 @@ ssize_t (*real_pread64)(int, void*, size_t, off_t) = NULL; ssize_t (*real_pwrite64)(int, const void*, size_t, off_t) = NULL; off_t (*real_lseek)(int, off_t, int) = NULL; off64_t (*real_lseek64)(int, off64_t, int) = NULL; -int (*real_fstat)(int, int, struct stat*) = NULL; -int (*real_fxstat64)(int, int, struct stat64*) = NULL; -int (*real_stat)(int, const char*, struct stat*) = NULL; -int (*real_lstat)(int, const char*, struct stat*) = NULL; -int (*real_stat64)(int, const char*, struct stat64*) = NULL; -int (*real_lstat64)(int, const char*, struct stat64*) = NULL; +int (*real_fstat)(int, struct stat*) = NULL; +int (*real_fxstat64)(int, struct stat64*) = NULL; +int (*real_stat)(const char*, struct stat*) = NULL; +int (*real_lstat)(const char*, struct stat*) = NULL; +int (*real_stat64)(const char*, struct stat64*) = NULL; +int (*real_lstat64)(const char*, struct stat64*) = NULL; int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; int (*real_rename)(const char*, const char*) = NULL; @@ -88,10 +88,22 @@ struct dirent64* (*real_readdir64)(DIR*) = NULL; // Proccess API int (*real_fork)(void) = NULL; -int (*real_pipe)(int[2]) = NULL; +int (*real_pipe)(int*) = NULL; int (*real_dup)(int) = NULL; +int (*real_dup2)(int, int) = NULL; +void (*real_exit)(int) = NULL; +int (*real_chdir)(char*) = NULL; +int (*real_chmod)(char*, mode_t) = NULL; +int (*real_fchmod)(int, mode_t) = NULL; +int (*real_chown)(char*, uid_t, gid_t) = NULL; +int (*real_fcntl)(int, int, long) = NULL; +int (*real_access)(const char*, int) = NULL; +char* (*real_realpath)(const char*, char*) = NULL; +int (*real_fsync)(int) = NULL; +int (*real_flock)(int, int) = NULL; +void* (*real_mmap)(void*, size_t, int, int, int, off_t) = NULL; + -// File API int dlsym_open(char* path, int flags) { @@ -345,39 +357,38 @@ dlsym_lseek64(int fd, off64_t offset, int whence) { } int -dlsym_fstat(int ver, int fd, struct stat* buf) { +dlsym_fstat(int fd, struct stat* buf) { if(real_fstat == NULL) { - real_fstat = - (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, "fstat"); + real_fstat = (int (*)(int, struct stat*)) dlsym(RTLD_NEXT, "fstat"); } - int ret = real_fstat(ver, fd, buf); + int ret = real_fstat(fd, buf); return ret; } int -dlsym_fxstat64(int ver, int fd, struct stat64* buf) { +dlsym_fxstat64(int fd, struct stat64* buf) { if(real_fxstat64 == NULL) { - real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym(RTLD_NEXT, - "fxstat64"); + real_fxstat64 = + (int (*)(int, struct stat64*)) dlsym(RTLD_NEXT, "fxstat64"); } - int ret = real_fxstat64(ver, fd, buf); + int ret = real_fxstat64(fd, buf); return ret; } int -dlsym_stat(int ver, const char* path, struct stat* buf) { +dlsym_stat(const char* path, struct stat* buf) { if(real_stat == NULL) { - real_stat = (int (*)(int, const char*, struct stat*)) dlsym(RTLD_NEXT, - "stat"); + real_stat = + (int (*)(const char*, struct stat*)) dlsym(RTLD_NEXT, "stat"); } - int ret = real_stat(ver, path, buf); + int ret = real_stat(path, buf); return ret; } @@ -390,39 +401,38 @@ int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; */ int -dlsym_lstat(int ver, const char* path, struct stat* buf) { +dlsym_lstat(const char* path, struct stat* buf) { if(real_lstat == NULL) { - real_lstat = (int (*)(int, const char*, struct stat*)) dlsym(RTLD_NEXT, - "lstat"); + real_lstat = + (int (*)(const char*, struct stat*)) dlsym(RTLD_NEXT, "lstat"); } - int ret = real_lstat(ver, path, buf); - + int ret = real_lstat(path, buf); return ret; } int -dlsym_stat64(int ver, const char* path, struct stat64* buf) { +dlsym_stat64(const char* path, struct stat64* buf) { if(real_stat64 == NULL) { - real_stat64 = (int (*)(int, const char*, struct stat64*)) dlsym( - RTLD_NEXT, "stat64"); + real_stat64 = (int (*)(const char*, struct stat64*)) dlsym(RTLD_NEXT, + "stat64"); } - int ret = real_stat64(ver, path, buf); + int ret = real_stat64(path, buf); return ret; } int -dlsym_lstat64(int ver, const char* path, struct stat64* buf) { +dlsym_lstat64(const char* path, struct stat64* buf) { if(real_lstat64 == NULL) { - real_lstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( - RTLD_NEXT, "lstat64"); + real_lstat64 = (int (*)(const char*, struct stat64*)) dlsym(RTLD_NEXT, + "lstat64"); } - int ret = real_lstat64(ver, path, buf); + int ret = real_lstat64(path, buf); return ret; } @@ -492,6 +502,236 @@ dlsym_unlink(const char* path) { } +// Proccess API +int +dlsym_fork(void) { + debug_info("[SYSCALL_PROXIES] [dlsym_fork] >> Begin\n"); + + if(real_fork == NULL) { + real_fork = (int (*)()) dlsym(RTLD_NEXT, "fork"); + } + + int ret = real_fork(); + + debug_info("[SYSCALL_PROXIES] [dlsym_fork] >> End\n"); + + return ret; +} + +int +dlsym_pipe(int pipefd[2]) { + debug_info("[SYSCALL_PROXIES] [dlsym_pipe] >> Begin\n"); + + if(real_pipe == NULL) { + real_pipe = (int (*)(int*)) dlsym(RTLD_NEXT, "pipe"); + } + + int ret = real_pipe(pipefd); + + debug_info("[SYSCALL_PROXIES] [dlsym_pipe] >> End\n"); + + return ret; +} + +int +dlsym_dup(int fd) { + debug_info("[SYSCALL_PROXIES] [dlsym_dup] >> Begin\n"); + + if(real_dup == NULL) { + real_dup = (int (*)(int)) dlsym(RTLD_NEXT, "dup"); + } + + int ret = real_dup(fd); + + debug_info("[SYSCALL_PROXIES] [dlsym_dup] >> End\n"); + + return ret; +} + +int +dlsym_dup2(int fd, int fd2) { + debug_info("[SYSCALL_PROXIES] [dlsym_dup2] >> Begin\n"); + + if(real_dup2 == NULL) { + real_dup2 = (int (*)(int, int)) dlsym(RTLD_NEXT, "dup2"); + } + + int ret = real_dup2(fd, fd2); + + debug_info("[SYSCALL_PROXIES] [dlsym_dup2] >> End\n"); + + return ret; +} + +void +dlsym_exit(int status) { + debug_info("[SYSCALL_PROXIES] [dlsym_exit] >> Begin\n"); + + if(real_exit == NULL) { + real_exit = (void (*)(int)) dlsym(RTLD_NEXT, "exit"); + } + + real_exit(status); + + debug_info("[SYSCALL_PROXIES] [dlsym_exit] >> End\n"); +} + +// File/Directory Metadata API +int +dlsym_chdir(char* path) { + debug_info("[SYSCALL_PROXIES] [dlsym_chdir] >> Begin\n"); + + if(real_chdir == NULL) { + real_chdir = (int (*)(char*)) dlsym(RTLD_NEXT, "chdir"); + } + + int ret = real_chdir((char*) path); + + debug_info("[SYSCALL_PROXIES] [dlsym_chdir] >> End\n"); + + return ret; +} + +int +dlsym_chmod(char* path, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_chmod] >> Begin\n"); + + if(real_chmod == NULL) { + real_chmod = (int (*)(char*, mode_t)) dlsym(RTLD_NEXT, "chmod"); + } + + int ret = real_chmod((char*) path, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_chmod] >> End\n"); + + return ret; +} + +int +dlsym_fchmod(int fd, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_fchmod] >> Begin\n"); + + if(real_fchmod == NULL) { + real_fchmod = (int (*)(int, mode_t)) dlsym(RTLD_NEXT, "fchmod"); + } + + int ret = real_fchmod(fd, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_fchmod] >> End\n"); + + return ret; +} + +int +dlsym_chown(char* path, uid_t owner, gid_t group) { + debug_info("[SYSCALL_PROXIES] [dlsym_chown] >> Begin\n"); + + if(real_chown == NULL) { + real_chown = (int (*)(char*, uid_t, gid_t)) dlsym(RTLD_NEXT, "chown"); + } + + int ret = real_chown((char*) path, owner, group); + + debug_info("[SYSCALL_PROXIES] [dlsym_chown] >> End\n"); + + return ret; +} + +int +dlsym_fcntl(int fd, int cmd, long arg) { + debug_info("[SYSCALL_PROXIES] [dlsym_fcntl] >> Begin\n"); + + if(real_fcntl == NULL) { + real_fcntl = (int (*)(int, int, long)) dlsym(RTLD_NEXT, "fcntl"); + } + + int ret = real_fcntl(fd, cmd, arg); + + debug_info("[SYSCALL_PROXIES] [dlsym_fcntl] >> End\n"); + + return ret; +} + +int +dlsym_access(const char* path, int mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_access] >> Begin\n"); + + if(real_access == NULL) { + real_access = (int (*)(const char*, int)) dlsym(RTLD_NEXT, "access"); + } + + int ret = real_access((char*) path, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_access] >> End\n"); + + return ret; +} + +char* +dlsym_realpath(const char* path, char* resolved_path) { + debug_info("[SYSCALL_PROXIES] [dlsym_realpath] >> Begin\n"); + + if(real_realpath == NULL) { + real_realpath = + (char* (*) (const char*, char*) ) dlsym(RTLD_NEXT, "realpath"); + } + + char* ret = real_realpath((char*) path, (char*) resolved_path); + + debug_info("[SYSCALL_PROXIES] [dlsym_realpath] >> End\n"); + + return ret; +} + +int +dlsym_fsync(int fd) { + debug_info("[SYSCALL_PROXIES] [dlsym_fsync] >> Begin\n"); + + if(real_fsync == NULL) { + real_fsync = (int (*)(int)) dlsym(RTLD_NEXT, "fsync"); + } + + int ret = real_fsync(fd); + + debug_info("[SYSCALL_PROXIES] [dlsym_fsync] >> End\n"); + + return ret; +} + +int +dlsym_flock(int fd, int operation) { + debug_info("[SYSCALL_PROXIES] [dlsym_flock] >> Begin\n"); + + if(real_flock == NULL) { + real_flock = (int (*)(int, int)) dlsym(RTLD_NEXT, "fsync"); + } + + int ret = real_flock(fd, operation); + + debug_info("[SYSCALL_PROXIES] [dlsym_flock] >> End\n"); + + return ret; +} + +// Memory API +void* +dlsym_mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_mmap] >> Begin\n"); + + if(real_mmap == NULL) { + real_mmap = (void* (*) (void*, size_t, int, int, int, off_t)) dlsym( + RTLD_NEXT, "mmap"); + } + + void* ret = real_mmap(addr, length, prot, flags, fd, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_mmap] >> End\n"); + + return ret; +} + + // File API int open(const char* path, int flags, ...) { @@ -855,7 +1095,7 @@ fstat(int fd, struct stat* buf) { return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); } - int ret = dlsym_fstat(0, fd, buf); + int ret = dlsym_fstat(fd, buf); debug_info("[BYPASS] << After fstat....\n"); @@ -893,24 +1133,6 @@ unlink(const char* path) { return ret; } -int -dup(int oldfd) { - debug_info("DUP %d\n", oldfd); - return oldfd; -} - -int -dup2(int oldfd, int newfd) { - debug_info("DUP2 %d %d\n", oldfd, newfd); - return oldfd; -} - -int -dup3(int oldfd, int newfd, int flags) { - debug_info("DUP3 %d %d\n", oldfd, newfd); - return oldfd; -} - // fill missing stat functions int stat(const char* path, struct stat* buf) { @@ -935,7 +1157,7 @@ stat(const char* path, struct stat* buf) { } } - int ret = dlsym_stat(0, path, buf); + int ret = dlsym_stat(path, buf); debug_info("[BYPASS] << After stat....\n"); @@ -965,7 +1187,7 @@ lstat(const char* path, struct stat* buf) { } } - int ret = dlsym_lstat(0, path, buf); + int ret = dlsym_lstat(path, buf); debug_info("[BYPASS] << After lstat....\n"); @@ -1031,8 +1253,10 @@ rename(const char* oldpath, const char* newpath) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_rename(resolved_old, - resolved_new); + return -ENOTDIR; + // return + // gkfs::syscall::gkfs_rename(resolved_old, + // resolved_new); default: // Try normal open. @@ -1048,5 +1272,328 @@ rename(const char* oldpath, const char* newpath) { debug_info("[BYPASS] << After rename....\n"); + return ret; +} + +pid_t +fork(void) { + int ret = -1; + + debug_info("[BYPASS] >> Begin fork()\n"); + + ret = dlsym_fork(); + if(0 == ret) { + // We want the children to be initialized + if(CTX->interception_enabled()) { + debug_info("Interception enabled in child\n"); + } + } + + debug_info("[BYPASS] << After fork()\n"); + + return ret; +} + +int +pipe(int pipefd[2]) { + debug_info("[BYPASS] >> Begin pipe() %d - %d\n", pipefd[0], pipefd[1]); + + int ret = dlsym_pipe(pipefd); + + debug_info("[BYPASS]\t dlsym_pipe -> %d\n", ret); + + + return ret; +} + +int +dup(int fd) { + debug_info("[BYPASS] >> Begin dup... %d\n", fd); + + int ret = -1; + // check if fd is from gekkofs + if(CTX->file_map()->exist(fd)) { + + ret = gkfs::syscall::gkfs_dup(fd); + debug_info("[dup from GKFS]....%d -> %d \n", fd, ret); + return ret; + } + + // call the real dup function + ret = dlsym_dup(fd); + + debug_info("[BYPASS] << After dup()\n"); + + return ret; +} + +int +dup2(int fd, int fd2) { + debug_info("[BYPASS] >> Begin dup2...%d -> %d\n", fd, fd2); + + int ret = -1; + // check if fd is from gekkofs + if(CTX->file_map()->exist(fd)) { + ret = gkfs::syscall::gkfs_dup2(fd, fd2); + debug_info("[dup2 from GKFS]....%d -> %d \n", fd, fd2); + return ret; + } + + // call the real dup2 function + ret = dlsym_dup2(fd, fd2); + + debug_info("[BYPASS] << After dup2()\n"); + + + return ret; +} + +void +exit(int status) { + debug_info("[BYPASS] >> Begin exit...\n"); + debug_info("[BYPASS] 1) status %d\n", status); + + + debug_info("[BYPASS] dlsym_exit\n"); + + dlsym_exit(status); + __builtin_unreachable(); + + debug_info("[BYPASS] << After exit()\n"); +} + +// Manager API + +int +chdir(const char* path) { + debug_info("[BYPASS] >> Begin chdir...\n"); + debug_info("[BYPASS] 1) path %s\n", path); + + int ret = -1; + + // is the path from gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return -ENOTDIR; + + default: + // Try normal open. + break; + } + } + + // call the real chdir function + ret = dlsym_chdir((char*) path); + + debug_info("[BYPASS] << After chdir()\n"); + + return ret; +} + + +int +fcntl(int fd, int cmd, long arg) // TODO +{ + debug_info("[BYPASS] >> Begin fcntl... %d , %d ,%ld\n", fd, cmd, arg); + + int ret = -1; + + + // is from gekkofs? + if(CTX->file_map()->exist(fd)) { + switch(cmd) { + + case F_DUPFD: + debug_info("dupfd\n"); + + return gkfs::syscall::gkfs_dup(fd); + + case F_DUPFD_CLOEXEC: + debug_info("dupfd_cloexec\n"); + + ret = gkfs::syscall::gkfs_dup(fd); + if(ret == -1) { + return -errno; + } + CTX->file_map()->get(fd)->set_flag( + gkfs::filemap::OpenFile_flags::cloexec, true); + return ret; + + case F_GETFD: + debug_info("getfd\n"); + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::cloexec)) { + return FD_CLOEXEC; + } + return 0; + + case F_GETFL: + debug_info("getfl\n"); + ret = 0; + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::rdonly)) { + ret |= O_RDONLY; + } + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::wronly)) { + ret |= O_WRONLY; + } + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::rdwr)) { + ret |= O_RDWR; + } + return ret; + + case F_SETFD: + debug_info("setfd\n"); + CTX->file_map()->get(fd)->set_flag( + gkfs::filemap::OpenFile_flags::cloexec, + (arg & FD_CLOEXEC)); + return 0; + + case F_GETLK: + + return 0; + + case F_SETLK: + + return 0; + + default: + + return -ENOTSUP; + } + } + + // call the real fcntl function + ret = dlsym_fcntl(fd, cmd, arg); + debug_info("[BYPASS] << After fcntl()\n"); + + return ret; +} + +int +access(const char* path, int mode) { + struct stat64 stats; + + debug_info("[BYPASS] >> Begin access...\n"); + debug_info("[BYPASS] 1) path %s\n", path); + debug_info("[BYPASS] 2) mode %d\n", mode); + + int ret = -1; + + // is gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return -ENOTDIR; + + default: + debug_info("[GekkoFS Access] \n"); + auto ret = gkfs::syscall::gkfs_access(resolved, mode, true); + break; + } + } + + // call the real access function + ret = dlsym_access((char*) path, mode); + + debug_info("[BYPASS] << After access()\n"); + + return ret; + + return ret; +} + +char* +realpath(const char* path, char* resolved_path) { + debug_info("[BYPASS] >> Begin realpath...\n"); + debug_info("[BYPASS] 1) Path %s\n", path); + // is gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return nullptr; + + case gkfs::preload::RelativizeStatus::internal: + return nullptr; + + default: + + strcpy(resolved_path, resolved.c_str()); + return resolved_path; + } + } + + // call the real realpath function + char* ret = dlsym_realpath((char*) path, resolved_path); + + debug_info("[BYPASS] << After realpath()\n"); + + return ret; +} + +char* +__realpath_chk(const char* path, char* resolved_path, + __attribute__((__unused__)) size_t resolved_len) { + debug_info("[BYPASS] >> Begin __realpath_chk...\n"); + debug_info("[BYPASS] 1) Path %s\n", path); + + + debug_info("[BYPASS] Begin dlsym_realpath...\n"); + + return dlsym_realpath(path, resolved_path); +} + +int +fsync(int fd) // TODO +{ + debug_info("[BYPASS] >> Begin fsync...\n"); + debug_info("[BYPASS] 1) fd %d\n", fd); + int ret; + + ret = dlsym_fsync(fd); + + debug_info("[BYPASS]\t dlsym_fsync -> %d\n", ret); + + + return ret; +} + +int +flock(int fd, int operation) { + int ret = -1; + + debug_info("[BYPASS] >> Begin flock...\n"); + debug_info("[BYPASS] * fd=%d\n", fd); + debug_info("[BYPASS] * operation=%d\n", operation); + + + debug_info("[BYPASS]\t try to dlsym_flock %d,%d\n", fd, operation); + + ret = dlsym_flock(fd, operation); + + + debug_info("[BYPASS] << After flock...\n"); + return ret; } \ No newline at end of file -- GitLab From 6cb55c85fd262aba2dbc8e5fd028daedf736e986 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 10 Oct 2024 13:57:53 +0200 Subject: [PATCH 29/32] format --- include/client/gkfs_libc.hpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 3052d96a6..7a58ce410 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -92,9 +92,9 @@ dlsym_stat(const char* path, struct stat* buf); int dlsym_lstat(const char* path, struct stat* buf); int -dlsym_lxstat64( const char* path, struct stat64* buf); +dlsym_lxstat64(const char* path, struct stat64* buf); int -dlsym_xstat64( const char* path, struct stat64* buf); +dlsym_xstat64(const char* path, struct stat64* buf); int dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags); int @@ -189,11 +189,10 @@ dlsym_fsync(int fd); int dlsym_flock(int fd, int operation); - // Manager API - -char *dlsym_realpath (const char * path, char * resolved_path); - +// Manager API +char* +dlsym_realpath(const char* path, char* resolved_path); // Memory API @@ -224,9 +223,12 @@ mkdir(const char* path, mode_t mode); int rmdir(const char* path) noexcept; -int dup(int oldfd) __THROW __wur; - int dup2(int oldfd, int newfd) __THROW; - int dup3(int oldfd, int newfd, int flags) __THROW; +int +dup(int oldfd) __THROW __wur; +int +dup2(int oldfd, int newfd) __THROW; +int +dup3(int oldfd, int newfd, int flags) __THROW; ssize_t pread(int fd, void* buf, size_t count, off_t offset); ssize_t -- GitLab From a838bf5f212639ebec6c62a2ea704e2da61aa550 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 10 Oct 2024 14:38:40 +0200 Subject: [PATCH 30/32] add openat --- include/client/gkfs_libc.hpp | 4 ++++ src/client/gkfs_libc.cpp | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 7a58ce410..31dbac275 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -204,6 +204,10 @@ int open64(const char* path, int flags, ...); int open(const char* path, int flags, ...); +//openat +int openat (int __fd, const char *__file, int __oflag, ...); + + int close(int fd); int diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index c37da61bc..c74ed6e67 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -805,6 +805,44 @@ open64(const char* path, int flags, ...) { return ret; } +int +openat(int dirfd, const char* path, int flags, ...) { + + int ret, fd; + va_list ap; + mode_t mode = 0; + + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + va_end(ap); + debug_info("[BYPASS] >> End open.... %s %d\n", path, fd); + return fd; + default: + // Try normal open. + break; + } + } + + ret = dlsym_openat(dirfd, (char*) path, flags, mode); + va_end(ap); + + + return ret; +} + + // Generate the rest of the functions to build a libc io interception int close(int fd) { -- GitLab From 173742fb7fc124a1e984541794e9046d38881c02 Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Wed, 23 Oct 2024 18:12:58 +0200 Subject: [PATCH 31/32] added readdir (WIP) --- include/client/gkfs_libc.hpp | 77 ++- include/client/preload.hpp | 1 + include/client/user_functions.hpp | 19 + src/client/gkfs_functions.cpp | 8 +- src/client/gkfs_libc.cpp | 976 ++++++++++++++++++++++++++---- src/client/open_file_map.cpp | 4 + 6 files changed, 950 insertions(+), 135 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index 31dbac275..af29c8f06 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -40,6 +40,29 @@ extern "C" { #include #include #include +#include + +#include +#include + + +#ifndef _STAT_VER +#define _STAT_VER 0 +#endif + +struct __dirstream + { + int fd; // File descriptor. + //__libc_lock_define (, lock) // Mutex lock for this structure. //TODO + size_t allocation; // Space allocated for the block. + size_t size; // Total valid data in the block. + size_t offset; // Current offset into the block. + off_t filepos; // Position of next entry to read. + // Directory block. + char data[0] __attribute__ ((aligned (__alignof__ (void*)))); + + char * path; + }; // File API @@ -84,22 +107,25 @@ off64_t dlsym_lseek64(int fd, off64_t offset, int whence); int -dlsym_fstat(int fd, struct stat* buf); +dlsym_fstat(int ver, int fd, struct stat* buf); int -dlsym_fxstat64(int fd, struct stat64* buf); +dlsym_fxstat64(int ver, int fd, struct stat64* buf); int -dlsym_stat(const char* path, struct stat* buf); +dlsym_stat(int ver, const char* path, struct stat* buf); int -dlsym_lstat(const char* path, struct stat* buf); +dlsym_lstat(int ver, const char* path, struct stat* buf); int -dlsym_lxstat64(const char* path, struct stat64* buf); +dlsym_lxstat64(int ver, const char* path, struct stat64* buf); int -dlsym_xstat64(const char* path, struct stat64* buf); +dlsym_xstat64(int ver, const char* path, struct stat64* buf); int dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags); int dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags); +int +dlsym_statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* buf); int dlsym_rename(const char* old_path, const char* new_path); int @@ -204,8 +230,13 @@ int open64(const char* path, int flags, ...); int open(const char* path, int flags, ...); -//openat -int openat (int __fd, const char *__file, int __oflag, ...); +// openat +int +openat(int __fd, const char* __file, int __oflag, ...); + + +int +openat64(int dirfd, const char* path, int flags, ...); int @@ -246,6 +277,12 @@ off_t lseek(int fd, off_t offset, int whence) __THROW; off64_t lseek64(int fd, off64_t offset, int whence) __THROW; +// statvfs + +int +statvfs(const char* path, struct statvfs* buf); +int +fstatvfs(int fd, struct statvfs* buf); int fstat(int fd, struct stat* buf); @@ -253,17 +290,28 @@ int fstat64(int fd, struct stat64* buf); int stat(const char* path, struct stat* buf); + + int -lstat(const char* path, struct stat* buf); +__xstat(int ver, const char* path, struct stat* buf); int -stat64(const char* path, struct stat64* buf); +__xstat64(int ver, const char* path, struct stat64* buf); int -lstat64(const char* path, struct stat64* buf); +__fxstat64(int ver, const char* path, struct stat64* buf); int -fstatat(int dfd, const char* path, struct stat* buf, int flags); +__lxstat(int ver, const char* path, struct stat* buf); int -fstatat64(int dfd, const char* path, struct stat64* buf, int flags); +__lxstat64(int ver, const char* path, struct stat64* buf); +int +__fxstat(int ver, int fd, struct stat* buf); +int +__fxstatat(int ver, int dfd, const char* path, struct stat* buf, int flags); +int +__fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, int flags); +int +statx(int dirfd, const char* pathname, int flags, unsigned int mask, + struct statx* statxbuf); int rename(const char* old_path, const char* new_path); int @@ -288,6 +336,9 @@ readdir(DIR* dirp); struct dirent64* readdir64(DIR* dirp); +int +clone(int (*fn)(void*), void* stack, int flags, void* arg, ...); +/* pid_t *parent_tid, void *tls, pid_t *child_tid */ /* ................................................................... */ diff --git a/include/client/preload.hpp b/include/client/preload.hpp index ff685d919..6bc965beb 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -37,6 +37,7 @@ #define CTX gkfs::preload::PreloadContext::getInstance() namespace gkfs::preload { +void init_environment(); void init_ld_env_if_needed(); } // namespace gkfs::preload diff --git a/include/client/user_functions.hpp b/include/client/user_functions.hpp index dca3da867..d753a1022 100644 --- a/include/client/user_functions.hpp +++ b/include/client/user_functions.hpp @@ -38,6 +38,7 @@ extern "C" { #include } +struct linux_dirent; struct linux_dirent64; namespace gkfs { @@ -73,6 +74,10 @@ gkfs_pread(int fd, void* buf, size_t count, off64_t offset); int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); +int +gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, + struct statx* buf, bool follow_links = true); + int gkfs_remove(const std::string& path); @@ -87,6 +92,20 @@ gkfs_access(const std::string& path, const int mask, bool follow_links); std::vector gkfs_get_file_list(const std::string& path); + + +int +gkfs_opendir(const std::string& path); + +int +gkfs_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count); + +int +gkfs_getdents64(unsigned int fd, struct linux_dirent64* dirp, + unsigned int count); + + + } // namespace syscall namespace malleable { diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index 438afbe69..0e50c83ee 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -65,9 +65,15 @@ using namespace std; * kernel: fs/readdir.c. */ struct linux_dirent { +#ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; +#else + uint64_t d_ino; + int64_t d_off; +#endif unsigned short d_reclen; + unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* @@ -1489,7 +1495,7 @@ gkfs_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count) { current_dirp->d_reclen = total_size; - *(reinterpret_cast(current_dirp) + total_size - 1) = + current_dirp->d_type = ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG : DT_DIR); diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index c74ed6e67..658c4280a 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -41,7 +41,10 @@ #include #include #include - +#include +#include +std::atomic activated{false}; +std::atomic initializing{false}; #define debug_info printf // #define debug_info(...) @@ -65,17 +68,19 @@ ssize_t (*real_pread64)(int, void*, size_t, off_t) = NULL; ssize_t (*real_pwrite64)(int, const void*, size_t, off_t) = NULL; off_t (*real_lseek)(int, off_t, int) = NULL; off64_t (*real_lseek64)(int, off64_t, int) = NULL; -int (*real_fstat)(int, struct stat*) = NULL; -int (*real_fxstat64)(int, struct stat64*) = NULL; -int (*real_stat)(const char*, struct stat*) = NULL; -int (*real_lstat)(const char*, struct stat*) = NULL; -int (*real_stat64)(const char*, struct stat64*) = NULL; -int (*real_lstat64)(const char*, struct stat64*) = NULL; +int (*real_stat)(int, char*, struct stat*) = NULL; +int (*real_xstat64)(int, const char*, struct stat64*) = NULL; +int (*real_lstat)(int, char*, struct stat*) = NULL; +int (*real_lxstat64)(int, const char*, struct stat64*) = NULL; +int (*real_fstat)(int, int, struct stat*) = NULL; +int (*real_fxstat64)(int, int, struct stat64*) = NULL; int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; + int (*real_rename)(const char*, const char*) = NULL; int (*real_unlink)(const char*) = NULL; int (*real_remove)(char*) = NULL; +int (*real_statx)(int, const char*, int, unsigned int, struct statx*) = NULL; // Directory API DIR* (*real_opendir)(char*) = NULL; @@ -102,8 +107,23 @@ char* (*real_realpath)(const char*, char*) = NULL; int (*real_fsync)(int) = NULL; int (*real_flock)(int, int) = NULL; void* (*real_mmap)(void*, size_t, int, int, int, off_t) = NULL; +int (*real_clone)(int(void*), void*, int, void*, pid_t*, void*, pid_t*) = NULL; - +void +initializeGekko() { + // if the activated is false call init + // Create a global mutex + /* + if(!activated and !initializing) { + debug_info("[BYPASS] >> DEACTIVATED GEKKOFS.... \n"); + initializing = true; + init_libc(); + activated = true; + initializing = false; + debug_info("[BYPASS] >> ACTIVATED GEKKOFS.... \n"); + } + */ +} int dlsym_open(char* path, int flags) { @@ -357,82 +377,91 @@ dlsym_lseek64(int fd, off64_t offset, int whence) { } int -dlsym_fstat(int fd, struct stat* buf) { - if(real_fstat == NULL) { - real_fstat = (int (*)(int, struct stat*)) dlsym(RTLD_NEXT, "fstat"); +dlsym_lxstat64(int ver, const char* path, struct stat64* buf) { + + + if(real_lxstat64 == NULL) { + real_lxstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "__lxstat64"); } - int ret = real_fstat(fd, buf); + int ret = real_lxstat64(ver, (char*) path, buf); + return ret; } int -dlsym_fxstat64(int fd, struct stat64* buf) { +dlsym_xstat64(int ver, const char* path, struct stat64* buf) { - if(real_fxstat64 == NULL) { - real_fxstat64 = - (int (*)(int, struct stat64*)) dlsym(RTLD_NEXT, "fxstat64"); + + if(real_xstat64 == NULL) { + real_xstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "__xstat64"); } - int ret = real_fxstat64(fd, buf); + int ret = real_xstat64(ver, (char*) path, buf); + return ret; } int -dlsym_stat(const char* path, struct stat* buf) { +dlsym_fxstat64(int ver, int fd, struct stat64* buf) { - if(real_stat == NULL) { - real_stat = - (int (*)(const char*, struct stat*)) dlsym(RTLD_NEXT, "stat"); + + if(real_fxstat64 == NULL) { + real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym(RTLD_NEXT, + "__fxstat64"); } - int ret = real_stat(path, buf); + int ret = real_fxstat64(ver, fd, buf); + return ret; } -/* Add missing functions -int (*real_lstat)(int, const char*, struct stat*) = NULL; -int (*real_stat64)(int, const char*, struct stat64*) = NULL; -int (*real_lstat64)(int, const char*, struct stat64*) = NULL; -int (*real_fstatat)(int, const char*, struct stat*, int) = NULL; -int (*real_fstatat64)(int, const char*, struct stat64*, int) = NULL; -*/ int -dlsym_lstat(const char* path, struct stat* buf) { +dlsym_lstat(int ver, const char* path, struct stat* buf) { + + if(real_lstat == NULL) { - real_lstat = - (int (*)(const char*, struct stat*)) dlsym(RTLD_NEXT, "lstat"); + real_lstat = (int (*)(int, char*, struct stat*)) dlsym(RTLD_NEXT, + "__lxstat"); } - int ret = real_lstat(path, buf); + int ret = real_lstat(ver, (char*) path, buf); + + return ret; } int -dlsym_stat64(const char* path, struct stat64* buf) { +dlsym_stat(int ver, const char* path, struct stat* buf) { - if(real_stat64 == NULL) { - real_stat64 = (int (*)(const char*, struct stat64*)) dlsym(RTLD_NEXT, - "stat64"); + + if(real_stat == NULL) { + real_stat = + (int (*)(int, char*, struct stat*)) dlsym(RTLD_NEXT, "__xstat"); } - int ret = real_stat64(path, buf); + int ret = real_stat(ver, (char*) path, buf); + return ret; } int -dlsym_lstat64(const char* path, struct stat64* buf) { +dlsym_fstat(int ver, int fd, struct stat* buf) { + - if(real_lstat64 == NULL) { - real_lstat64 = (int (*)(const char*, struct stat64*)) dlsym(RTLD_NEXT, - "lstat64"); + if(real_fstat == NULL) { + real_fstat = + (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, "__fxstat"); } - int ret = real_lstat64(path, buf); + int ret = real_fstat(ver, fd, buf); + return ret; } @@ -440,12 +469,14 @@ dlsym_lstat64(const char* path, struct stat64* buf) { int dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags) { + if(real_fstatat == NULL) { real_fstatat = (int (*)(int, const char*, struct stat*, int)) dlsym( RTLD_NEXT, "fstatat"); } - int ret = real_fstatat(dfd, path, buf, flags); + int ret = real_fstatat(dfd, (char*) path, buf, flags); + return ret; } @@ -453,16 +484,29 @@ dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags) { int dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags) { + if(real_fstatat64 == NULL) { real_fstatat64 = (int (*)(int, const char*, struct stat64*, int)) dlsym( RTLD_NEXT, "fstatat64"); } - int ret = real_fstatat64(dfd, path, buf, flags); + int ret = real_fstatat64(dfd, (char*) path, buf, flags); + return ret; } +int +dlsym_statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* buf) { + if(real_statx == NULL) { + real_statx = (int (*)(int, const char*, int, unsigned int, + struct statx*)) dlsym(RTLD_NEXT, "statx"); + } + int ret = real_statx(dirfd, path, flags, mask, buf); + return ret; +} + int dlsym_rename(const char* oldpath, const char* newpath) { @@ -501,6 +545,94 @@ dlsym_unlink(const char* path) { return ret; } +// opendir +// Directory API +DIR* +dlsym_opendir(char* dirname) { + + if(real_opendir == NULL) { + real_opendir = (DIR * (*) (char*) ) dlsym(RTLD_NEXT, "opendir"); + } + + DIR* ret = real_opendir((char*) dirname); + + return ret; +} + +DIR* +dlsym_opendir64(char* dirname) { + + + if(real_opendir64 == NULL) { + real_opendir64 = (DIR * (*) (char*) ) dlsym(RTLD_NEXT, "opendir64"); + } + + DIR* ret = real_opendir64((char*) dirname); + + + return ret; +} + +// readdir +struct dirent* +dlsym_readdir(DIR* dirp) { + + if(real_readdir == NULL) { + real_readdir = + (struct dirent * (*) (DIR*) ) dlsym(RTLD_NEXT, "readdir"); + } + + struct dirent* ret = real_readdir(dirp); + + return ret; +} + +struct dirent64* +dlsym_readdir64(DIR* dirp) { + + + if(real_readdir64 == NULL) { + real_readdir64 = + (struct dirent64 * (*) (DIR*) ) dlsym(RTLD_NEXT, "readdir64"); + } + + struct dirent64* ret = real_readdir64(dirp); + + + return ret; +} + +// closedir +int +dlsym_closedir(DIR* dirp) { + + + if(real_closedir == NULL) { + real_closedir = (int (*)(DIR*)) dlsym(RTLD_NEXT, "closedir"); + } + + int ret = real_closedir(dirp); + + + return ret; +} + +// telldir +long +dlsym_telldir(DIR* dirp) { + debug_info("[SYSCALL_PROXIES] [dlsym_telldir] >> Begin\n"); + + if(real_telldir == NULL) { + real_telldir = (long (*)(DIR*)) dlsym(RTLD_NEXT, "telldir"); + } + + long ret = real_telldir(dirp); + + debug_info("[SYSCALL_PROXIES] [dlsym_telldir] >> End\n"); + + return ret; +} + // Proccess API int @@ -654,7 +786,7 @@ dlsym_fcntl(int fd, int cmd, long arg) { int dlsym_access(const char* path, int mode) { - debug_info("[SYSCALL_PROXIES] [dlsym_access] >> Begin\n"); + if(real_access == NULL) { real_access = (int (*)(const char*, int)) dlsym(RTLD_NEXT, "access"); @@ -662,7 +794,6 @@ dlsym_access(const char* path, int mode) { int ret = real_access((char*) path, mode); - debug_info("[SYSCALL_PROXIES] [dlsym_access] >> End\n"); return ret; } @@ -732,6 +863,47 @@ dlsym_mmap(void* addr, size_t length, int prot, int flags, int fd, } +/** + * stat management + */ +int +stat_to_stat64(struct stat64* buf, struct stat* st) { + buf->st_dev = (__dev_t) st->st_dev; + buf->st_ino = (__ino64_t) st->st_ino; + buf->st_mode = (__mode_t) st->st_mode; + buf->st_nlink = (__nlink_t) st->st_nlink; + buf->st_uid = (__uid_t) st->st_uid; + buf->st_gid = (__gid_t) st->st_gid; + buf->st_rdev = (__dev_t) st->st_rdev; + buf->st_size = (__off64_t) st->st_size; + buf->st_blksize = (__blksize_t) st->st_blksize; + buf->st_blocks = (__blkcnt64_t) st->st_blocks; + buf->st_atime = (__time_t) st->st_atime; + buf->st_mtime = (__time_t) st->st_mtime; + buf->st_ctime = (__time_t) st->st_ctime; + + return 0; +} + +int +stat64_to_stat(struct stat* buf, struct stat64* st) { + buf->st_dev = (__dev_t) st->st_dev; + buf->st_ino = (__ino_t) st->st_ino; + buf->st_mode = (__mode_t) st->st_mode; + buf->st_nlink = (__nlink_t) st->st_nlink; + buf->st_uid = (__uid_t) st->st_uid; + buf->st_gid = (__gid_t) st->st_gid; + buf->st_rdev = (__dev_t) st->st_rdev; + buf->st_size = (__off_t) st->st_size; + buf->st_blksize = (__blksize_t) st->st_blksize; + buf->st_blocks = (__blkcnt_t) st->st_blocks; + buf->st_atime = (__time_t) st->st_atime; + buf->st_mtime = (__time_t) st->st_mtime; + buf->st_ctime = (__time_t) st->st_ctime; + + return 0; +} + // File API int open(const char* path, int flags, ...) { @@ -742,13 +914,14 @@ open(const char* path, int flags, ...) { va_start(ap, flags); mode = va_arg(ap, mode_t); - + initializeGekko(); if(CTX->interception_enabled()) { std::string resolved; auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_not_a_dir: + va_end(ap); return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: @@ -775,7 +948,7 @@ open64(const char* path, int flags, ...) { int fd, ret; va_list ap; mode_t mode = 0; - + initializeGekko(); va_start(ap, flags); mode = va_arg(ap, mode_t); @@ -786,18 +959,24 @@ open64(const char* path, int flags, ...) { switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_not_a_dir: + va_end(ap); return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: + debug_info("[GEKKO] >> Begin open64.... %s %d %o %o %o\n", path, + fd, flags, mode, flags & O_CREAT); fd = gkfs::syscall::gkfs_open(resolved, mode, flags); - va_end(ap); - debug_info("[BYPASS] >> End open64.... %s %d\n", path, fd); + + debug_info("[GEKKO] >> End open64.... %s %d %o %o\n", path, fd, + flags, mode); + va_end(ap); return fd; default: // Try normal open. break; } - } + } + ret = dlsym_open64((char*) path, flags, mode); va_end(ap); @@ -805,13 +984,14 @@ open64(const char* path, int flags, ...) { return ret; } + int openat(int dirfd, const char* path, int flags, ...) { - + debug_info("[BYPASS] >> openat.... %s %o\n", path, flags); int ret, fd; va_list ap; mode_t mode = 0; - + initializeGekko(); va_start(ap, flags); mode = va_arg(ap, mode_t); @@ -827,12 +1007,23 @@ openat(int dirfd, const char* path, int flags, ...) { case gkfs::preload::RelativizeStatus::internal: fd = gkfs::syscall::gkfs_open(resolved, mode, flags); va_end(ap); - debug_info("[BYPASS] >> End open.... %s %d\n", path, fd); + debug_info("[BYPASS] >> End openat.... %s %d\n", path, fd); return fd; default: // Try normal open. break; } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin openat. ERROR...%s\n", path); + if(p.find("mnt") != std::string::npos) { + gkfs::preload::init_environment(); + CTX->enable_interception(); + debug_info("[BYPASS] >> Reinited. ERROR...%s %d\n", path, + CTX->interception_enabled()); + return openat(dirfd, (char*) path, flags, mode); + } } ret = dlsym_openat(dirfd, (char*) path, flags, mode); @@ -842,14 +1033,31 @@ openat(int dirfd, const char* path, int flags, ...) { return ret; } +int +openat64(int dirfd, const char* path, int flags, ...) { + va_list ap; + mode_t mode = 0; + initializeGekko(); + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + va_end(ap); + return openat(dirfd, path, flags, mode); +} // Generate the rest of the functions to build a libc io interception int close(int fd) { - + initializeGekko(); // Is fd from gekkofs ? - if(CTX->file_map()->exist(fd)) { - return gkfs::syscall::gkfs_close(fd); + if(CTX->interception_enabled()) { + + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_close(fd); + } + + } else { + debug_info("%d [BYPASS] >> close not intercepted...%d\n", gettid(), fd); } // Try normal close. @@ -924,7 +1132,7 @@ ftruncate(int fd, off_t length) { ssize_t read(int fd, void* buf, size_t nbyte) { - // Is fd from GekkoFS? + initializeGekko(); if(CTX->file_map()->exist(fd)) { debug_info("[READ from GKFS]....%d %ld\n", fd, nbyte); return gkfs::syscall::gkfs_read(fd, buf, nbyte); @@ -938,7 +1146,7 @@ read(int fd, void* buf, size_t nbyte) { ssize_t write(int fd, const void* buf, size_t nbyte) { - // Is fd from GekkoFS? + initializeGekko(); if(CTX->file_map()->exist(fd)) { debug_info("[WRITE from GKFS]....%d \n", fd); return gkfs::syscall::gkfs_write(fd, buf, nbyte); @@ -954,7 +1162,7 @@ int mkdir(const char* path, mode_t mode) { debug_info("[BYPASS] >> Begin mkdir....%s\n", path); int ret = 0; - // if path is inside gekkofs + initializeGekko(); if(CTX->interception_enabled()) { std::string resolved; @@ -1051,7 +1259,7 @@ mkstemp(char* templates) { // Add lseek off_t lseek(int fd, off_t offset, int whence) { - + initializeGekko(); // Is fd from GekkoFS? if(CTX->file_map()->exist(fd)) { debug_info("[xLSEEK GEKKO]....%ld %d\n", offset, whence); @@ -1122,27 +1330,11 @@ pwrite64(int fd, const void* buf, size_t count, off_t offset) { } -// add fstat -int -fstat(int fd, struct stat* buf) { - debug_info("[BYPASS] >> Begin fstat....%d\n", fd); - - // Is fd from GekkoFS? - if(CTX->file_map()->exist(fd)) { - debug_info("[FSTAT from GKFS]....%d \n", fd); - return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); - } - - int ret = dlsym_fstat(fd, buf); - - debug_info("[BYPASS] << After fstat....\n"); - - return ret; -} - int unlink(const char* path) { + debug_info("[BYPASS] >> Begin unlink....%s\n", path); + initializeGekko(); int ret = 0; // if path is inside gekkofs if(CTX->interception_enabled()) { @@ -1173,9 +1365,9 @@ unlink(const char* path) { // fill missing stat functions int -stat(const char* path, struct stat* buf) { - debug_info("[BYPASS] >> Begin stat....%s\n", path); - +__xstat(int ver, const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin __xstat....%s\n", path); + initializeGekko(); // Is path from GekkoFS? if(CTX->interception_enabled()) { std::string resolved; @@ -1187,25 +1379,32 @@ stat(const char* path, struct stat* buf) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: + debug_info("[_xSTAT from GKFS]....%s \n", resolved.c_str()); return gkfs::syscall::gkfs_stat(resolved, buf); default: // Try normal open. break; } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin stat. ERROR...%s\n", path); } - int ret = dlsym_stat(path, buf); - debug_info("[BYPASS] << After stat....\n"); + int ret = dlsym_stat(ver, path, buf); return ret; } int -lstat(const char* path, struct stat* buf) { - debug_info("[BYPASS] >> Begin lstat....%s\n", path); +statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* statxbuf) { + + debug_info("%d [BYPASS] >> Begin statx....%s\n", gettid(), path); + initializeGekko(); // Is path from GekkoFS? if(CTX->interception_enabled()) { std::string resolved; @@ -1217,25 +1416,116 @@ lstat(const char* path, struct stat* buf) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: - return gkfs::syscall::gkfs_stat(resolved, buf); + debug_info("[STATx from GKFS]....%s -> %s \n", path, + resolved.c_str()); + return gkfs::syscall::gkfs_statx(dirfd, resolved, flags, mask, + statxbuf); default: // Try normal open. break; } + } else { + std::string p = path; + debug_info("[BYPASS] >> Begin statx. ERROR...%s\n", path); } - int ret = dlsym_lstat(path, buf); - debug_info("[BYPASS] << After lstat....\n"); + int ret = dlsym_statx(dirfd, path, flags, mask, statxbuf); return ret; } int -fstatat(int dfd, const char* path, struct stat* buf, int flags) { - debug_info("[BYPASS] >> Begin fstatat....%s\n", path); +__lxstat(int ver, const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin __lxstat....%s\n", path); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[__lxstat64 from GKFS]....%s \n", resolved.c_str()); + res = gkfs::syscall::gkfs_stat(resolved, buf); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_lstat(ver, (const char*) path, buf); + return res; +} + +int +__lxstat64(int ver, const char* path, struct stat64* buf) { + debug_info("[BYPASS] >> Begin __lxstat64....%s\n", path); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[__lxstat64 from GKFS]....%s \n", resolved.c_str()); + struct stat st; + + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_lxstat64(ver, (const char*) path, buf); + return res; +} + +int +__fxstat(int ver, int fd, struct stat* buf) { + debug_info("[BYPASS] >> Begin __fxstat....%d\n", fd); + int res; + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(fd)) { + + debug_info("[__fxstat from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), + buf); + return res; + } + } + + res = dlsym_fstat(ver, fd, buf); + return res; +} + + +int +__fxstatat(int ver, int dfd, const char* path, struct stat* buf, int flags) { + debug_info("[BYPASS] >> Begin __fxstatat....%s\n", path); // Is path from GekkoFS? if(CTX->interception_enabled()) { std::string resolved; @@ -1259,12 +1549,188 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) { } int ret = dlsym_fstatat(dfd, path, buf, flags); + return ret; +} - debug_info("[BYPASS] << After fstatat....\n"); +int +__fxstat64(int ver, int fd, struct stat64* buf) { + debug_info("[BYPASS] >> Begin __fxstat64....%d\n", fd); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(fd)) { + + debug_info("[__fxstat64 from GKFS]....%d \n", fd); + struct stat st; + + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), + &st); + stat_to_stat64(buf, &st); + return res; + } + } + + res = dlsym_fxstat64(ver, fd, buf); + return res; +} + +int +__fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, + int flags) { + debug_info("[BYPASS] >> Begin __fxstatat....%s\n", path); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + int res; + auto rstatus = CTX->relativize_fd_path(dfd, path, resolved, flags); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::fd_unknown: + return -EBADF; + + case gkfs::preload::RelativizeStatus::internal: + struct stat st; + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + int ret = dlsym_fstatat64(dfd, path, buf, flags); + return ret; +} + +int +__xstat64(int ver, const char* path, struct stat64* buf) { + + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + struct stat st; + + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_xstat64(ver, (const char*) path, buf); + return res; +} + + +int +statvfs(const char* path, struct statvfs* buf) { + debug_info("[BYPASS] >> Begin statvfs....%s\n", path); + + buf->f_bsize = 4096; + buf->f_blocks = 1024; + buf->f_bfree = 1024; + buf->f_bavail = 1024; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_favail = 0; + buf->f_fsid = 0; + buf->f_namemax = 4096; + buf->f_frsize = 0; + buf->f_flag = 0; + + return 0; +} +int +fstatvfs(int fd, struct statvfs* buf) { + debug_info("[BYPASS] >> Begin fstatvfs....%d\n", fd); + buf->f_bsize = 4096; + buf->f_blocks = 1024; + buf->f_bfree = 1024; + buf->f_bavail = 1024; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_favail = 0; + buf->f_fsid = 0; + buf->f_namemax = 4096; + buf->f_frsize = 0; + buf->f_flag = 0; + return 0; +} + +int +stat(const char* path, struct stat* buf) { + debug_info("%d [BYPASS] >> Begin stat....%s\n", gettid(), path); + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[STAT from GKFS]....%s \n", resolved.c_str()); + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin stat. ERROR...%s\n", path); + } + + + int ret = dlsym_stat(_STAT_VER, path, buf); + + return ret; +} + +// add fstat +int +fstat(int fd, struct stat* buf) { + debug_info("[BYPASS] >> Begin fstat....%d\n", fd); + initializeGekko(); + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[FSTAT from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); + } + + int ret = dlsym_fstat(_STAT_VER, fd, buf); + + debug_info("[BYPASS] << After fstat....\n"); return ret; } + int rename(const char* oldpath, const char* newpath) { debug_info("[BYPASS] >> Begin rename....%s %s\n", oldpath, newpath); @@ -1316,18 +1782,18 @@ rename(const char* oldpath, const char* newpath) { pid_t fork(void) { int ret = -1; - + initializeGekko(); debug_info("[BYPASS] >> Begin fork()\n"); ret = dlsym_fork(); if(0 == ret) { // We want the children to be initialized - if(CTX->interception_enabled()) { - debug_info("Interception enabled in child\n"); - } + debug_info("I am the child\n"); + + initializeGekko(); } - debug_info("[BYPASS] << After fork()\n"); + debug_info("%d -> %d [BYPASS] << After fork()\n", ret, gettid()); return ret; } @@ -1335,7 +1801,7 @@ fork(void) { int pipe(int pipefd[2]) { debug_info("[BYPASS] >> Begin pipe() %d - %d\n", pipefd[0], pipefd[1]); - + initializeGekko(); int ret = dlsym_pipe(pipefd); debug_info("[BYPASS]\t dlsym_pipe -> %d\n", ret); @@ -1347,7 +1813,7 @@ pipe(int pipefd[2]) { int dup(int fd) { debug_info("[BYPASS] >> Begin dup... %d\n", fd); - + initializeGekko(); int ret = -1; // check if fd is from gekkofs if(CTX->file_map()->exist(fd)) { @@ -1368,7 +1834,7 @@ dup(int fd) { int dup2(int fd, int fd2) { debug_info("[BYPASS] >> Begin dup2...%d -> %d\n", fd, fd2); - + initializeGekko(); int ret = -1; // check if fd is from gekkofs if(CTX->file_map()->exist(fd)) { @@ -1443,7 +1909,7 @@ fcntl(int fd, int cmd, long arg) // TODO debug_info("[BYPASS] >> Begin fcntl... %d , %d ,%ld\n", fd, cmd, arg); int ret = -1; - + initializeGekko(); // is from gekkofs? if(CTX->file_map()->exist(fd)) { @@ -1520,11 +1986,8 @@ fcntl(int fd, int cmd, long arg) // TODO int access(const char* path, int mode) { - struct stat64 stats; - debug_info("[BYPASS] >> Begin access...\n"); - debug_info("[BYPASS] 1) path %s\n", path); - debug_info("[BYPASS] 2) mode %d\n", mode); + initializeGekko(); int ret = -1; @@ -1537,13 +2000,14 @@ access(const char* path, int mode) { case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; - + break; case gkfs::preload::RelativizeStatus::internal: - return -ENOTDIR; - + debug_info("[GekkoFS Access] %s\n", resolved.c_str()); + ret = gkfs::syscall::gkfs_access(resolved, mode, true); + return ret; + break; default: - debug_info("[GekkoFS Access] \n"); - auto ret = gkfs::syscall::gkfs_access(resolved, mode, true); + // try normal break; } } @@ -1551,17 +2015,12 @@ access(const char* path, int mode) { // call the real access function ret = dlsym_access((char*) path, mode); - debug_info("[BYPASS] << After access()\n"); - - return ret; - return ret; } char* realpath(const char* path, char* resolved_path) { - debug_info("[BYPASS] >> Begin realpath...\n"); - debug_info("[BYPASS] 1) Path %s\n", path); + debug_info("[BYPASS] >> Begin realpath... %s\n", path); // is gekkofs if(CTX->interception_enabled()) { std::string resolved; @@ -1576,7 +2035,6 @@ realpath(const char* path, char* resolved_path) { return nullptr; default: - strcpy(resolved_path, resolved.c_str()); return resolved_path; } @@ -1585,8 +2043,6 @@ realpath(const char* path, char* resolved_path) { // call the real realpath function char* ret = dlsym_realpath((char*) path, resolved_path); - debug_info("[BYPASS] << After realpath()\n"); - return ret; } @@ -1634,4 +2090,282 @@ flock(int fd, int operation) { debug_info("[BYPASS] << After flock...\n"); return ret; -} \ No newline at end of file +} + + +DIR* +opendir(const char* dirname) { + DIR* ret; + + initializeGekko(); + if(CTX->interception_enabled()) { + int fd; + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, dirname, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", dirname); + errno = ENOTDIR; + return NULL; + case gkfs::preload::RelativizeStatus::internal: + // debug_info("[BYPASS] >> opendir GKFS.... %s\n", dirname); + + // check if resolved is a dir with gkfs_stat + // if not, return NULL + struct stat st; + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", dirname); + errno = ENOTDIR; + return NULL; + } + fd = gkfs::syscall::gkfs_opendir(resolved); + + + ret = (DIR*) malloc(sizeof(DIR)); + + // fill the dirp info + ret->fd = fd; + ret->path = strdup(resolved.c_str()); + // debug_info("[BYPASS] >> End opendir.... %p %s %d\n", + // (void*) ret, dirname, fd); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_opendir((char*) dirname); + return ret; +} + +// opendir64 +DIR* +opendir64(const char* dirname) { + DIR* ret; + + initializeGekko(); + if(CTX->interception_enabled()) { + int fd; + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, dirname, resolved); + switch(rstatus) { + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", dirname); + errno = ENOTDIR; + return NULL; + + case gkfs::preload::RelativizeStatus::internal: + // debug_info("[BYPASS] >> opendir64 GKFS.... %s\n", dirname); + // check if resolved is a dir with gkfs_stat + // if not, return NULL + struct stat st; + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", dirname); + errno = ENOTDIR; + return NULL; + } + + fd = gkfs::syscall::gkfs_opendir(resolved); + + + ret = (DIR*) malloc(sizeof(DIR)); + + // fill the dirp info + ret->fd = fd; + ret->path = strdup(resolved.c_str()); + // debug_info("[BYPASS] >> End opendir64.... %p %s %d\n", + // (void*) ret, dirname, fd); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_opendir64((char*) dirname); + return ret; +} +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) +// readdir +struct dirent* +readdir(DIR* dirp) { + struct dirent* ret; + + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + // call gekko getdents + //debug_info("[BYPASS] >> readdir GKFS.... %p\n", (void*) dirp); + ret = (struct dirent*) malloc(sizeof(dirent) * 1); + auto open_dir = CTX->file_map()->get_dir(dirp->fd); + if(open_dir == nullptr) { + // Cast did not succeeded: open_file is a regular file + errno = EBADF; + free((void*) ret); + return NULL; + } + + // get directory position of which entries to return + auto pos = open_dir->pos(); + if(pos >= open_dir->size()) { + free((void*) ret); + return NULL; + } + + + auto de = open_dir->getdent(pos); + auto total_size = ALIGN(offsetof(struct dirent, d_name) + + de.name().size() + 3, + sizeof(long)); + // fill ret with data + ret->d_ino = std::hash()(open_dir->path() + "/" + + de.name()); + ret->d_reclen = total_size; + ret->d_type = + ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG + : DT_DIR); + std::strcpy(&(ret->d_name[0]), de.name().c_str()); + + open_dir->pos(pos + 1); + return ret; + } + } + + ret = dlsym_readdir(dirp); + return ret; +} + + +// readdir64 +struct dirent64* +readdir64(DIR* dirp) { + struct dirent64* ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + // call gekko getdents + //debug_info("[BYPASS] >> readdir64 GKFS.... %p\n", (void*) dirp); + ret = (struct dirent64*) malloc(sizeof(dirent64) * 1); + auto open_dir = CTX->file_map()->get_dir(dirp->fd); + if(open_dir == nullptr) { + // Cast did not succeeded: open_file is a regular file + errno = EBADF; + free((void*) ret); + return NULL; + } + + // get directory position of which entries to return + auto pos = open_dir->pos(); + if(pos >= open_dir->size()) { + free((void*) ret); + return NULL; + } + + + auto de = open_dir->getdent(pos); + auto total_size = ALIGN(offsetof(struct dirent64, d_name) + + de.name().size() + 3, + sizeof(long)); + // fill ret with data + ret->d_ino = std::hash()(open_dir->path() + "/" + + de.name()); + ret->d_reclen = total_size; + ret->d_type = + ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG + : DT_DIR); + std::strcpy(&(ret->d_name[0]), de.name().c_str()); + + open_dir->pos(pos + 1); + return ret; + } + } + + ret = dlsym_readdir64(dirp); + return ret; +} + +// closedir +int +closedir(DIR* dirp) { + int ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + //debug_info("[BYPASS] >> closedir GKFS.... %p\n", (void*) dirp); + ret = gkfs::syscall::gkfs_close(dirp->fd); + free(dirp->path); + free(dirp); + return ret; + } + } + + ret = dlsym_closedir(dirp); + return ret; +} + +// telldir +long +telldir(DIR* dirp) { + debug_info("[BYPASS] >> telldir.... %p\n", (void*) dirp); + long ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + debug_info("[BYPASS] >> telldir GKFS not implemented.... %p\n", + (void*) dirp); + ret = 0; + // ret = gkfs::syscall::gkfs_telldir(dirp->fd); + return ret; + } + } + + ret = dlsym_telldir(dirp); + return ret; +} + +// seekdir +void +seekdir(DIR* dirp, long loc) { + debug_info("[BYPASS] >> seekdir.... %p %ld\n", (void*) dirp, loc); + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + debug_info("[BYPASS] >> seekdir GKFS no implemented.... %p %ld\n", + (void*) dirp, loc); + return; + } + } + + dlsym_seekdir(dirp, loc); +} + +/* +// getdents +ssize_t +getdents(int fd, struct dirent* dirp, unsigned int count) { + debug_info("[BYPASS] >> getdents.... %d %p %u\n", fd, dirp, count); + ssize_t ret; + if(CTX->interception_enabled()) { + if(dirp->d_name != NULL) { + ret = gkfs::syscall::gkfs_getdents(fd, dirp, count); + return ret; + } + } + + ret = dlsym_getdents(fd, dirp, count); + return ret; +} + +// getdents64 +ssize_t +getdents64(int fd, struct dirent64* dirp, unsigned int count) { + debug_info("[BYPASS] >> getdents64.... %d %p %u\n", fd, dirp, count); + ssize_t ret; + if(CTX->interception_enabled()) { + if(dirp->d_name != NULL) { + ret = gkfs::syscall::gkfs_getdents64(fd, dirp, count); + return ret; + } + } + + ret = dlsym_getdents64(fd, dirp, count); + return ret; +} +*/ diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index d9334002d..45cadeed3 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -175,6 +175,10 @@ OpenFileMap::remove(const int fd) { return false; } files_.erase(fd); + if(!CTX->protect_fds()) { + // We close the dev null fd + close(fd); + } if(fd_validation_needed && files_.empty()) { fd_validation_needed = false; LOG(DEBUG, "fd_validation flag reset"); -- GitLab From 5f592f4bf645c9333f1fef1c3df78e5cbe924e4a Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 24 Oct 2024 07:16:10 +0200 Subject: [PATCH 32/32] Rebase and reformat --- include/client/gkfs_libc.hpp | 21 ++++++------ include/client/preload.hpp | 3 +- include/client/user_functions.hpp | 1 - src/client/gkfs_libc.cpp | 57 +++++++++++++++++-------------- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp index af29c8f06..f2a15c062 100644 --- a/include/client/gkfs_libc.hpp +++ b/include/client/gkfs_libc.hpp @@ -50,19 +50,18 @@ extern "C" { #define _STAT_VER 0 #endif -struct __dirstream - { - int fd; // File descriptor. +struct __dirstream { + int fd; // File descriptor. //__libc_lock_define (, lock) // Mutex lock for this structure. //TODO - size_t allocation; // Space allocated for the block. - size_t size; // Total valid data in the block. - size_t offset; // Current offset into the block. - off_t filepos; // Position of next entry to read. + size_t allocation; // Space allocated for the block. + size_t size; // Total valid data in the block. + size_t offset; // Current offset into the block. + off_t filepos; // Position of next entry to read. // Directory block. - char data[0] __attribute__ ((aligned (__alignof__ (void*)))); + char data[0] __attribute__((aligned(__alignof__(void*)))); - char * path; - }; + char* path; +}; // File API @@ -297,7 +296,7 @@ __xstat(int ver, const char* path, struct stat* buf); int __xstat64(int ver, const char* path, struct stat64* buf); int -__fxstat64(int ver, const char* path, struct stat64* buf); +__fxstat64(int ver, int fd, struct stat64* buf); int __lxstat(int ver, const char* path, struct stat* buf); int diff --git a/include/client/preload.hpp b/include/client/preload.hpp index 6bc965beb..88d708251 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -37,7 +37,8 @@ #define CTX gkfs::preload::PreloadContext::getInstance() namespace gkfs::preload { -void init_environment(); +void +init_environment(); void init_ld_env_if_needed(); } // namespace gkfs::preload diff --git a/include/client/user_functions.hpp b/include/client/user_functions.hpp index d753a1022..0d79409fc 100644 --- a/include/client/user_functions.hpp +++ b/include/client/user_functions.hpp @@ -105,7 +105,6 @@ gkfs_getdents64(unsigned int fd, struct linux_dirent64* dirp, unsigned int count); - } // namespace syscall namespace malleable { diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index 658c4280a..172b93607 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -959,24 +959,24 @@ open64(const char* path, int flags, ...) { switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_not_a_dir: - va_end(ap); + va_end(ap); return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: debug_info("[GEKKO] >> Begin open64.... %s %d %o %o %o\n", path, fd, flags, mode, flags & O_CREAT); fd = gkfs::syscall::gkfs_open(resolved, mode, flags); - + debug_info("[GEKKO] >> End open64.... %s %d %o %o\n", path, fd, flags, mode); - va_end(ap); + va_end(ap); return fd; default: // Try normal open. break; } - } - + } + ret = dlsym_open64((char*) path, flags, mode); va_end(ap); @@ -1565,8 +1565,8 @@ __fxstat64(int ver, int fd, struct stat64* buf) { debug_info("[__fxstat64 from GKFS]....%d \n", fd); struct stat st; - return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), - &st); + res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), + &st); stat_to_stat64(buf, &st); return res; } @@ -2105,17 +2105,20 @@ opendir(const char* dirname) { switch(rstatus) { case gkfs::preload::RelativizeStatus::fd_not_a_dir: - debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", dirname); + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", + dirname); errno = ENOTDIR; return NULL; case gkfs::preload::RelativizeStatus::internal: - // debug_info("[BYPASS] >> opendir GKFS.... %s\n", dirname); - + // debug_info("[BYPASS] >> opendir GKFS.... %s\n", dirname); + // check if resolved is a dir with gkfs_stat // if not, return NULL struct stat st; - if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or S_ISREG(st.st_mode)) { - debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", dirname); + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or + S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", + dirname); errno = ENOTDIR; return NULL; } @@ -2127,8 +2130,8 @@ opendir(const char* dirname) { // fill the dirp info ret->fd = fd; ret->path = strdup(resolved.c_str()); - // debug_info("[BYPASS] >> End opendir.... %p %s %d\n", - // (void*) ret, dirname, fd); + // debug_info("[BYPASS] >> End opendir.... %p %s %d\n", + // (void*) ret, dirname, fd); return ret; default: // Try normal open. @@ -2151,22 +2154,26 @@ opendir64(const char* dirname) { std::string resolved; auto rstatus = CTX->relativize_fd_path(AT_FDCWD, dirname, resolved); switch(rstatus) { - case gkfs::preload::RelativizeStatus::fd_not_a_dir: - debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", dirname); + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", + dirname); errno = ENOTDIR; return NULL; case gkfs::preload::RelativizeStatus::internal: - // debug_info("[BYPASS] >> opendir64 GKFS.... %s\n", dirname); + // debug_info("[BYPASS] >> opendir64 GKFS.... %s\n", + // dirname); // check if resolved is a dir with gkfs_stat // if not, return NULL struct stat st; - if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or S_ISREG(st.st_mode)) { - debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", dirname); + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or + S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", + dirname); errno = ENOTDIR; return NULL; } - + fd = gkfs::syscall::gkfs_opendir(resolved); @@ -2175,8 +2182,8 @@ opendir64(const char* dirname) { // fill the dirp info ret->fd = fd; ret->path = strdup(resolved.c_str()); - // debug_info("[BYPASS] >> End opendir64.... %p %s %d\n", - // (void*) ret, dirname, fd); + // debug_info("[BYPASS] >> End opendir64.... %p %s %d\n", + // (void*) ret, dirname, fd); return ret; default: // Try normal open. @@ -2196,7 +2203,7 @@ readdir(DIR* dirp) { if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { // call gekko getdents - //debug_info("[BYPASS] >> readdir GKFS.... %p\n", (void*) dirp); + // debug_info("[BYPASS] >> readdir GKFS.... %p\n", (void*) dirp); ret = (struct dirent*) malloc(sizeof(dirent) * 1); auto open_dir = CTX->file_map()->get_dir(dirp->fd); if(open_dir == nullptr) { @@ -2244,7 +2251,7 @@ readdir64(DIR* dirp) { if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { // call gekko getdents - //debug_info("[BYPASS] >> readdir64 GKFS.... %p\n", (void*) dirp); + // debug_info("[BYPASS] >> readdir64 GKFS.... %p\n", (void*) dirp); ret = (struct dirent64*) malloc(sizeof(dirent64) * 1); auto open_dir = CTX->file_map()->get_dir(dirp->fd); if(open_dir == nullptr) { @@ -2290,7 +2297,7 @@ closedir(DIR* dirp) { int ret; if(CTX->interception_enabled()) { if(CTX->file_map()->exist(dirp->fd)) { - //debug_info("[BYPASS] >> closedir GKFS.... %p\n", (void*) dirp); + // debug_info("[BYPASS] >> closedir GKFS.... %p\n", (void*) dirp); ret = gkfs::syscall::gkfs_close(dirp->fd); free(dirp->path); free(dirp); -- GitLab