In the following minimal example, a library loaded via LD_PRELOAD
with functions to intercept fopen
and openat
is apparently operating before its initialization. (Linux is CentOS 7.3). Why??
library file comm.c
:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>
typedef FILE *(*fopen_type)(const char *, const char *);
// initialize to invalid value (non-NULL)
// init() should initialize this correctly
fopen_type g_orig_fopen = (fopen_type) 1;
typedef int (*openat_type)(int, const char *, int, ...);
openat_type g_orig_openat;
void init() {
g_orig_fopen = (fopen_type)dlsym(RTLD_NEXT,"fopen");
g_orig_openat = (openat_type)dlsym(RTLD_NEXT,"openat");
}
FILE *fopen(const char *filename, const char *mode) {
// have to do this here because init is not called yet???
FILE * const ret = ((fopen_type)dlsym(RTLD_NEXT,"fopen"))(filename, mode);
printf("g_orig_fopen %p fopen file %s\n", g_orig_fopen, filename);
return ret;
}
int openat(int dirfd, const char* pathname, int flags, ...) {
int fd;
va_list ap;
printf("g_orig_fopen %p openat file %s\n", g_orig_fopen, pathname);
if (flags & (O_CREAT)) {
va_start(ap, flags);
fd = g_orig_openat(dirfd, pathname, flags, va_arg(ap, mode_t));
}
else
fd = g_orig_openat(dirfd, pathname, flags);
return fd;
}
compiled with:
gcc -shared -fPIC -Wl,-init,init -ldl comm.c -o comm.so
I have an empty subdirectory subdir
. Then it appears the library function fopen
is called before init
:
#LD_PRELOAD=./comm.so find subdir
g_orig_fopen 0x1 fopen file /proc/filesystems
g_orig_fopen 0x1 fopen file /proc/mounts
subdir
g_orig_fopen 0x7f7b2e574620 openat file subdir