[gnutls-dev] gnutls versioning again

Simon Josefsson simon at josefsson.org
Thu Feb 15 12:20:50 CET 2007


"Dmitry V. Levin" <ldv at altlinux.org> writes:

> Hi,
>
> On Sun, Feb 04, 2007 at 12:59:05PM +0100, Simon Josefsson wrote:
>> I'm copying the list on this, since I'd appreciate wider discussion.
>> 
>> Pavlov Konstantin writes:
>> 
>> > Another problem i recognized is the lack of real symbol versioning in 
>> > libgnutls:
>> > GNUTLS_1_3
>> > {
>> >   global: _gnutls*; gnutls*; _E_*;
>> >   local: *;
>> > };
>> >
>> > I made a new .version file for 1.6.1 release, it looks like :
>> > GNUTLS_1_3
>> > {
>> >   global: _gnutls*; gnutls*; _E_*;
>> > };
>> >
>> > GNUTLS_1_6_1 {
>> >     global:
>> >         gnutls_transport_set_errno;
>> >         gnutls_transport_set_global_errno;
>> >         local:  *;
>> > };
>> >
>> >
>> > What do you think about it ?
>> 
>> I've re-read the relevant parts of Drepper's DSO howto to refresh my
>> memory on this, but still, I don't see what problem the above change
>> would fix.  Could you explain?
>> 
>> The only problem that I can think of that the above would solve if is
>> an application that uses e.g. gnutls_transport_set_errno was built
>> against 1.6.x or later is moved to a system which has an older
>> libgnutls installed that doesn't have that symbol.  The application
>> will not work.
>
> Yes.  Imagine large binary package repository (e.g. Debian or Sisyphus).
> Maintainer builds new software which uses new symbols from gnutls.
> When user installs package with this new software, there are no indication
> that it requires new version of gnutls, so old version of gnutls may
> remain unupgraded.  As result, user will see runtime relocation error
> which is not what maintainer usually want.

One solution to that is for the new software packages to have a
versioned dependency on the newer version of the gnutls packages.

> To resolve this issue, our gnutls package maintainer had to create new
> interface, e.g. GNUTLS_1_6_1 and place new symbols there.  As result,
> every package with software which uses these symbols will automatically
> have all necessary dependencies, e.g. libgnutls.so.13(GNUTLS_1_6_1),
> so any user installing this package will also update gnutls package.

There needs to be some mechanisms here that figures out that
application X uses symbols from libgnutls.so.13 with the GNUTLS_1_6_1
label, and maps GNUTLS_1_6_1 back to a versioned dependency on GnuTLS
version Y, and adds it to the application X packages.  Right?  That
mechanism is presumably part of your package build scripts.

Why can't that mechanism check for the new APIs instead, and add the
versioned dependency when applications use them?  That seems to amount
to roughly the same amount of hard-coding and special mapping.  But it
seems more reliable.

I wonder if it isn't easier to hand-maintain these versioned
dependencies.  Eventually, you'll run into the situation where
application X depends on the behaviour (i.e., not causing a security
problem) of some API gnutls_foo in GnuTLS version P or later.  Shared
library symbols won't protect you from this, since the shared library
label of gnutls_foo won't be incremented when we fix a security
problem in that function.  Only hand-maintained version information
does.

>> We can't protect against that, though, as far as I can see.  If an
>> application uses a new interface, he must make sure a library that
>> implements that interface is available.
>
> Just otherwise, library should provide new symbols via new interface,
> so an application which uses new symbols will get necessary dependencies.

As far as I understand, the linker scripts weren't designed for that
purpose.

>> Thus, my conclusion would be that, generally, adding new interface
>> doesn't require changes to the version script.
>
> If new version of a library exports new symbols, it should add new
> interface explicitly, using version script or any other available method.
> As I see, gnutls uses version script for this purposes.

No, GnuTLS uses version scripts to make sure that we can safely CHANGE
the behaviour of an API function in a later release, and be sure that
old applications will still work with the new library.  If I
understand Drepper's paper on shared library versioning, that was what
this feature was originally designed for.

I'll grant you that there is no really good documentation that seem to
answer this question.  It may be that adding new APIs should cause a
new shared library label to be added.  I see some signs that libc
actually do this.

Also, I doubt that I will ever CHANGE an existing API, and then use
the tricky shared library tricks described in Drepper's paper to avoid
problems.  That mechanism isn't portable.  So I frankly don't know why
we are using the versioned library mechanism.  Other than the Debian
folks asking us to.  Does anyone recall the motivation for Debian the
require versioned libraries?

I'd like to continue discuss this.  Maybe we can write down our
conclusions.  There doesn't seem to be a best practice on shared
library version handling written from the point of view of the
maintainer of a library.

/Simon




More information about the Gnutls-devel mailing list