1

A program linked against libc.so calls a libc function through the plt, let's say setenv(). Internally within setenv() it calls malloc(), at least according to musl libc.

Does the setenv()->malloc() call always have to go through the plt and got? Wouldn't RIP relative addressing work better since even with ASLR enabled you're only moving the whole VMA?

nox
  • 23
  • 3

1 Answers1

2

Does the setenv()->malloc() call always have to go through the plt and got?

It doesn't have to, but many libc implementations allow end user to substitute his/her own malloc implementation (e.g. TCMalloc or jemalloc), and calling malloc from setenv directly would severely limit this.

Wouldn't RIP relative addressing work better

You need to be careful with with what "work better" actually means, and along which axis you evaluate it.

IP-relative call (i.e. direct call) would be faster and more efficient, but it will not work at all for symbol interpositioning.

P.S. At least GLIBC has no similar provision for user-provided mmap, and so makes mmap calls directly. This actually causes problems for people who want to accurately account for all of the memory used in the process by interposing mmap and munmap.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thank you for taking the time to answer! I'd upvote but I don't have enough reputation yet. I'm still trying to better understand this, so please correct me if I'm wrong - it seems libc implementers use a combination of `-Bsymbolic` or `-Bsymbolic-functions` and `--dynamic-list` to enable .plt entries for these functions, thus allowing interpolation. Strangely, when i set `-Bsymbolic-functions` there still exist .plt entries for many functions in libc.so, while setting `-Bsymbolic` removed them. Do you forsee any pitfalls from this besides being unable to interpose these functions? – nox Dec 08 '19 at 19:15