Most of the sources online state that you can statically link glibc, but discourage from doing so; e.g. centos package repo:
The glibc-static package contains the C library static libraries
for -static linking. You don’t need these, unless you link statically, which is highly discouraged.
These sources rarely (or never) say why that would be a bad idea.
3
Answers
The program/
glibc
interface is standardized and documented by POSIX, the C and C++ standards, and others. For example, thefopen()
function behaves per the C standard, andpthread_mutex_lock()
per POSIX.The
glibc
/kernel interface is not standardized. Doesfopen()
useopen()
under the hood? Or does it useopenat()
? Or something else? What will it use next year? You don’t know.If the
glibc
/kernel interface changes, a program that uses whatever changed but statically linksglibc
won’t work any more.15+ years ago, Solaris removed all static versions of
libc
for this very reason.Static Linking – where did it go?
Edit:
There seems to be serious overestimation of the stability of the Linux kernel interface. See Linux kernel API changes/additions for details. To summarize:
The reasons given in other answers are correct, but they are not the most important reason.
The most important reason why glibc should not be statically linked, is that it makes extensive internal use of
dlopen
, to load NSS (Name Service Switch) modules andiconv
conversions. The modules themselves refer to C library functions. If the main program is dynamically linked with the C library, that’s no problem. But if the main program is statically linked with the C library,dlopen
has to go load a second copy of the C library to satisfy the modules’ load requirements.This means your "statically linked" program still needs a copy of
libc.so.6
to be present on the file system, plus the NSS oriconv
or whatever modules themselves, plus other dynamic libraries that the modules might need, likeld-linux.so.2
,libresolv.so.2
, etc. This is not what people usually want when they statically link programs.It also means the statically linked program has two copies of the C library in its address space, and they might fight over whose
stdout
buffer is to be used, who gets to callsbrk
with a nonzero argument, that sort of thing. There is a bunch of defensive logic inside glibc to try to make this work, but it’s never been guaranteed to work.You might think your program doesn’t need to worry about this because it doesn’t ever call
getaddrinfo
oriconv
, but locale support usesiconv
internally, which means anystdio.h
function might trigger a call todlopen
, and you don’t control this, the user’s environment variable settings do.And if your program does call
iconv
, for example, then things get even worse, especially when a “statically linked” executable is built on one distro, and then copied to another. Theiconv
modules are sometimes located in different places on different distros, so an executable that was built, say, on a Red Hat distro may fail to run properly on a Debian one, which is exactly the opposite of what people want from statically linked executables.I can think of one good reason for allowing static linking. If someone gains access to the system, they can replace the libc.so with one that contains malware. When your application is run, it will execute the malware. If the app had been built with a static glibc, that attack vector would disappear.