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

Syscall Wrapper

parent f5e19305
Loading
Loading
Loading
Loading
Loading
+72 −53
Original line number Original line Diff line number Diff line
@@ -56,6 +56,19 @@ with_errno(int ret) {


} // namespace
} // namespace


template <class... Args>
inline long
syscall_no_intercept_wrapper(long syscall_number, Args... args) {
    long result;
    int error;
    result = syscall_no_intercept(syscall_number, args...);
    error = syscall_error_code(result);
    if(error != 0) {
        return -error;
    }
    return result;
}

namespace gkfs::hook {
namespace gkfs::hook {


int
int
@@ -103,7 +116,7 @@ hook_close(int fd) {
        return 0;
        return 0;
    }
    }


    return syscall_no_intercept(SYS_close, fd);
    return syscall_no_intercept_wrapper(SYS_close, fd);
}
}


int
int
@@ -116,7 +129,8 @@ hook_stat(const char* path, struct stat* buf) {
    if(CTX->relativize_path(path, rel_path, false)) {
    if(CTX->relativize_path(path, rel_path, false)) {
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
    }
    }
    return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf);

    return syscall_no_intercept_wrapper(SYS_stat, rel_path.c_str(), buf);
}
}


#ifdef STATX_TYPE
#ifdef STATX_TYPE
@@ -167,7 +181,8 @@ hook_lstat(const char* path, struct stat* buf) {
    if(CTX->relativize_path(path, rel_path)) {
    if(CTX->relativize_path(path, rel_path)) {
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
    }
    }
    return syscall_no_intercept(SYS_lstat, rel_path.c_str(), buf);
    return syscall_no_intercept_wrapper(SYS_lstat, rel_path.c_str(), buf);
    ;
}
}


int
int
@@ -179,7 +194,7 @@ hook_fstat(unsigned int fd, struct stat* buf) {
        auto path = CTX->file_map()->get(fd)->path();
        auto path = CTX->file_map()->get(fd)->path();
        return with_errno(gkfs::syscall::gkfs_stat(path, buf));
        return with_errno(gkfs::syscall::gkfs_stat(path, buf));
    }
    }
    return syscall_no_intercept(SYS_fstat, fd, buf);
    return syscall_no_intercept_wrapper(SYS_fstat, fd, buf);
}
}


int
int
@@ -197,12 +212,12 @@ hook_fstatat(int dirfd, const char* cpath, struct stat* buf, int flags) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf,
            return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd, cpath,
                                        flags);
                                                buf, flags);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_newfstatat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_newfstatat, dirfd,
                                        buf, flags);
                                                resolved.c_str(), buf, flags);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -225,7 +240,7 @@ hook_read(unsigned int fd, void* buf, size_t count) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_read(fd, buf, count));
        return with_errno(gkfs::syscall::gkfs_read(fd, buf, count));
    }
    }
    return syscall_no_intercept(SYS_read, fd, buf, count);
    return syscall_no_intercept_wrapper(SYS_read, fd, buf, count);
}
}


int
int
@@ -239,7 +254,7 @@ hook_pread(unsigned int fd, char* buf, size_t count, loff_t pos) {
    }
    }
    /* Since kernel 2.6: pread() became pread64(), and pwrite() became
    /* Since kernel 2.6: pread() became pread64(), and pwrite() became
     * pwrite64(). */
     * pwrite64(). */
    return syscall_no_intercept(SYS_pread64, fd, buf, count, pos);
    return syscall_no_intercept_wrapper(SYS_pread64, fd, buf, count, pos);
}
}


int
int
@@ -251,7 +266,7 @@ hook_readv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_readv(fd, iov, iovcnt));
        return with_errno(gkfs::syscall::gkfs_readv(fd, iov, iovcnt));
    }
    }
    return syscall_no_intercept(SYS_readv, fd, iov, iovcnt);
    return syscall_no_intercept_wrapper(SYS_readv, fd, iov, iovcnt);
}
}


int
int
@@ -267,7 +282,7 @@ hook_preadv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt,
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_preadv(fd, iov, iovcnt, pos_l));
        return with_errno(gkfs::syscall::gkfs_preadv(fd, iov, iovcnt, pos_l));
    }
    }
    return syscall_no_intercept(SYS_preadv, fd, iov, iovcnt, pos_l);
    return syscall_no_intercept_wrapper(SYS_preadv, fd, iov, iovcnt, pos_l);
}
}


