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

intercept mkdir/mkdirat

parent 4c8fc68a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ 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);
int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count);
int hook_mkdirat(int dirfd, const char * cpath, mode_t mode);


#endif
+40 −0
Original line number Diff line number Diff line
@@ -198,3 +198,43 @@ int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count
    }
    return syscall_no_intercept(SYS_getdents, fd, dirp, count);
}

int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) {
    if(cpath == nullptr || cpath[0] == '\0') {
        CTX->log()->error("{}() path is invalid", __func__);
        return -EINVAL;
    }

    CTX->log()->trace("{}() called with fd: {}, path: {}, mode: {}",
                      __func__, dirfd, cpath, mode);

    std::string resolved;

    if((cpath[0] == PSP) || (dirfd == AT_FDCWD)) {
        // cpath is absolute or relative to CWD
        if (CTX->relativize_path(cpath, resolved)) {
            return with_errno(adafs_mk_node(resolved, mode | S_IFDIR));
        }
    } else {
        // cpath is relative
        if(!(CTX->file_map()->exist(dirfd))) {
            //TODO relative cpath could still lead to our FS
            return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode);
        }

        auto dir = CTX->file_map()->get_dir(dirfd);
        if(dir == nullptr) {
            CTX->log()->error("{}() dirfd is not a directory ", __func__);
            return -ENOTDIR;
        }

        std::string path = CTX->mountdir();
        path.append(dir->path());
        path.push_back(PSP);
        path.append(cpath);
        if(resolve_path(path, resolved)) {
            return with_errno(adafs_mk_node(resolved, mode | S_IFDIR));
        }
    }
    return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode);
}
+12 −0
Original line number Diff line number Diff line
@@ -104,6 +104,18 @@ static inline int hook(long syscall_number,
                                static_cast<unsigned int>(arg2));
        break;

    case SYS_mkdirat:
        *result = hook_mkdirat(static_cast<unsigned int>(arg0),
                               reinterpret_cast<const char *>(arg1),
                               static_cast<mode_t>(arg2));
        break;

    case SYS_mkdir:
        *result = hook_mkdirat(AT_FDCWD,
                               reinterpret_cast<const char *>(arg0),
                               static_cast<mode_t>(arg1));
        break;

    default:
        /*
         * Ignore any other syscalls