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

realpath added

parent 39035659
Loading
Loading
Loading
Loading
+103 −56
Original line number Diff line number Diff line
@@ -81,17 +81,18 @@ initializeGekko() {

#define STRIP_PARENS(...) __VA_ARGS__

void log_arguments(const char* symbol) {
void
log_arguments(const char* symbol) {
    LOG(DEBUG, "[BYPASS] {}", symbol);
}

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

@@ -130,7 +131,8 @@ void log_arguments(const char* symbol, Args&&... args) {
                                   not supported */                            \
                return (return_type) - 1; /* Return error value */             \
            }                                                                  \
        } log_arguments(symbol_name, STRIP_PARENS args);             \
        }                                                                      \
        log_arguments(symbol_name, STRIP_PARENS args);                         \
        return real_##func_name args;                                          \
    }

@@ -201,7 +203,7 @@ DLSYM_WRAPPER(int, statx,
              (dirfd, path, flags, mask, buf), "statx")
DLSYM_WRAPPER(int, rename, (const char* oldpath, const char* newpath),
              (oldpath, newpath), "rename")
// DLSYM_WRAPPER(int, remove, (char* path), (path), "remove")
DLSYM_WRAPPER(int, remove, (char* path), (path), "remove")
DLSYM_WRAPPER(int, unlink, (const char* path), (path), "unlink")
DLSYM_WRAPPER(DIR*, opendir, (const char* dirname), (dirname), "opendir")
DLSYM_WRAPPER(DIR*, opendir64, (const char* dirname), (dirname), "opendir64")
@@ -217,18 +219,20 @@ DLSYM_WRAPPER(int, dup2, (int fd, int fd2), (fd, fd2), "dup2")
DLSYM_WRAPPER(int, dup3, (int fd, int fd2, int flags), (fd, fd2, flags), "dup3")
DLSYM_WRAPPER(void, exit, (int status), (status), "exit")
DLSYM_WRAPPER(int, chdir, (char* path), (path), "chdir")
// DLSYM_WRAPPER(int, chmod, (char* path, mode_t mode), (path, mode), "chmod")
// DLSYM_WRAPPER(int, fchmod, (int fd, mode_t mode), (fd, mode), "fchmod")
// DLSYM_WRAPPER(int, chown, (char* path, uid_t owner, gid_t group), (path,
// owner, group), "chown")
DLSYM_WRAPPER(int, chmod, (char* path, mode_t mode), (path, mode), "chmod")
DLSYM_WRAPPER(int, fchmod, (int fd, mode_t mode), (fd, mode), "fchmod")
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(char*, realpath, (const char* path, char* resolved_path),
              (path, resolved_path), "realpath")
DLSYM_WRAPPER(int, fsync, (int fd), (fd), "fsync")
DLSYM_WRAPPER(int, flock, (int fd, int operation), (fd, operation), "flock")
// DLSYM_WRAPPER(void*, mmap, (void* addr, size_t length, int prot, int flags,
// int fd, off_t offset), (addr, length, prot, flags, fd, offset), "mmap")
DLSYM_WRAPPER(void*, mmap,
              (void* addr, size_t length, int prot, int flags, int fd,
               off_t offset),
              (addr, length, prot, flags, fd, offset), "mmap")
DLSYM_WRAPPER(FILE*, fopen, (const char* filename, const char* mode),
              (filename, mode), "fopen")
DLSYM_WRAPPER(FILE*, fdopen, (int fd, const char* mode), (fd, mode), "fdopen")
@@ -321,6 +325,15 @@ enum class PathStatus { External, Internal, Error };
PathStatus
resolve_gkfs_path(int dirfd, const char* path, std::string& resolved,
                  int flags = 0, bool resolve_last_link = true) {
    // if path does not start with CTX->mountdir() just return external
    auto res = std::mismatch(CTX->mountdir().begin(), CTX->mountdir().end(),
                             std::string(path).begin());

    if(res.first != CTX->mountdir().end()) {
        return PathStatus::External;
    }


    const auto status = CTX->relativize_fd_path(dirfd, path, resolved, flags,
                                                resolve_last_link);

@@ -345,7 +358,8 @@ is_gkfs_fd(int fd) {
}

#define GKFS_OPERATION(name, ...)                                              \
    if(CTX->interception_enabled() && is_gkfs_fd(fd)) { LOG(DEBUG,"[GKFS] %d",fd); \
    if(CTX->interception_enabled() && is_gkfs_fd(fd)) {                        \
        LOG(DEBUG, "[GKFS] {}", fd);                                           \
        return gkfs::syscall::gkfs_##name(__VA_ARGS__);                        \
    }

@@ -482,6 +496,7 @@ ftruncate(int fd, off_t length) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        std::string path_str = CTX->file_map()->get(fd)->path();
        LOG(DEBUG, "[GKFS] {}", path_str);
        return gkfs::syscall::gkfs_truncate(path_str, length);
    }
    GKFS_FALLBACK(ftruncate, fd, length);
@@ -586,6 +601,7 @@ __xstat64(int ver, const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -627,6 +643,7 @@ __lxstat(int ver, const char* path, struct stat* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved, 0, false)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, buf);
                return res;
            }