int
int
@@ -279,7 +294,7 @@ hook_write(unsigned int fd, const char* buf, size_t count) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_write(fd, buf, count));
        return with_errno(gkfs::syscall::gkfs_write(fd, buf, count));
    }
    }
    return syscall_no_intercept(SYS_write, fd, buf, count);
    return syscall_no_intercept_wrapper(SYS_write, fd, buf, count);
}
}


int
int
@@ -293,7 +308,7 @@ hook_pwrite(unsigned int fd, const char* buf, size_t count, loff_t pos) {
    }
    }
    /* Since kernel 2.6: pread() became pread64(), and pwrite() became
    /* Since kernel 2.6: pread() became pread64(), and pwrite() became
     * pwrite64(). */
     * pwrite64(). */
    return syscall_no_intercept(SYS_pwrite64, fd, buf, count, pos);
    return syscall_no_intercept_wrapper(SYS_pwrite64, fd, buf, count, pos);
}
}


int
int
@@ -305,7 +320,7 @@ hook_writev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_writev(fd, iov, iovcnt));
        return with_errno(gkfs::syscall::gkfs_writev(fd, iov, iovcnt));
    }
    }
    return syscall_no_intercept(SYS_writev, fd, iov, iovcnt);
    return syscall_no_intercept_wrapper(SYS_writev, fd, iov, iovcnt);
}
}


int
int
@@ -321,7 +336,7 @@ hook_pwritev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt,
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_pwritev(fd, iov, iovcnt, pos_l));
        return with_errno(gkfs::syscall::gkfs_pwritev(fd, iov, iovcnt, pos_l));
    }
    }
    return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt, pos_l);
    return syscall_no_intercept_wrapper(SYS_pwritev, fd, iov, iovcnt, pos_l);
}
}


int
int
@@ -339,11 +354,12 @@ hook_unlinkat(int dirfd, const char* cpath, int flags) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags);
            return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd, cpath,
                                                flags);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_unlinkat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_unlinkat, dirfd,
                                        flags);
                                                resolved.c_str(), flags);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -378,11 +394,11 @@ hook_symlinkat(const char* oldname, int newdfd, const char* newname) {
            CTX->relativize_fd_path(newdfd, newname, newname_resolved, false);
            CTX->relativize_fd_path(newdfd, newname, newname_resolved, false);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_symlinkat, oldname, newdfd,
            return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd,
                                                newname);
                                                newname);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_symlinkat, oldname, newdfd,
            return syscall_no_intercept_wrapper(SYS_symlinkat, oldname, newdfd,
                                                newname_resolved.c_str());
                                                newname_resolved.c_str());


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
@@ -412,7 +428,7 @@ hook_access(const char* path, int mask) {
        }
        }
        return ret;
        return ret;
    }
    }
    return syscall_no_intercept(SYS_access, rel_path.c_str(), mask);
    return syscall_no_intercept_wrapper(SYS_access, rel_path.c_str(), mask);
}
}


int
int
@@ -425,11 +441,12 @@ hook_faccessat(int dirfd, const char* cpath, int mode) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode);
            return syscall_no_intercept_wrapper(SYS_faccessat, dirfd, cpath,
                                                mode);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_faccessat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_faccessat, dirfd,
                                        mode);
                                                resolved.c_str(), mode);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -460,7 +477,7 @@ hook_lseek(unsigned int fd, off_t offset, unsigned int whence) {
        LOG(DEBUG, "{}() returning {}", __func__, off_ret);
        LOG(DEBUG, "{}() returning {}", __func__, off_ret);
        return off_ret;
        return off_ret;
    }
    }
    return syscall_no_intercept(SYS_lseek, fd, offset, whence);
    return syscall_no_intercept_wrapper(SYS_lseek, fd, offset, whence);
}
}


int
int
@@ -472,7 +489,7 @@ hook_truncate(const char* path, long length) {
    if(CTX->relativize_path(path, rel_path)) {
    if(CTX->relativize_path(path, rel_path)) {
        return with_errno(gkfs::syscall::gkfs_truncate(rel_path, length));
        return with_errno(gkfs::syscall::gkfs_truncate(rel_path, length));
    }
    }
    return syscall_no_intercept(SYS_truncate, rel_path.c_str(), length);
    return syscall_no_intercept_wrapper(SYS_truncate, rel_path.c_str(), length);
}
}


