Policy on static linking ?

Jilles Tjoelker jilles at stack.nl
Sat Jan 15 22:48:59 UTC 2011


On Sat, Jan 15, 2011 at 09:11:50PM +1100, Jean-Yves Avenard wrote:
> On Friday, 14 January 2011, Pete French <petefrench at ticketswitch.com> wrote:
> > I build code using static linking for deployment across a set of
> > machines. For me this has a lot of advantages - I know that the
> > code will run, no matter what the state of the ports is on the
> > machine, and if there is a need to upgrade a library then I do it
> > once on the build machine, rebuild the executable, and rsync it out
> > to the leaf nodes. Only one place to track security updates, only
> > one place where I need to have all the porst the code depends on
> > installed.

> I actually tried to compile a port against another and have it link
> statically, but I couldn't find a way to do so without hacking the
> configure script. I was wondering if there was another (and easier)
> way to do so...

> I use ldap for authentication purposes, along with pam_ldap and nss_ldap

> If I compile openldap-client against openssl from ports, then it
> creates massive problems elsewhere.

> For example, base ssh server will now crash due to using different
> libcrypto. compiling ports will also become impossible as bsd tar
> itself crash (removing ldap call from nsswitch.conf is required to
> work again)

> I was then advised in the freebsd forums to uninstall openssl port,
> compile openldap against openssl base, install it, then re-install
> openssl port.
> (I have to use openssl from ports with apache/subversion to fix a bug
> with TLSv1 making svn commit crash under some circumstances)

> I dislike this method, because should openldap gets upgraded again and
> be linked against openssl port, I will lock myself out of the machine
> again due to sshd crashing. Just like what happened today :(

> So how can I configure openldap-client to link against libssl and
> libcrypto statically?

I think this can be solved with a symbol versioning trick. By applying a
different version to all symbols from each OpenSSL version, the dynamic
linker will be able to distinguish between different versions of OpenSSL
and will use the correct OpenSSL version each object was linked to, even
if there are multiple OpenSSL versions in the process. Note that each
OpenSSL version should still have its own SONAME (the security/openssl
port does this).

The version script can be as simple as (substituting the version)

OPENSSL_0.9.8 {
	global:
		*;
};

and needs to be in the top level and in the engines directory.

For it to work completely, both base and the port need to be patched.
Old binaries continue to work but the benefit only appears after
recompilation.

The SONAME needs to be bumped when the version string is changed or
deleted (but not when it is initially added), otherwise binaries will
stop working. This also means that making the change cannot be undone
without breaking binary compatibility.

What will not work is allocating an OpenSSL structure in one object
linked to one OpenSSL version and then using it in another object linked
to another OpenSSL version. That would require true symbol versioning,
keeping compatibility with old versions in the same library with the
same SONAME. Unlike the approach I propose, that would be a lot of work
and can only be done by the OpenSSL project, and I think their policy is
not to do such extra work for ABI compatibility. If they change their
mind they will probably start with the symver version of the previous
release so as to remain compatible with what various Linux distributions
are doing.

Also, a side effect is that it is no longer possible to cheat by
symlinking different OpenSSL versions.

The approach has been used by Debian for some time.

Links:
http://chris.dzombak.name/blog/2010/03/building-openssl-with-symbol-versioning/
http://chris.dzombak.name/files/openssl/openssl-0.9.8l-symbolVersioning.diff
http://rt.openssl.org/Ticket/Display.html?id=1222&user=guest&pass=guest

-- 
Jilles Tjoelker


More information about the freebsd-stable mailing list