Differences between revisions 4 and 31 (spanning 27 versions)
Revision 4 as of 2015-05-19 06:49:57
Size: 1900
Editor: PaulWise
Comment: policy
Revision 31 as of 2021-09-21 02:07:46
Size: 5575
Editor: PaulWise
Comment: mention the policy change
Deletions are marked like this. Additions are marked like this.
Line 12: Line 12:
It requires rebuilding the world when the libraries change.  * It requires rebuilding the world when the libraries change.
 * It is harder to track than dynamic linking.
 * It prevents memory sharing between different executables using the same code.
 * It renders some security measure less effective (ASLR for example).
 * To comply with the DFSG and GNU GPL, we need to keep old source around.
 * Possible to ship incomplete libs. Eg. foo() depends on bar() but bar() not present at link time.
Line 14: Line 19:
It is harder to track than dynamic linking.

??
<<Anchor(upsides)>>
== Upsides ==
 * --(Code can be built non-fpic, which can be 5-20% faster due to register pressure on register-starved archs like i386. (Especially numerical code).)-- NB: With gcc-5, -fPIC has less overhead: https://software.intel.com/en-us/blogs/2014/12/26/new-optimizations-for-x86-in-upcoming-gcc-50-32bit-pic-mode
 * Makes it easier to have different versions of a library used by packages.
 * Maps automatically to upstream build/module tools
Line 28: Line 35:
Debian Policy unfortunately says that Built-Using may *only* be used for the purposes of DFSG/license compliance so tracking static linking must be done using custom headers.
Line 45: Line 53:
?? The go tool from golang currently requires all libraries be available in source form and then builds everything into one binary. These source files in the -dev packages are the equivalent of the .a file.

When using gccgo-5 (go -gccgo), the Go runtime library is dynamically linked against an executable, however everything else is again linked "statically".

Michael Hudson-Doyle has tried building shared go libraries. Support for dynamic linking (for amd64 only) has been in Ubuntu for a while. But this plan is abandoned now. Even micro releases of the Go compiler break ABI, dynamic linking is just way too tedious, said by mwhudson.

The golang tooling [[https://manpages.debian.org/unstable/dh-golang/dh_golang.1p.en.html|generates Built-Using headers]] for all(both direct and indirect) dependencies.

=== Lisp ===

Lisp libraries are cl-* packages shipping the source code in /usr/share/common-lisp/, similar to Go libraries.
The compiler (e.g. sbcl) builds a static binary from all used cl-* packages.

=== FreePascal ===

The FreePascal Compiler (fpc) packages in Debian don't seem to use dynamic linking. See also [[http://wiki.freepascal.org/Lazarus/FPC_Libraries|here]].

=== Rust ===

The default for Rust is static linking but dynamic linking is available with {{{rustc -C prefer-dynamic}}}. The ABI is [[https://lwn.net/Articles/797616/|not stable but this is being worked on]].

=== JavaScript ===

browserify and other tools merge together multiple JS files for shipping to browsers.

Some browser extensions (webext-* packages) copy their dependencies at build time instead of symlinking, because some browsers ([[DebianBug:922944|Firefox]]) do not follow symlinks installed into /usr/share/webext/.

=== Java/Closure ===

Java has "[[https://hashman.ca/the-repl/|uberjars]]" which bundle dependencies into the pre-built jar files.
Line 50: Line 87:
The Debian archive keeps around old sources referenced by the [[https://www.debian.org/doc/debian-policy/ch-relationships.html#s-built-using|Built-Using]] header, marking them with the Extra-Source-Only header. This is only to be used for licensing reasons though, not for tracking static linking.
Line 52: Line 91:
Change debian-policy to discourage static linking? For safety reasons, binaries should be linked dynamically to include hardening features e.g. ASLR. A user should be able to presume that binaries shipped by Debian are safe to use in front-facing (e.g. web services) scripts, etc.

More automatic detection of static linking? [[DebianBug:698398|#698398]]

Make it easier to add Built-Using?

Change debian-policy & lintian to discourage static linking?

Do browserify from package postinsts?

Something based on searching for statically-linkable files and then mapping those packages to buildinfo files?

Intro

In general Debian Policy allows static linking but it has various downsides.

This page aims to document the downsides and mitigations we have in place for those downsides as well as improving the situation in Debian around static linking.

Downsides

  • It requires rebuilding the world when the libraries change.
  • It is harder to track than dynamic linking.
  • It prevents memory sharing between different executables using the same code.
  • It renders some security measure less effective (ASLR for example).
  • To comply with the DFSG and GNU GPL, we need to keep old source around.
  • Possible to ship incomplete libs. Eg. foo() depends on bar() but bar() not present at link time.

Upsides

Affected

Various technology in Debian uses or is affected by static linking.

C libraries

C libraries support static linking and files are named *.a and can be unpacked with the ar tool from binutils.

Packages can declare they were built using code from other packages by using the Built-Using header and the Debian archive keeps around old sources, marking them with the Extra-Source-Only header. Debian Policy unfortunately says that Built-Using may *only* be used for the purposes of DFSG/license compliance so tracking static linking must be done using custom headers.

Lintian detects binaries that have been statically linked.

Haskell

All Haskell libraries are statically linked into the final binary.

The release team have a transition that tracks Haskell rebuilds.

OCaml

All OCaml libraries are statically linked into the final binary.

The release team have a transition that tracks OCaml rebuilds.

Go

The go tool from golang currently requires all libraries be available in source form and then builds everything into one binary. These source files in the -dev packages are the equivalent of the .a file.

When using gccgo-5 (go -gccgo), the Go runtime library is dynamically linked against an executable, however everything else is again linked "statically".

Michael Hudson-Doyle has tried building shared go libraries. Support for dynamic linking (for amd64 only) has been in Ubuntu for a while. But this plan is abandoned now. Even micro releases of the Go compiler break ABI, dynamic linking is just way too tedious, said by mwhudson.

The golang tooling generates Built-Using headers for all(both direct and indirect) dependencies.

Lisp

Lisp libraries are cl-* packages shipping the source code in /usr/share/common-lisp/, similar to Go libraries. The compiler (e.g. sbcl) builds a static binary from all used cl-* packages.

FreePascal

The ?FreePascal Compiler (fpc) packages in Debian don't seem to use dynamic linking. See also here.

Rust

The default for Rust is static linking but dynamic linking is available with rustc -C prefer-dynamic. The ABI is not stable but this is being worked on.

JavaScript

browserify and other tools merge together multiple JS files for shipping to browsers.

Some browser extensions (webext-* packages) copy their dependencies at build time instead of symlinking, because some browsers (Firefox) do not follow symlinks installed into /usr/share/webext/.

Java/Closure

Java has "uberjars" which bundle dependencies into the pre-built jar files.

Mitigation

The Debian archive keeps around old sources referenced by the Built-Using header, marking them with the Extra-Source-Only header. This is only to be used for licensing reasons though, not for tracking static linking.

Manual binNMUs can be done for packages that declare a Built-Using header.

For safety reasons, binaries should be linked dynamically to include hardening features e.g. ASLR. A user should be able to presume that binaries shipped by Debian are safe to use in front-facing (e.g. web services) scripts, etc.

More automatic detection of static linking? #698398

Make it easier to add Built-Using?

Change debian-policy & lintian to discourage static linking?

Do browserify from package postinsts?

Something based on searching for statically-linkable files and then mapping those packages to buildinfo files?