int
int
@@ -484,7 +501,7 @@ hook_ftruncate(unsigned int fd, unsigned long length) {
        auto path = CTX->file_map()->get(fd)->path();
        auto path = CTX->file_map()->get(fd)->path();
        return with_errno(gkfs::syscall::gkfs_truncate(path, length));
        return with_errno(gkfs::syscall::gkfs_truncate(path, length));
    }
    }
    return syscall_no_intercept(SYS_ftruncate, fd, length);
    return syscall_no_intercept_wrapper(SYS_ftruncate, fd, length);
}
}


int
int
@@ -495,7 +512,7 @@ hook_dup(unsigned int fd) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_dup(fd));
        return with_errno(gkfs::syscall::gkfs_dup(fd));
    }
    }
    return syscall_no_intercept(SYS_dup, fd);
    return syscall_no_intercept_wrapper(SYS_dup, fd);
}
}


int
int
@@ -506,7 +523,7 @@ hook_dup2(unsigned int oldfd, unsigned int newfd) {
    if(CTX->file_map()->exist(oldfd)) {
    if(CTX->file_map()->exist(oldfd)) {
        return with_errno(gkfs::syscall::gkfs_dup2(oldfd, newfd));
        return with_errno(gkfs::syscall::gkfs_dup2(oldfd, newfd));
    }
    }
    return syscall_no_intercept(SYS_dup2, oldfd, newfd);
    return syscall_no_intercept_wrapper(SYS_dup2, oldfd, newfd);
}
}


int
int
@@ -521,7 +538,7 @@ hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) {
        LOG(WARNING, "{}() Not supported", __func__);
        LOG(WARNING, "{}() Not supported", __func__);
        return -ENOTSUP;
        return -ENOTSUP;
    }
    }
    return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags);
    return syscall_no_intercept_wrapper(SYS_dup3, oldfd, newfd, flags);
}
}


int
int
@@ -533,7 +550,7 @@ hook_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_getdents(fd, dirp, count));
        return with_errno(gkfs::syscall::gkfs_getdents(fd, dirp, count));
    }
    }
    return syscall_no_intercept(SYS_getdents, fd, dirp, count);
    return syscall_no_intercept_wrapper(SYS_getdents, fd, dirp, count);
}
}




@@ -547,7 +564,7 @@ hook_getdents64(unsigned int fd, struct linux_dirent64* dirp,
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_getdents64(fd, dirp, count));
        return with_errno(gkfs::syscall::gkfs_getdents64(fd, dirp, count));
    }
    }
    return syscall_no_intercept(SYS_getdents64, fd, dirp, count);
    return syscall_no_intercept_wrapper(SYS_getdents64, fd, dirp, count);
}
}




@@ -561,11 +578,12 @@ hook_mkdirat(int dirfd, const char* cpath, mode_t mode) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd,
                                        mode);
                                                resolved.c_str(), mode);


        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode);
            return syscall_no_intercept_wrapper(SYS_mkdirat, dirfd, cpath,
                                                mode);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -590,11 +608,12 @@ hook_fchmodat(int dirfd, const char* cpath, mode_t mode) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode);
            return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd, cpath,
                                                mode);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_fchmodat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_fchmodat, dirfd,
                                        mode);
                                                resolved.c_str(), mode);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -618,7 +637,7 @@ hook_fchmod(unsigned int fd, mode_t mode) {
        LOG(WARNING, "{}() operation not supported", __func__);
        LOG(WARNING, "{}() operation not supported", __func__);
        return -ENOTSUP;
        return -ENOTSUP;
    }
    }
    return syscall_no_intercept(SYS_fchmod, fd, mode);
    return syscall_no_intercept_wrapper(SYS_fchmod, fd, mode);
}
}


