Перехватывает системный вызов openat() для GNU tar

Я пытаюсь перехватить openat() системный вызов в Linux с использованием пользовательской общей библиотеки, которую я могу загрузить через LD_PRELOAD, Пример intercept-openat.c имеет это содержание:

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>

int (*_original_openat)(int dirfd, const char *pathname, int flags, mode_t mode);

void init(void) __attribute__((constructor));
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

void init(void)
{
        _original_openat = (int (*)(int, const char *, int, mode_t))
                dlsym(RTLD_NEXT, "openat");
}

int openat(int dirfd, const char *pathname, int flags, mode_t mode)
{
        fprintf(stderr, "intercepting openat()...\n");
        return _original_openat(dirfd, pathname, flags, mode);
}

Я компилирую это через gcc -fPIC -Wall -shared -o intercept-openat.so intercept-openat.c -ldl, Затем, когда я запускаю этот небольшой пример программы:

int main(int argc, char *argv[])
{
    int fd;
    fd = openat(AT_FDCWD, "/home/feh/.vimrc", O_RDONLY);
    if(fd == -1)
        return -1;
    close(fd);
    return 0;
}

openat() вызов переписывается через библиотеку:

$ LD_PRELOAD=./intercept-openat.so ./openat 
intercepting openat()...

Однако то же самое не происходит с GNU tar, даже если он использует тот же системный вызов:

$ strace -e openat tar cf /tmp/t.tgz .vimrc  
openat(AT_FDCWD, ".vimrc", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC) = 4
$ LD_PRELOAD=./intercept-openat.so tar cf /tmp/t.tgz .vimrc

Так что обычай openat() от intercept-openat.so не вызывается. Это почему?

1 ответ

Решение

Он использует тот же системный вызов, но, очевидно, не вызывает его через ту же функцию C. В качестве альтернативы, это может быть так, но это статически связано.

В любом случае, я думаю, вы доказали, что он никогда не динамически связывает имена функций "openat". Если вы все еще хотите использовать эту опцию, вы можете посмотреть, ссылается ли она на конкретную версию этой функции, но это еще не все.

Вы все еще можете перехватить системный вызов, написав свою программу для использования ptrace, Это тот же интерфейс, который используется strace и gdb. Это будет иметь более высокую производительность, хотя.

http://linux.die.net/man/2/ptrace

Другие вопросы по тегам