Static vs Dynamic
static linking not so harmful in container context - when done right
There a few articles out there that doom static linking. While there is a valid point behind every argument and most - if not all - of them are 100% applicable to a standard Linux system, it may not be exactly applicable to a containerized environment. So I’m picking one article (without intended pun to the author) and try to put this into container context - again, without saying that the author isn’t completely right in general. (Well maybe excpet for the “This has never been the case and never will be the case” statement)
flexibility by replacing DSOs (rathen than the statically linked binary)
When you need to replace an outdated, buggy or even vulnerable piece of code inside a container you wouldn’t just replace a single library anyway. I’m not going into the build/layer details now (see later), but at the very least you will have to add a file to the container, produce an updated SBOM and sign the results. Now - how is just replacing the DSO easier than just replacing the entire binary? Except for the need to recompile: it isn’t.
keeping track of dependencies
This one would be a killer argument indeed. However, binaries in spartanc properly document their dependencies. At the time of (static) linking all static libs that are pulled in are documented. Not only the name of the library, but also the actual package (including version) that provided the library. From documentation perspective this is as good as pointing to a DSO. This information is stored both in the binary (ELF: .note.package and annobin object!) and in the package database - allowing an inventory (we just syft) to pick it up and properly document it in the SBOM.
security measures
We use the “hardened” Gentoo profile for our build environment, see changes here (https://wiki.gentoo.org/wiki/Hardened/Toolchain#Changes). However, PIE is currently disabled when compiling static binaries. We are currently exploring the use of “static-pie” though, which will enable ASLR even for static binaries.
more efficient use of physical memory
One of the purposes of containerization is isolation. Not so much as in a virtual machine - you are only in a different Linux namespace - but, except for rare cases (identical library, same image layer, compatible storage driver, supporting runtime), you wouldn’t be sharing physical memory when you have the exact same library in two different containers. No gain for DSO here. The dynamically linked binary plus the DSO in a container might even be larger than the static binary (see advantages).
glibc depends on dynamic linking
Musl doesn’t. I’m not saying glibc is doing anything wrong - just that we don’t use it, so this is a non-argument.
accidentally linking wrong nss module
To be honest - I don’t get the point here. If you do, please let me know!
no accidental license violation
Both (!), dynamic and static linking to a library with code under GPL, have identical implications (see https://www.gnu.org/licenses/gpl-faq.en.html#GPLStaticVsDynamic). Even with the LGPL, if you provide the DSO together with your binary (when distributing container images, you do), you inherit the need to supply the library sources. In our source artifact container you will find the source of the main programm together with the source of all (statically) linked libraries - problem solved. If you know of any (GPL) license implications that are specific to static linking and the current process does not already cover it, please let me know.
hacks don’t work
I’m not sure this was ever a pro-argument. I certainly see the inability to mess around with the binary in a production environment highly positive, not negative. Plus our binaries are built with -ggdb, with debug information stripped - but preserved in the debug artifact in case you need it.