int
int
@@ -681,7 +700,7 @@ hook_fchdir(unsigned int fd) {
            return -(se.code().value());
            return -(se.code().value());
        }
        }
    } else {
    } else {
        long ret = syscall_no_intercept(SYS_fchdir, fd);
        long ret = syscall_no_intercept_wrapper(SYS_fchdir, fd);
        if(ret < 0) {
        if(ret < 0) {
            throw std::system_error(
            throw std::system_error(
                    syscall_error_code(ret), std::system_category(),
                    syscall_error_code(ret), std::system_category(),
@@ -719,12 +738,12 @@ hook_readlinkat(int dirfd, const char* cpath, char* buf, int bufsiz) {
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    switch(rstatus) {
    switch(rstatus) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf,
            return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd, cpath,
                                        bufsiz);
                                                buf, bufsiz);


        case gkfs::preload::RelativizeStatus::external:
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_readlinkat, dirfd, resolved.c_str(),
            return syscall_no_intercept_wrapper(SYS_readlinkat, dirfd,
                                        buf, bufsiz);
                                                resolved.c_str(), buf, bufsiz);


        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;
            return -ENOTDIR;
@@ -746,7 +765,7 @@ hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) {
        arg);
        arg);


    if(!CTX->file_map()->exist(fd)) {
    if(!CTX->file_map()->exist(fd)) {
        return syscall_no_intercept(SYS_fcntl, fd, cmd, arg);
        return syscall_no_intercept_wrapper(SYS_fcntl, fd, cmd, arg);
    }
    }
    int ret;
    int ret;
    switch(cmd) {
    switch(cmd) {
@@ -864,8 +883,8 @@ hook_renameat(int olddfd, const char* oldname, int newdfd, const char* newname,
            return -EINVAL;
            return -EINVAL;
    }
    }


    return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd,
    return syscall_no_intercept_wrapper(SYS_renameat2, olddfd, oldpath_pass,
                                newpath_pass, flags);
                                        newdfd, newpath_pass, flags);
}
}


int
int
@@ -878,7 +897,7 @@ hook_statfs(const char* path, struct statfs* buf) {
    if(CTX->relativize_path(path, rel_path)) {
    if(CTX->relativize_path(path, rel_path)) {
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
    }
    }
    return syscall_no_intercept(SYS_statfs, rel_path.c_str(), buf);
    return syscall_no_intercept_wrapper(SYS_statfs, rel_path.c_str(), buf);
}
}


int
int
@@ -889,7 +908,7 @@ hook_fstatfs(unsigned int fd, struct statfs* buf) {
    if(CTX->file_map()->exist(fd)) {
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
    }
    }
    return syscall_no_intercept(SYS_fstatfs, fd, buf);
    return syscall_no_intercept_wrapper(SYS_fstatfs, fd, buf);
}
}


