Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why doesn't LD_PRELOAD trick catch open() when called by fopen()?

I use the LD_PRELOAD trick to catch open64() calls and I think I know how to do it correctly: with the program foobar compiled from

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
  open64("foobar.txt", 0);
  return 0;
}

I catch open64 as I expect:

>LD_PRELOAD=$PWD/catch.so ./foobar
open64 called

However, when open64 is replaced with fopen64:

#include <stdio.h>

int main() {
  fopen64("foobar.txt", "r");
  return 0;
}

now open64 is not caught. Why?

In case that fopen64 calls open, I do have both open and open64 intercepted, none is caught.

Both versions of the program foobar, when executed with strace, show that open is called, which means that fopen64 does call internally open or open64.

I thought that perhaps something is statically linked, but that seems not the case:

>ldd foobar

shows

libc.so.6 => /lib64/libc.so.6 

which is a shared library, and

>nm /lib64/libc.so.6

shows both open64 and fopen64 as defined (but not fopen, that's why in the question, I used the "64" versions for the purpose of argument; perhaps fopen is a macro to fopen64 or something like that, does not matter, since the problem happens with or without 64).

like image 671
Mark Galeck Avatar asked Mar 03 '16 11:03

Mark Galeck


1 Answers

I think it works like this: user space programs call library functions in libc, and libc calls system calls in the kernel. With LD_PRELOAD it is possible to intercept libc calls between the program and libc. You can not intercept system calls. If glibc calls another function internally (e.g. fopen calls open), you can not intercept it.

Instead of using strace, it is better to use ltrace in this case because that shows which library calls are done. These are the calls that you can intercept.

enter image description here

like image 63
Sjoerd Avatar answered Oct 20 '22 00:10

Sjoerd