Verified Commit f782a743 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

intercept renameat

parent d6c78bdb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ int hook_fchdir(unsigned int fd);
int hook_getcwd(char * buf, unsigned long size);
int hook_readlinkat(int dirfd, const char * cpath, char * buf, int bufsiz);
int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
int hook_renameat(int olddfd, const char * oldname, int newdfd, const char * newname,
                  unsigned int flags);


#endif
+58 −0
Original line number Diff line number Diff line
@@ -555,3 +555,61 @@ int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) {
            return -ENOTSUP;
    }
}

int hook_renameat(int olddfd, const char * oldname,
                  int newdfd, const char * newname,
                  unsigned int flags) {

    CTX->log()->trace("{}() called with olddfd {}, oldname: '{}', newfd {}, newname '{}', flags {}",
                      __func__, olddfd, oldname, newdfd, newname, flags);

    const char * oldpath_pass;
    std::string oldpath_resolved;
    auto oldpath_status = CTX->relativize_fd_path(olddfd, oldname, oldpath_resolved);
    switch(oldpath_status) {
        case RelativizeStatus::fd_unknown:
            oldpath_pass = oldname;
            break;

        case RelativizeStatus::external:
            oldpath_pass = oldpath_resolved.c_str();
            break;

        case RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case RelativizeStatus::internal:
            CTX->log()->warn("{}() not supported", __func__);
            return -ENOTSUP;

        default:
            CTX->log()->error("{}() relativize status unknown", __func__);
            return -EINVAL;
    }

    const char * newpath_pass;
    std::string newpath_resolved;
    auto newpath_status = CTX->relativize_fd_path(newdfd, newname, newpath_resolved);
    switch(newpath_status) {
        case RelativizeStatus::fd_unknown:
            newpath_pass = newname;
            break;

        case RelativizeStatus::external:
            newpath_pass = newpath_resolved.c_str();
            break;

        case RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case RelativizeStatus::internal:
            CTX->log()->warn("{}() not supported", __func__);
            return -ENOTSUP;

        default:
            CTX->log()->error("{}() relativize status unknown", __func__);
            return -EINVAL;
    }

   return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags);
}
+24 −0
Original line number Diff line number Diff line
@@ -242,6 +242,30 @@ static inline int hook(long syscall_number,
                             static_cast<unsigned long>(arg2));
        break;

    case SYS_rename:
        *result = hook_renameat(AT_FDCWD,
                                reinterpret_cast<const char *>(arg0),
                                AT_FDCWD,
                                reinterpret_cast<const char *>(arg1),
                                0);
        break;

    case SYS_renameat:
        *result = hook_renameat(static_cast<int>(arg0),
                                reinterpret_cast<const char *>(arg1),
                                static_cast<int>(arg2),
                                reinterpret_cast<const char *>(arg3),
                                0);
        break;

    case SYS_renameat2:
        *result = hook_renameat(static_cast<int>(arg0),
                                reinterpret_cast<const char *>(arg1),
                                static_cast<int>(arg2),
                                reinterpret_cast<const char *>(arg3),
                                static_cast<unsigned int>(arg4));
        break;
    
    default:
        /*
         * Ignore any other syscalls