/* The function should broadcast a flush message (pmem_persist i.e.) if the
/* The function should broadcast a flush message (pmem_persist i.e.) if the
@@ -904,7 +923,7 @@ hook_fsync(unsigned int fd) {
        return 0;
        return 0;
    }
    }


    return syscall_no_intercept(SYS_fsync, fd);
    return syscall_no_intercept_wrapper(SYS_fsync, fd);
}
}


} // namespace gkfs::hook
} // namespace gkfs::hook
+40 −13
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
    const long args[gkfs::syscall::MAX_ARGS] = {arg0, arg1, arg2,
    const long args[gkfs::syscall::MAX_ARGS] = {arg0, arg1, arg2,
                                                arg3, arg4, arg5};
                                                arg3, arg4, arg5};
#endif
#endif
    int syserror = 0;


    LOG(SYSCALL,
    LOG(SYSCALL,
        gkfs::syscall::from_internal_code | gkfs::syscall::to_hook |
        gkfs::syscall::from_internal_code | gkfs::syscall::to_hook |
@@ -96,9 +97,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
            *result = syscall_no_intercept(
            *result = syscall_no_intercept(
                    syscall_number, reinterpret_cast<char*>(arg0),
                    syscall_number, reinterpret_cast<char*>(arg0),
                    static_cast<int>(arg1), static_cast<mode_t>(arg2));
                    static_cast<int>(arg1), static_cast<mode_t>(arg2));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            } else {
                *result = -syserror;
            }
            }


            break;
            break;
@@ -107,9 +111,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
            *result = syscall_no_intercept(
            *result = syscall_no_intercept(
                    syscall_number, reinterpret_cast<const char*>(arg0),
                    syscall_number, reinterpret_cast<const char*>(arg0),
                    O_WRONLY | O_CREAT | O_TRUNC, static_cast<mode_t>(arg1));
                    O_WRONLY | O_CREAT | O_TRUNC, static_cast<mode_t>(arg1));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            } else {
                *result = -syserror;
            }
            }


            break;
            break;
@@ -119,19 +126,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
                    syscall_number, static_cast<int>(arg0),
                    syscall_number, static_cast<int>(arg0),
                    reinterpret_cast<const char*>(arg1), static_cast<int>(arg2),
                    reinterpret_cast<const char*>(arg1), static_cast<int>(arg2),
                    static_cast<mode_t>(arg3));
                    static_cast<mode_t>(arg3));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            } else {
                *result = -syserror;
            }
            }

            break;
            break;


        case SYS_epoll_create:
        case SYS_epoll_create:
            *result = syscall_no_intercept(syscall_number,
            *result = syscall_no_intercept(syscall_number,
                                           static_cast<int>(arg0));
                                           static_cast<int>(arg0));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            } else {
                *result = -syserror;
            }
            }


            break;
            break;
@@ -139,9 +151,12 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
        case SYS_epoll_create1:
        case SYS_epoll_create1:
            *result = syscall_no_intercept(syscall_number,
            *result = syscall_no_intercept(syscall_number,
                                           static_cast<int>(arg0));
                                           static_cast<int>(arg0));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            } else {
                *result = -syserror;
            }
            }


            break;
            break;
@@ -149,8 +164,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
        case SYS_dup:
        case SYS_dup:
            *result = syscall_no_intercept(syscall_number,
            *result = syscall_no_intercept(syscall_number,
                                           static_cast<unsigned int>(arg0));
                                           static_cast<unsigned int>(arg0));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            }
            }


@@ -160,8 +176,9 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
            *result = syscall_no_intercept(syscall_number,
            *result = syscall_no_intercept(syscall_number,
                                           static_cast<unsigned int>(arg0),
                                           static_cast<unsigned int>(arg0),
                                           static_cast<unsigned int>(arg1));
                                           static_cast<unsigned int>(arg1));
            syserror = syscall_error_code(*result);


            if(*result >= 0) {
            if(syserror == 0) {
                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            }
            }


@@ -172,7 +189,11 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
                    syscall_number, static_cast<unsigned int>(arg0),
                    syscall_number, static_cast<unsigned int>(arg0),
                    static_cast<unsigned int>(arg1), static_cast<int>(arg2));
                    static_cast<unsigned int>(arg1), static_cast<int>(arg2));


            if(*result >= 0) {
            syserror = syscall_error_code(*result);

            if(syserror == 0) {


                *result = CTX->register_internal_fd(*result);
                *result = CTX->register_internal_fd(*result);
            }
            }


@@ -370,18 +391,24 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3,
            *result =
            *result =
                    syscall_no_intercept(syscall_number, static_cast<int>(arg0),
                    syscall_no_intercept(syscall_number, static_cast<int>(arg0),
                                         static_cast<int>(arg1), arg2);
                                         static_cast<int>(arg1), arg2);
            syserror = syscall_error_code(*result);


            if(*result >= 0 && (static_cast<int>(arg1) == F_DUPFD ||
            if(syserror == 0) {


                if((static_cast<int>(arg1) == F_DUPFD ||
                    static_cast<int>(arg1) == F_DUPFD_CLOEXEC)) {
                    static_cast<int>(arg1) == F_DUPFD_CLOEXEC)) {
                    *result = CTX->register_internal_fd(*result);
                    *result = CTX->register_internal_fd(*result);
                }
                }
            }
            break;
            break;


        case SYS_close:
        case SYS_close:
            *result = syscall_no_intercept(syscall_number,
            *result = syscall_no_intercept(syscall_number,
                                           static_cast<int>(arg0));
                                           static_cast<int>(arg0));
            syserror = syscall_error_code(*result);


            if(*result == 0) {
            if(syserror == 0) {
                CTX->unregister_internal_fd(arg0);
                CTX->unregister_internal_fd(arg0);
            }
            }
            break;
            break;
+2 −2
Original line number Original line Diff line number Diff line
@@ -395,8 +395,8 @@ PreloadContext::protect_user_fds() {


    const auto fd_is_open = [](int fd) -> bool {
    const auto fd_is_open = [](int fd) -> bool {
        const int ret = ::syscall_no_intercept(SYS_fcntl, fd, F_GETFD);
        const int ret = ::syscall_no_intercept(SYS_fcntl, fd, F_GETFD);
        return ::syscall_error_code(ret) == 0 ||
        const int error = ::syscall_error_code(ret);
               ::syscall_error_code(ret) != EBADF;
        return error == 0 || error != EBADF;
    };
    };


    for(int fd = 0; fd < MAX_USER_FDS; ++fd) {
    for(int fd = 0; fd < MAX_USER_FDS; ++fd) {