Commit feee85b5 authored by Ramon Nou's avatar Ramon Nou
Browse files

more calls and debug

parent 9a2a38f5
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -42,11 +42,10 @@

#include <client/open_file_map.hpp>
#include <common/metadata.hpp>
#include <client/intercept.hpp>

struct statfs;
struct statvfs;
struct linux_dirent;
struct linux_dirent64;

namespace gkfs::syscall {

+1 −3
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ extern "C" {
#include <client/void_syscall_intercept.hpp>
#endif

#include <client/intercept.hpp>

/*
 * For PowerPC, syscall_no_intercept_wrapper() is defined in the
@@ -75,9 +76,6 @@ syscall_no_intercept_wrapper(long syscall_number, Args... args) {
#endif

struct statfs;
struct linux_dirent;
struct linux_dirent64;

namespace gkfs::hook {

int
+31 −0
Original line number Diff line number Diff line
@@ -40,6 +40,37 @@
#ifndef GEKKOFS_INTERCEPT_HPP
#define GEKKOFS_INTERCEPT_HPP

#include <stdint.h>
/*
 * linux_dirent is used in getdents() but is privately defined in the linux
 * 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];
};
/*
 * linux_dirent64 is used in getdents64() and defined in the linux kernel:
 * include/linux/dirent.h. However, it is not part of the kernel-headers and
 * cannot be imported.
 */
struct linux_dirent64 {
    uint64_t d_ino;
    int64_t d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++
                    // forbids zero-size array 'd_name'
};

namespace gkfs::preload {

int
+0 −30
Original line number Diff line number Diff line
@@ -70,36 +70,6 @@ using namespace std;
 */
#define ALIGN(x, a) __ALIGN_KERNEL((x), (a))

/*
 * linux_dirent is used in getdents() but is privately defined in the linux
 * 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];
};
/*
 * linux_dirent64 is used in getdents64() and defined in the linux kernel:
 * include/linux/dirent.h. However, it is not part of the kernel-headers and
 * cannot be imported.
 */
struct linux_dirent64 {
    uint64_t d_ino;
    int64_t d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++
                    // forbids zero-size array 'd_name'
};

struct dirent_extended {
    size_t size;
    time_t ctime;
+107 −12
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ initializeGekko() {
void
log_arguments(const char* symbol) {
    LOG(DEBUG, "[BYPASS] {}", symbol);
    // printf("[BYPASS] %s\n",symbol);
}

// Variadic case: 1+ arguments
@@ -94,6 +95,18 @@ log_arguments(const char* symbol, Args&&... args) {
    ss << "[BYPASS] Calling " << symbol << " with arguments: ";
    ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...);
    LOG(DEBUG, "{}", ss.str());
    // printf("%s\n",ss.str().c_str());
}

// Variadic case: 1+ arguments
template <typename... Args>
void
log_argumentsx(const char* symbol, Args&&... args) {
    std::stringstream ss;
    ss << "[BYPASS-ERROR] Calling " << symbol << " with arguments: ";
    ((ss << "[" << typeid(Args).name() << "] " << args << " "), ...);
    LOG(DEBUG, "{}", ss.str());
    // printf("%s\n",ss.str().c_str());
}

/**
@@ -137,6 +150,28 @@ log_arguments(const char* symbol, Args&&... args) {
    }


#define CDLSYM_WRAPPER(return_type, func_name, params, args, symbol_name)      \
    static return_type(*real_##func_name) params = nullptr;                    \
    return_type dlsym_##func_name params {                                     \
        if(!real_##func_name) {                                                \
            real_##func_name = reinterpret_cast<return_type(*) params>(        \
                    dlsym(RTLD_NEXT, symbol_name));                            \
            if(!real_##func_name) {                                            \
                fprintf(stderr, "dlsym failed for %s: %s\n", symbol_name,      \
                        dlerror());                                            \
                errno = ENOSYS; /* Set errno to ENOSYS to indicate function    \
                                   not supported */                            \
                return (return_type) - 1; /* Return error value */             \
            }                                                                  \
        }                                                                      \
        log_argumentsx(symbol_name, STRIP_PARENS args);                        \
        return real_##func_name args;                                          \
    }                                                                          \
    return_type func_name params {                                             \
        return dlsym_##func_name args;                                         \
    }


// DLSYM_WRAPPER(int, open, (char* path, int flags, mode_t mode), (path, flags,
// mode), "open")
DLSYM_WRAPPER(int, open2, (const char* path, int flags, mode_t mode),
@@ -188,8 +223,7 @@ DLSYM_WRAPPER(int, stat, (int ver, const char* path, struct stat* buf),
              (ver, path, buf), "__xstat")
DLSYM_WRAPPER(int, fstat, (int ver, int fd, struct stat* buf), (ver, fd, buf),
              "__fxstat")
DLSYM_WRAPPER(int, fstat64, ( int fd,struct stat64* buf), ( fd, buf),
              "__fxstat64")
DLSYM_WRAPPER(int, fstat64, (int fd, struct stat64* buf), (fd, buf), "fstat64")
DLSYM_WRAPPER(int, fxstatat,
              (int ver, int dfd, const char* path, struct stat* buf, int flags),
              (ver, dfd, path, buf, flags), "__fxstatat")
@@ -227,6 +261,9 @@ DLSYM_WRAPPER(int, chown, (char* path, uid_t owner, gid_t group),
              (path, owner, group), "chown")
DLSYM_WRAPPER(int, fcntl, (int fd, int cmd, long arg), (fd, cmd, arg), "fcntl")
DLSYM_WRAPPER(int, access, (const char* path, int mode), (path, mode), "access")
DLSYM_WRAPPER(int, faccessat, (int dfd, const char* path, int mode, int flags),
              (dfd, path, mode, flags), "faccessat")

DLSYM_WRAPPER(char*, realpath, (const char* path, char* resolved_path),
              (path, resolved_path), "realpath")
DLSYM_WRAPPER(int, fsync, (int fd), (fd), "fsync")
@@ -258,7 +295,48 @@ DLSYM_WRAPPER(int, fputs, (const char* str, FILE* stream), (str, stream),
DLSYM_WRAPPER(char*, fgets, (char* str, int n, FILE* stream), (str, n, stream),
              "fgets")
DLSYM_WRAPPER(int, fflush, (FILE * stream), (stream), "fflush")
CDLSYM_WRAPPER(ssize_t, readlink, (const char* path, char* buf, size_t bufsize),
               (path, buf, bufsize), "readlink")

CDLSYM_WRAPPER(ssize_t, readlinkat,
               (int dfd, const char* path, char* buf, size_t bufsize),
               (dfd, path, buf, bufsize), "readlinkat")

CDLSYM_WRAPPER(int, openat2,
               (int dfd, const char* path, int flags, mode_t mode),
               (dfd, path, flags, mode), "openat2")

CDLSYM_WRAPPER(int, execve,
               (const char* filename, char* const argv, char* const envp),
               (filename, argv, envp), "execve")

CDLSYM_WRAPPER(int, execveat,
               (int dfd, const char* filename, char* const argv[],
                char* const envp[], int flags),
               (dfd, filename, argv, envp, flags), "execveat")

CDLSYM_WRAPPER(int, execv, (const char* filename, char* const argv[]),
               (filename, argv), "execv")

CDLSYM_WRAPPER(int, fexecve, (int fd, const char* filename, char* const argv[]),
               (fd, filename, argv), "fexecve")

DLSYM_WRAPPER(long, syscall, (long number, char* cmd, void* arg, void* env),
              (number, cmd, arg, env), "syscall")

long
syscall(long number, ...) {

    if(number == SYS_execve or number == SYS_execveat) {
        LOG(DEBUG, "OSTIA execve {}", number);
    }
    va_list myargs;
    va_start(myargs, number);

    auto res = syscall_no_intercept_wrapper(number, myargs);
    va_end(myargs);
    return res;
}
/* not used */
/*static void
convert(struct stat64* src, struct stat* dest) {
@@ -362,6 +440,7 @@ is_gkfs_fd(int fd) {
#define GKFS_OPERATION(name, ...)                                              \
    if(CTX->interception_enabled() && is_gkfs_fd(fd)) {                        \
        LOG(DEBUG, "[GKFS] {}", fd);                                           \
        printf("[GKFS] %d\n", fd);                                             \
        return gkfs::syscall::gkfs_##name(__VA_ARGS__);                        \
    }

@@ -371,6 +450,7 @@ is_gkfs_fd(int fd) {
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                printf("[GKFS] %s\n", resolved.c_str());                       \
                return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__);      \
            case PathStatus::Error:                                            \
                return -errno;                                                 \
@@ -385,6 +465,7 @@ is_gkfs_fd(int fd) {
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                printf("[GKFS] %s\n", resolved.c_str());                       \
                return gkfs::syscall::gkfs_##name(dirfd, resolved,             \
                                                  __VA_ARGS__);                \
            case PathStatus::Error:                                            \
@@ -400,6 +481,7 @@ is_gkfs_fd(int fd) {
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                LOG(DEBUG, "[GKFS] {}", resolved);                             \
                printf("[GKFS] %s\n", resolved.c_str());                       \
                return gkfs::syscall::gkfs_##name(resolved);                   \
            case PathStatus::Error:                                            \
                return -errno;                                                 \
@@ -445,7 +527,6 @@ open64(const char* path, int flags, mode_t mode) {
}



int
openat(int dirfd, const char* path, int flags, ...) {
    va_list ap;
@@ -519,7 +600,7 @@ get_open_fds() {
int
close_range(unsigned low, unsigned high, int flags) {
    LOG(DEBUG, "close_range({}, {}, {})", low, high, flags);
    //return 0;
    return 0;
    auto fds = get_open_fds();
    if(flags & CLOSE_RANGE_UNSHARE) {
        // Unshare the file descriptor table
@@ -795,6 +876,22 @@ __fxstat64(int ver, int fd, struct stat64* buf) {
    GKFS_FALLBACK(fxstat64, ver, fd, buf);
}

int
fstat64(int fd, struct stat64* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        struct stat st;
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        int res =
                gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), &st);
        if(res == 0)
            convert(&st, buf);
        return res;
    }
    GKFS_FALLBACK(fstat64, fd, buf);
}


int
__fxstatat64(int ver, int dfd, const char* path, struct stat64* buf,
             int flags) {
@@ -969,12 +1066,10 @@ dup2(int fd, int fd2) {
    if(is_gkfs_fd(fd) && is_gkfs_fd(fd2)) {
        LOG(DEBUG, "[GKFS] DUP2 G{} --> G{}", fd, fd2);
        return gkfs::syscall::gkfs_dup2(fd, fd2);
    }else
    if(is_gkfs_fd(fd2)) {
    } else if(is_gkfs_fd(fd2)) {
        LOG(DEBUG, "[GKFS-NON] DUP2 {} --> G{}", fd, fd2);
        return gkfs::syscall::gkfs_dup(fd);
    }else
    if(is_gkfs_fd(fd)) {
    } else if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS-NON] DUP2 G{} --> {}", fd, fd2);
        return gkfs::syscall::gkfs_dup2(fd, fd2);
    }
Loading