@@ -649,6 +666,7 @@ __lxstat64(int ver, const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -667,6 +685,7 @@ int
__fxstat(int ver, int fd, struct stat* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf);
    }
    GKFS_FALLBACK(fstat, ver, fd, buf);
@@ -684,6 +703,7 @@ __fxstat64(int ver, 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)
@@ -702,6 +722,7 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf,
        std::string resolved;
        switch(resolve_gkfs_path(dfd, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", resolved);
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -731,6 +752,7 @@ stat64(const char* path, struct stat64* buf) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
                auto res = gkfs::syscall::gkfs_stat(resolved, &st);
                convert(&st, buf);
                return res;
@@ -752,6 +774,7 @@ int
fstat(int fd, struct stat* buf) {
    initializeGekko();
    if(is_gkfs_fd(fd)) {
        LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
        return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf);
    }
    GKFS_FALLBACK(fstat, _STAT_VER, fd, buf);
@@ -764,6 +787,7 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) {
        std::string resolved;
        switch(resolve_gkfs_path(dfd, path, resolved)) {
            case PathStatus::Internal: {
                LOG(DEBUG, "[GKFS] {}", CTX->file_map()->get(fd)->path());
                auto res = gkfs::syscall::gkfs_stat(resolved, buf);
                return res;
            }
@@ -793,6 +817,8 @@ rename(const char* oldpath, const char* newpath) {
            case PathStatus::Internal:
                switch(rstatus_new) {
                    case PathStatus::Internal:
                        LOG(DEBUG, "[GKFS] {} {}{}", "NOT IMPLEMENTED",
                            resolved_old, resolved_new);
                        return -ENOTDIR;
                        //                       return
                        //                       gkfs::syscall::gkfs_rename(resolved_old,
@@ -840,6 +866,12 @@ fork(void) {
int
pipe(int pipefd[2]) {
    initializeGekko();
    if(is_gkfs_fd(pipefd[0])) {
        LOG(DEBUG, "[GKFS] 0 {}", pipefd[0]);
    }
    if(is_gkfs_fd(pipefd[1])) {
        LOG(DEBUG, "[GKFS] 1 {}", pipefd[1]);
    }
    GKFS_FALLBACK(pipe, pipefd);
}

@@ -879,7 +911,7 @@ chdir(const char* path) {
    initializeGekko();
    // is the path from gekkofs
    //   return gkfs::hook::hook_chdir(path);
    /*

    if(CTX->interception_enabled()) {
        std::string resolved;

@@ -890,14 +922,15 @@ chdir(const char* path) {
                return -ENOTDIR;

            case gkfs::preload::RelativizeStatus::internal:
                return (
                LOG(DEBUG, "[GKFS] NOT IMPLEMENTED {}", path);
                break;

            default:
                // Try normal open.
                break;
        }
    }
*/

    GKFS_FALLBACK(chdir, const_cast<char*>(path));
}

@@ -913,12 +946,12 @@ fcntl(int fd, int cmd, long arg) // TODO
        switch(cmd) {

            case F_DUPFD:
                DEBUG_INFO("dupfd\n");
                LOG(DEBUG, "[GKFS] DUPFD {}", fd);

                return gkfs::syscall::gkfs_dup(fd);

            case F_DUPFD_CLOEXEC:
                DEBUG_INFO("dupfd_cloexec\n");
                LOG(DEBUG, "[GKFS] F_DUPFD_CLOEXEC {}", fd);
                ret = gkfs::syscall::gkfs_dup(fd);
                if(ret == -1) {
                    return -errno;
@@ -928,7 +961,7 @@ fcntl(int fd, int cmd, long arg) // TODO
                return ret;

            case F_GETFD:
                DEBUG_INFO("getfd\n");
                LOG(DEBUG, "[GKFS] F_GETFD {}", fd);
                if(CTX->file_map()->get(fd)->get_flag(
                           gkfs::filemap::OpenFile_flags::cloexec)) {
                    return FD_CLOEXEC;
@@ -936,7 +969,7 @@ fcntl(int fd, int cmd, long arg) // TODO
                return 0;

            case F_GETFL:
                DEBUG_INFO("getfl\n");
                LOG(DEBUG, "[GKFS] F_GETFL {}", fd);
                ret = 0;
                if(CTX->file_map()->get(fd)->get_flag(
                           gkfs::filemap::OpenFile_flags::rdonly)) {
@@ -953,18 +986,18 @@ fcntl(int fd, int cmd, long arg) // TODO
                return ret;

            case F_SETFD:
                DEBUG_INFO("setfd\n");
                LOG(DEBUG, "[GKFS] F_SETFD {}", fd);
                CTX->file_map()->get(fd)->set_flag(
                        gkfs::filemap::OpenFile_flags::cloexec,
                        (arg & FD_CLOEXEC));
                return 0;

            case F_GETLK:

                LOG(DEBUG, "[GKFS] F_GETLK {}", fd);
                return 0;

            case F_SETLK:

                LOG(DEBUG, "[GKFS] F_SETLK {}", fd);
                return 0;

            default:
@@ -989,7 +1022,7 @@ realpath(const char* path, char* resolved_path) {

    // is gekkofs
    initializeGekko();
    /*   if(CTX->interception_enabled()) {
    if(CTX->interception_enabled()) {
        std::string resolved;

        auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved);
@@ -999,21 +1032,30 @@ realpath(const char* path, char* resolved_path) {
                return nullptr;

            case gkfs::preload::RelativizeStatus::internal:
                LOG(DEBUG, "[GKFS] {}", resolved);
                if(resolved_path == nullptr) {
                    resolved_path =
                            static_cast<char*>(malloc(resolved.size() + 1));
                    if(resolved_path == nullptr) {
                        errno = ENOMEM;
                        return nullptr;
                    }
                }
                strcpy(resolved_path, path);
                return resolved_path;

            default:
                   strcpy(resolved_path, resolved.c_str());
                   return resolved_path;
                break;
        }
    }
   */

    GKFS_FALLBACK(realpath, path, resolved_path);
}

char*
__realpath_chk(const char* path, char* resolved_path,
               __attribute__((__unused__)) size_t resolved_len) {
    GKFS_FALLBACK(realpath, path, resolved_path);
    return realpath(path, resolved_path);
}

int
@@ -1055,6 +1097,7 @@ opendir(const char* dirname) {
        std::string resolved;
        if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) ==
           PathStatus::Internal) {
            LOG(DEBUG, "[GKFS] {}", resolved);
            return gekko_opendir(resolved);
        }
    }
@@ -1068,6 +1111,7 @@ opendir64(const char* dirname) {
        std::string resolved;
        if(resolve_gkfs_path(AT_FDCWD, dirname, resolved) ==
           PathStatus::Internal) {
            LOG(DEBUG, "[GKFS] {}", resolved);
            return gekko_opendir(resolved);
        }
    }
@@ -1191,8 +1235,7 @@ closedir(DIR* dirp) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            // DEBUG_INFO("[BYPASS] >> closedir GKFS.... %p\n", (void*)
            // dirp);
            LOG(DEBUG, "[GKFS] {}", dirp->fd);
            ret = gkfs::syscall::gkfs_close(dirp->fd);
            free(dirp->path);
            free(dirp);
@@ -1211,8 +1254,7 @@ telldir(DIR* dirp) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            DEBUG_INFO("[BYPASS] >> telldir GKFS not implemented.... %p\n",
                       static_cast<void*>(dirp));
            LOG(DEBUG, "[GKFS] NOT IMPLEMENTED");
            ret = 0;
            // ret = gkfs::syscall::gkfs_telldir(dirp->fd);
            return ret;
@@ -1229,8 +1271,7 @@ seekdir(DIR* dirp, long loc) {
    initializeGekko();
    if(CTX->interception_enabled()) {
        if(CTX->file_map()->exist(dirp->fd)) {
            DEBUG_INFO("[BYPASS] >> seekdir GKFS no implemented.... %p %ld\n",
                       static_cast<void*>(dirp), loc);
            LOG(DEBUG, "[GKFS] NOT IMPLEMENTED");
            return;
        }
    }
@@ -1342,6 +1383,7 @@ int
fseek(FILE* stream, long int offset, int whence) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        return gkfs::syscall::gkfs_lseek(stream->_fileno, offset, whence);
    }

@@ -1352,6 +1394,7 @@ long
ftell(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        return gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR);
    }

@@ -1362,6 +1405,7 @@ void
rewind(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_SET);
    }
    GKFS_FALLBACK(rewind, stream)
@@ -1372,6 +1416,7 @@ fclose(FILE* stream) {

    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        auto ret = gkfs::syscall::gkfs_close(stream->_fileno);
        // should I do a fclose (stream)?
        free(stream);
@@ -1386,6 +1431,7 @@ int
feof(FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        off_t cur = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_CUR);
        off_t end = gkfs::syscall::gkfs_lseek(stream->_fileno, 0, SEEK_END);
        gkfs::syscall::gkfs_lseek(stream->_fileno, cur, SEEK_SET);
@@ -1407,6 +1453,7 @@ fgets(char* str, int n, FILE* stream) {
    initializeGekko();
    if(CTX->interception_enabled() && CTX->file_map()->exist(stream->_fileno)) {
        // read str n chars
        LOG(DEBUG, "[GKFS] {}", stream->_fileno);
        auto l = gkfs::syscall::gkfs_read(stream->_fileno, str, n);
        if(l == 0) {
            return NULL;