Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking against an old version of libc to provide greater application coverage

Tags:

linux

linker

libc

Linux binaries are usually dynamically linked to the core system library (libc). This keeps the memory footprint of the binary quite small but binaries which are dependent on the latest libraries will not run on older systems. Conversely, binaries linked to older libraries will run happily on the latest systems.

Therefore, in order to ensure our application has good coverage during distribution we need to figure out the oldest libc we can support and link our binary against that.

How should we determine the oldest version of libc we can link to?

like image 754
Gearoid Murphy Avatar asked Oct 27 '10 10:10

Gearoid Murphy


People also ask

Can you statically link libc?

Instead, static linking against musl-libc is the recommended option on Linux. Since it's statically linked, a binary linked against musl-libc will also run on a glibc system. That's the entire point of it. It is however completely fine to statically link other libraries besides a dynamically linked glibc .

Is libc automatically linked?

libc is always searched automatically.

What is the difference between libc and glibc?

libc is a single library file (both . so and . a versions are available) and in most cases resides in /usr/lib . However, the glibc (GNU libc) project provides more than just libc - it also provides the libm mentioned earlier, and other core libraries like libpthread .

How do I know what version of libc So 6 I have?

In case of the libc you can simply run the . so file and will be told the library version. confus@confusion:~/misc/test$ /lib/x86_64-linux-gnu/libc. so.


1 Answers

Work out which symbols in your executable are creating the dependency on the undesired version of glibc.

$ objdump -p myprog ... Version References:   required from libc.so.6:     0x09691972 0x00 05 GLIBC_2.3     0x09691a75 0x00 03 GLIBC_2.2.5  $ objdump -T myprog | fgrep GLIBC_2.3 0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   realpath 

Look within the depended-upon library to see if there are any symbols in older versions that you can link against:

$ objdump -T /lib/libc.so.6 | grep -w realpath 0000000000105d90 g    DF .text  0000000000000021 (GLIBC_2.2.5) realpath 000000000003e7b0 g    DF .text  00000000000004bf  GLIBC_2.3   realpath 

We're in luck!

Request the version from GLIBC_2.2.5 in your code:

#include <limits.h> #include <stdlib.h>  __asm__(".symver realpath,realpath@GLIBC_2.2.5");  int main () {     realpath ("foo", "bar"); } 

Observe that GLIBC_2.3 is no longer needed:

$ objdump -p myprog ... Version References:   required from libc.so.6:     0x09691a75 0x00 02 GLIBC_2.2.5  $ objdump -T myprog | grep realpath 0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 realpath 

For further information, see http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103.

like image 137
Sam Morris Avatar answered Sep 21 '22 03:09

Sam Morris