Unverified Commit 303c6619 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

intercept dup, dup2, dup3

parent c294d9e0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ int hook_write(int fd, void* buf, size_t count);
int hook_unlink(const char* path);
int hook_access(const char* path, int mask);
int hook_lseek(unsigned int fd, off_t offset, unsigned int whence);
int hook_dup(unsigned int fd);
int hook_dup2(unsigned int oldfd, unsigned int newfd);
int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags);


#endif
+25 −0
Original line number Diff line number Diff line
@@ -156,3 +156,28 @@ int hook_lseek(unsigned int fd, off_t offset, unsigned int whence) {
   return syscall_no_intercept(SYS_lseek, fd, offset, whence);
}

int hook_dup(unsigned int fd) {
    CTX->log()->trace("{}() called with oldfd {}", __func__, fd);
    if (CTX->file_map()->exist(fd)) {
        return with_errno(adafs_dup(fd));
    }
    return syscall_no_intercept(SYS_dup, fd);
}

int hook_dup2(unsigned int oldfd, unsigned int newfd) {
    CTX->log()->trace("{}() called with fd {} newfd {}", __func__, oldfd, newfd);
    if (CTX->file_map()->exist(oldfd)) {
        return with_errno(adafs_dup2(oldfd, newfd));
    }
    return syscall_no_intercept(SYS_dup2, oldfd, newfd);
}

int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) {
    if (CTX->file_map()->exist(oldfd)) {
        // TODO implement O_CLOEXEC flag first which is used with fcntl(2)
        // It is in glibc since kernel 2.9. So maybe not that important :)
        CTX->log()->warn("{}() Not supported", __func__);
        return -ENOTSUP;
    }
    return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags);
}
+16 −0
Original line number Diff line number Diff line
@@ -96,6 +96,22 @@ static inline int hook(long syscall_number,
                             static_cast<unsigned int>(arg2));
        break;

    case SYS_dup:
        *result = hook_dup(static_cast<unsigned int>(arg0));
        break;

    case SYS_dup2:
        *result = hook_dup2(static_cast<unsigned int>(arg0),
                            static_cast<unsigned int>(arg1));
        break;

    case SYS_dup3:
        *result = hook_dup3(static_cast<unsigned int>(arg0),
                            static_cast<unsigned int>(arg1),
                            static_cast<int>(arg2));
        break;

    default:
        /*
         * Ignore any other syscalls
         * i.e.: pass them on to the kernel