c - LD_PRELOAD and clone() -


i'm using script run program ld_preload library created me intercept calls, works @ point process calls clone() , lose ability intercept what's next (the program run again without library), there way overcome this? call

clone(child_stack,    clone_vm | clone_fs | clone_files | clone_sighand | clone_thread |    clone_sysvsem | clone_settls | clone_parent_settid | clone_child_cleartid,    parent_tidptr, tls, child_tidptr) 

looking on parameters of clone saw there ability trace child process well, nothing pertaining preloading.

i should mention i'm trying intercept calls on specific file descriptor , process clones file descriptors i'm not sure if possible want without flag clone (problem don't understand of them).

update: i'm using trying log activity done qemu-dm (which run xen)

#define _largefile64_source #define _gnu_source #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> #include <stdio.h> #include <stdarg.h>  #define dprintf(...) if(__debug__) { char tmp[256]; int cnt = sprintf(tmp, __va_args__); _write_f_(2, tmp, cnt); _write_f_(__outfile__, tmp, cnt); }  typedef int (*_open_f_t_)(const char *path, int flags, ...); typedef int (*_open64_f_t_)(const char *path, int flags, ...); typedef file *(*_fopen_f_t_)(const char *path, const char *mode); typedef int (*_close_f_t_)(int fd); typedef ssize_t (*_read_f_t_)(int fd, void *buf, size_t count); typedef ssize_t (*_write_f_t_)(int fd, const void *buf, size_t count); typedef off_t (*_lseek_f_t_)(int fd, off_t offset, int whence);  static _open_f_t_ _open_f_ = null; static _open64_f_t_ _open64_f_ = null; static _fopen_f_t_ _fopen_f_ = null; static _close_f_t_ _close_f_ = null; static _read_f_t_ _read_f_ = null; static _write_f_t_ _write_f_ = null; static _lseek_f_t_ _lseek_f_ = null; static int __outfile__ = null; static int __debug__ = 0;  void __init__ () {     _open_f_ = (_open_f_t_)dlsym(rtld_next, "open");     _open64_f_ = (_open64_f_t_)dlsym(rtld_next, "open64");     _fopen_f_ = (_fopen_f_t_)dlsym(rtld_next, "fopen");     _close_f_ = (_close_f_t_)dlsym(rtld_next, "close");     _read_f_ = (_read_f_t_)dlsym(rtld_next, "read");     _write_f_ = (_write_f_t_)dlsym(rtld_next, "write");     _lseek_f_ = (_lseek_f_t_)dlsym(rtld_next, "lseek");     unlink("/tmp/qemu-dm-preload.log");     __outfile__ = _open_f_("/tmp/out-0", o_wronly | o_creat | o_append);     __debug__ = 1; }  void __fini__ () {     __debug__ = 0;     fsync(__outfile__);     _close_f_(__outfile__); }  int open(const char *path, int flags, ...) {     //replace     int result;     if (flags & o_creat)     {         va_list arg;         int mode = 0;         va_start (arg, flags);         mode = va_arg (arg, int);         va_end (arg);         result = _open_f_(path, flags, mode);         dprintf("open(%s, %d, %d) => %d\n", path, flags, mode, result);     } else {         result = _open_f_(path, flags);         dprintf("open(%s, %d) => %d\n", path, flags, result);     }     return result; }  int open64(const char *path, int flags, ...) {     //replace     int result;     if (flags & o_creat)     {         va_list arg;         int mode = 0;         va_start (arg, flags);         mode = va_arg (arg, int);         va_end (arg);         result = _open64_f_(path, flags, mode);         dprintf("open(%s, %d, %d) => %d\n", path, flags, mode, result);     } else {         result = _open64_f_(path, flags);         dprintf("open(%s, %d) => %d\n", path, flags, result);     }      return result; }  file * fopen(const char *path, const char *mode) {     file *result = _fopen_f_(path, mode);     dprintf("fopen(%s, %s) => %p\n", path, mode, result);     return result; }  int close(int fd) {     //replace     int result = _close_f_(fd);     dprintf("close(%d) => %d\n", fd, result);     return result; }  ssize_t read(int fd, void *buf, size_t count) {     // replace     ssize_t result = _read_f_(fd, buf, count);     dprintf("read(%d, %p, %lu) => %ld\n", fd, buf, count, result);     return result; }  ssize_t write(int fd, const void *buf, size_t count) {     // replace     ssize_t result = _write_f_(fd, buf, count);     dprintf("write(%d, %p, %lu) => %ld\n", fd, buf, count, result);     return result; }  off_t lseek(int fd, off_t offset, int whence) {     // replace     off_t result = _lseek_f_(fd, offset, whence);     dprintf("lseek(%d, %ld, %d) => %ld\n", fd, offset, whence, result);     return result; } 

compiled gcc -ggdb -shared -fpic -wl,-init,__init__ -wl,-fini,__fini__ -o fileaccesshooks.so -ldl fileaccesshooks.c

wrapper script contents:

#!/bin/bash export ld_preload=/home/xception/work/fileaccesshooks.so exec /usr/lib/xen/bin/qemu-dm-orig "$@" 

as observed in comments below environment same task , process (ld_preload same both /proc/8408/task/8526/environ , /proc/8408/environ) after call clone no more data logged grep -e "testfile" -e "(11" /tmp/out-0

open(/root/testfile.raw, 2) => 11 read(11, 0x7fffb7259d00, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 read(11, 0x7fba6e341200, 512) => 512 

this get, comparatively output of strace -f run on same executable contains more reads seeks

from clone parameters of clone_vm , similar, looks call clone creating new thread rather new process. wouldn't expect resulting thread reload libraries , therefore not expect preloaded library need act again in new thread - existing function implementations should 'just work'; jump instructions library should remain equally valid in new thread old.

i therefore suspicious not problem , clone red herring.

my theories are:

  • there's exec somewhere well
  • the __init__ code in library getting called each new thread, though seems unlikely indeed.

one last point regarding qemu - modern qemu uses coroutines lots of io things. uses various backends depending on what's available on host system - if you're unlucky, creates thread each 1 can result in very, large numbers of threads. read here - http://lists.gnu.org/archive/html/qemu-devel/2011-07/msg02894.html - there's way qemu configure stuff report coroutine backend it's using. however, suspect xen qemu-dm might old have coroutine stuff? don't know.


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -