zBopjy
zBopjy

Reputation: 41

Why does the getline call glibc's malloc instead of __wrap_malloc when passing `-wrap=malloc` to the linker?

When I try to pass --wrap=malloc to the ld linker for hooking malloc, I find that getline will not call __wrap_malloc, but call glibc's malloc.

// foo.c
void* __wrap_malloc(size_t sz) {
   printf("abc");
   return __reall_malloc(sz);
}

int main() {
   char *line = NULL;
   size_t n = 0;
   getline(&line, &n, stdin);   // will call malloc
   ....
}

Run as: $ gcc foo.c -Wl,--wrap=malloc && ./a.out It doesn't print "abc", it seems that __wrap_malloc isn't called.

But run as: $ gcc -static foo.c -Wl,--wrap=malloc && ./a.out I got a segment fault, print the backtrace:

#0  0x00000000004490e7 in vfprintf ()
#1  0x0000000000407a76 in printf ()
#2  0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
#3  0x0000000000456a2b in _IO_file_doallocate ()
#4  0x000000000040d4a5 in _IO_doallocbuf ()
#5  0x000000000040c4d8 in _IO_new_file_overflow ()
#6  0x000000000040b421 in _IO_new_file_xsputn ()
#7  0x000000000044921f in vfprintf ()
#8  0x0000000000407a76 in printf ()
#9  0x0000000000400ab7 in __wrap_malloc (size=1024) at foo.c:26
....

It seems that __wrap_malloc (called in printf initally) is called recursively, which means that getline call __wrap_malloc instead of glibc's malloc.

What happened if -static passed to linker? How can I force getline call __wrap_malloc instead of glibc's malloc?

Upvotes: 4

Views: 150

Answers (1)

Florian Weimer
Florian Weimer

Reputation: 33717

If -static is passed to the link editor, the link editor can see all internal calls to malloc and will try to wrap them, causing the infinite recursion because your own malloc implementation calls printf, which in turn calls malloc in some cases.

Without -static, the link editor cannot rewrite the internal malloc references within libc.so.6, so internal calls in glibc are never redirected. There is no infinite recursion, but you do not see those internal calls, either.

glibc supports replacing malloc using ELF symbol interposition (as far as such a thing is possible):

You still need to be careful to avoid triggering infinite recursion, though.

Upvotes: 2

Related Questions