Unverified Commit 0e62229e authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Intercept readlinkat

parent 24af9d3b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@ strong_alias(intcp_symlink, symlink)
strong_alias(intcp_symlink, __symlink)
int intcp_symlinkat(const char* oldname, int newfd, const char* newname) noexcept;
strong_alias(intcp_symlinkat, symlinkat)
ssize_t intcp_readlink(const char * cpath, char * buf, size_t bufsize) noexcept;
strong_alias(intcp_readlink, readlink)
ssize_t intcp_readlinkat(int dirfd, const char * cpath, char * buf, size_t bufsize) noexcept;
strong_alias(intcp_readlinkat, readlinkat)

int intcp_statvfs(const char *path, struct statvfs *buf) noexcept;
strong_alias(intcp_statvfs, statvfs)
+2 −0
Original line number Diff line number Diff line
@@ -115,6 +115,8 @@ extern void* libc_link;
extern void* libc_linkat;
extern void* libc_symlinkat;

extern void* libc_readlinkat;

extern void* libc_realpath;

void init_passthrough_if_needed();
+41 −0
Original line number Diff line number Diff line
@@ -1474,6 +1474,47 @@ int intcp_symlinkat(const char* oldname, int newdfd, const char* newname) noexce
    }
}

ssize_t intcp_readlink(const char * cpath, char * buf, size_t bufsize) noexcept {
    return intcp_readlinkat(AT_FDCWD, cpath, buf, bufsize);
}

ssize_t intcp_readlinkat(int dirfd, const char * cpath, char * buf, size_t bufsize) noexcept {
    init_passthrough_if_needed();
    if(!CTX->interception_enabled()) {
        return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize);
    }

    CTX->log()->trace("{}() called with path '{}' dirfd {}, bufsize {}",
                      __func__, cpath, dirfd, bufsize);

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    switch(rstatus) {
        case RelativizeStatus::fd_unknown:
            return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize);

        case RelativizeStatus::external:
            return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize);

        case RelativizeStatus::fd_not_a_dir:
            errno = ENOTDIR;
            return -1;

        case RelativizeStatus::internal:
#ifdef HAS_SYMLINKS
            return adafs_readlink(resolved, buf, bufsize);
#else
            CTX->log()->warn("{}() symlink not supported", __func__);
            errno = EINVAL;
            return -1;
#endif
        default:
            CTX->log()->error("{}() relativize status unknown: {}", __func__);
            errno = EINVAL;
            return -1;
    }
}

char *realpath(const char *path, char *resolved_path) {
    init_passthrough_if_needed();
    if(!CTX->interception_enabled()) {
+4 −0
Original line number Diff line number Diff line
@@ -116,6 +116,8 @@ void* libc_link;
void* libc_linkat;
void* libc_symlinkat;

void* libc_readlinkat;

void* libc_realpath;


@@ -230,6 +232,8 @@ void init_passthrough_() {
    libc_linkat = dlsym(libc, "linkat");
    libc_symlinkat = dlsym(libc, "symlinkat");

    libc_readlinkat = dlsym(libc, "readlinkat");

    libc_realpath = dlsym(libc, "realpath");

}