Static linking considered harmful

Ulrich Drepper drepper at redhat.com
Wed Nov 22 20:14:25 UTC 2006


Patrice Dumas wrote:
> Not only. There are cases when all those issues are moot, a prominent one 
> being for numerical models.

I'm not going to reply to each mail in this thread individually, this is 
a summary:

- I hope every agrees that using static linking with code you do not
   control yourself has severe consequences.  If not, you shouldn't be
   allowed to create binaries

- some people perceive some advantages like "it just runs on another
   machine"

These are the two main camps.  I think we can ignore the early boot 
issue (this can be easily fixed as DavidZ already showed) and the 
disaster recovery (here you should not trust _any_ binary on the system, 
just boot from CD/USB stick/network/etc and proceed from there).


As for the "works everywhere" argument:

- Jakub and others already pointed out that this is mostly a myth.
   Every non-trivial program needs services which require dynamic
   linking.  glibc's dependencies (iconv, nss, idn, ...) are prominent.
   But there are an increasing number of other projects which need it.
   Just look for all the DSOs linked against (explicitly or implicitly)
   libdl.  This includes basically all GUI stuff, all security apps.
   Heck, even ncurses falls in this category.  All of these are out
   when it comes to static linking.

- Other problems are file formats.  They change and we've seen problems
   on many occasions.  And I don't blame the maintainers of the packages
   providing the data.  They should not be held back in improving their
   packages because of an ancient file format.  If you do then you and
   up with a mess like the recent timezone file format change where all
   files suddenly are more than twice the size.  And even that
   possibility is sometimes not open.

- Every only slightly security relevant application must use the latest
   version of the code it is linked with.  As I wrote elsewhere, without
   dynamic linking it is almost certain that an update is missed which
   then leads to problems.  And don't start with "my servers are not
   accessible from the Internet therefore I don't care".  Complete utter
   nonsense.  The most dangerous and frequent attacker comes from the
   inside.  If you're working in a public company with such an attitude
   you're probably even legally vulnerable.

- The same code used in different environments very often does *not*
   "just works".

   + code is compiled with the assumption of a minimal expected runtime
     environment.  For glibc this means a minimal kernel.  For other
     packages the list will likely be longer.  And not all packages
     actually verify the assumptions for each program run (glibc does it
     but that's probably an exception)

   + this naïvely assumes that code is not looking at the environment
     itself and execute different code.  Prime examples are different
     syscalls that are available and where the code in old environment
     might have to live with incomplete emulations (example: pselect) or
     code which uses different CPU features depending on the availability
     (e.g., math code using the multi-media registers instead of floating
     point ops).  Assuming that this has no effects invalidates one's
     arguments flat out.

   + similarly, the results of especially math opcodes for a CPU are not
     the same over different manufacturers and even revisions.  If you
     need this you have to stick with exactly the same hardware on all
     the machines.  But then the argument of using different OS revisions
     or flavors goes mostly away.  Why severely cripple yourself by
     having the installations which have to be done at approximately the
     same time (otherwise the hardware would differ) so different?


Before going on I want to make one thing clear: there is no problem 
whatsoever if the code you're linking with statically is also controlled 
by yourself.  Especially if the library code comes in the same problem. 
  In this situation it is even a huge advantage to link statically and 
avoid the silly DSO which is used just in the programs of the package. 
This is something which likely applies to many of the users of 
heterogeneous computing environments (numeric stuff or not).


And even if all this does not apply it still is a bad idea to link 
statically and there is no reason.  You can always take the binaries, 
executable and DSOs, from an old system and install them as an item on 
all the machines.  Yes, you'd be using a non-standard dynamic linker, 
libc, ... on all the other machines but this is what you want.  Jakub 
already explained how to preserve even the file name to shut those 
making up phony arguments about things like this.  For updates you then 
only have to keep track on which machines the program is deployed and 
then replace the updated DSO.  Done correctly using network filesystems 
this would be one single place.

There is nothing which you can do with static linking that you cannot do 
with a dynamically linked executable as well.  The other direction is 
not true.


As for automatic -devel-static RPM, this is wrong as well.  Yes, for a 
transitional period some -devel-static RPMs might be needed.  But each 
and every one of them must be justified (e.g., no gnome/kde package 
should have them, period).  And you even need to dig in deeper: each .a 
file on those RPMs needs to be justified.  For instance, glibs's RPMs 
should not contain libpthread.a at all.  This code never really worked 
as well as the dynamically linked code.


And one final thing: we have -debuginfo packages.  But those can only 
work for DSOs.  Statically linked code is not debuggable.  We cannot 
effort shipping .a files with debug information included, that data is 
simply to huge.  This means even during development it makes no sense to 
use static linking with system-provided libraries.


I want to see a default policy of dropping all .a files (except special 
ones like libc_nonshared.a, of course, which are needed during dynamic 
linking).  Everybody having problems with any specific situation will 
have to make her/his point why a -devel-static package should be 
provided.  If the exception is granted it has to be revisited for the 
next release.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖




More information about the fedora-devel-list mailing list