перехватывает системный вызов openat () для GNU tar - PullRequest
5 голосов
/ 06 февраля 2012

Я пытаюсь перехватить системный вызов 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 Ответ

2 голосов
/ 06 февраля 2012

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

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

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

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

...