Перехват открытого системного вызова в C при вызове через fopenLinux

Ответить Пред. темаСлед. тема
Anonymous
 Перехват открытого системного вызова в C при вызове через fopen

Сообщение Anonymous »

Я пытаюсь запрограммировать (ограниченное) перенаправление файловой системы в памяти с помощью перехвата libc/syscall и возврата файловых дескрипторов, созданных memfd_create, для виртуализированных файлов. На этапе подготовки у меня есть следующий файл test.c:

Код: Выделить всё

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 

/*
FILE* fopen(const char *path, const char *mode)
{
typedef FILE* (*orig_fopen_func_type)(const char *path, const char *mode);
fprintf(stderr, "log_file_access_preload: fopen(\"%s\", \"%s\")\n", path, mode);
orig_fopen_func_type orig_func = (orig_fopen_func_type)dlsym(RTLD_NEXT, "fopen");
return orig_func(path, mode);
}
*/

int open(const char *path, int flags)
{
typedef int (*orig_func_type)(const char *pathname, int flags);
fprintf(stderr, "log_file_access_preload: open(\"%s\", %d)\n", path, flags);
orig_func_type orig_func = (orig_func_type)dlsym(RTLD_NEXT, "open");
return orig_func(path, flags);
}
int open64(const char *path, int flags)
{
typedef int (*orig_func_type)(const char *pathname, int flags);
fprintf(stderr, "log_file_access_preload: open64(\"%s\", %d)\n", path, flags);
orig_func_type orig_func = (orig_func_type)dlsym(RTLD_NEXT, "open64");
return orig_func(path, flags);
}
//TODO: int openat(int dirfd, const char *path, int flags, mode_t mode)
int openat(int dirfd, const char *path, int flags)
{
typedef int (*orig_func_type)(int dirfd, const char *pathname, int flags);
fprintf(stderr, "log_file_access_preload:  openat(%d, \"%s\", %d)\n", dirfd, path, flags);
orig_func_type orig_func = (orig_func_type)dlsym(RTLD_NEXT, "openat");
return orig_func(dirfd, path, flags);
}

int main()
{
(void)fopen("test.txt", "r");
}
Компиляция как gcc test.c (в Ubuntu 22.04) и вызов его как ./a.out ничего не печатает (если я раскомментирую fopen
Компиляция как gcc test.c (в Ubuntu 22.04) и вызов его как ./a.out ничего не печатает (если я раскомментирую fopen
Компиляция как gcc test.c (в Ubuntu 22.04) и вызов его как ./a.out ничего не печатает (если я раскомментирую fopen
Компиляция как gcc test.c (в Ubuntu 22.04) и вызов его как ./a.out) ничего не печатает (если я раскомментирую fopen
Компиляция как gcc test.c (в Ubuntu 22.04) и вызов его как ./a.out ничего не печатает code> перехват, то работает но к сожалению fmemopen не позволяет создать соответствующий fd/ с ним, в отличие от shm_open и memfd_create, поэтому я предпочитаю переопределять только вызовы open)
Если я поставлю аналогичный перехват в общей библиотеке с LD_PRELOAD она по-прежнему не вызывается для вызова open (опять же, это работает, если я перехватываю fopen).
Если я проведу трассировку -f ./a.out, то на выходе я получу openat(AT_FDCWD, "test.txt", O_RDONLY) = -1 ENOENT (Нет такого файла или каталога), так open вызывается?

Код: Выделить всё

execve("./a.out", ["./a.out"], 0x7ffff9b89518 /* 22 vars */) = 0
brk(NULL)                               = 0x7fffde75e000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fffe5547b50) = -1 EINVAL (Invalid argument)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcee5410000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=103195, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 103195, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcee53b6000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\244;\374\204(\337f#\315I\214\234\f\256\271\32"..., 68, 896) = 68
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2216304, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2260560, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcee5180000
mmap(0x7fcee51a8000, 1658880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x7fcee51a8000
mmap(0x7fcee533d000, 360448, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7fcee533d000
mmap(0x7fcee5395000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x214000) = 0x7fcee5395000
mmap(0x7fcee539b000, 52816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcee539b000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcee53b0000
arch_prctl(ARCH_SET_FS, 0x7fcee53b0740) = 0
set_tid_address(0x7fcee53b0a10)         = 5270
set_robust_list(0x7fcee53b0a20, 24)     = 0
rseq(0x7fcee53b10e0, 0x20, 0, 0x53053053) = -1 ENOSYS (Function not implemented)
mprotect(0x7fcee5395000, 16384, PROT_READ) = 0
mprotect(0x7fcee5419000, 4096, PROT_READ) = 0
mprotect(0x7fcee5408000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=8192*1024}) = 0
munmap(0x7fcee53b6000, 103195)          = 0
getrandom("\x05\x04\x5c\x57\xcc\x25\x9c\x8e", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0x7fffde75e000
brk(0x7fffde77f000)                     = 0x7fffde77f000
openat(AT_FDCWD, "test.txt", O_RDONLY)  = -1 ENOENT (No such file or directory)
exit_group(0)                           = ?
+++ exited with 0 +++
Почему strace может видеть этот вызов, а мой перехват — нет? Есть ли способ заставить этот перехват работать?
Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/786 ... -via-fopen
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»