#635847 libkrb5support0: library initialization errors in Perl module context

Package:
libkrb5support0
Source:
krb5
Description:
MIT Kerberos runtime libraries - Support library
Submitter:
Russ Allbery
Date:
2014-08-27 21:45:10 UTC
Severity:
normal
#635847#5
Date:
2011-07-29 03:36:12 UTC
From:
To:
I'm not sure that this bug is in the Kerberos library side, but I'll
start here and we can reassign if the problem is somewhere else.

If you run the following Perl script (with libnet-ldap-perl,
libauthen-sasl-cyrus-perl, and libauthen-krb5-perl installed along
with the MIT Kerberos Cyrus SASL GSSAPI module package installed):

#!/usr/bin/perl
use Net::LDAP;
use Authen::SASL qw(Cyrus);
use Authen::Krb5;

sub dir_bind {
   my ($serverName) = @_;

   print "Creating LDAP object for $serverName\n";
   my $ld = Net::LDAP->new($serverName);
   my $mech = 'GSSAPI';
   my $sasl = Authen::SASL->new(mechanism => $mech);

   print "binding using $mech\n";
   $ld->bind("", sasl=>$sasl);

   $ld->unbind if $ld;
}

dir_bind('ldap1.stanford.edu');
dir_bind('ldap2.stanford.edu');
exit;

you get:

Creating LDAP object for ldap1.stanford.edu
binding using GSSAPI
Creating LDAP object for ldap2.stanford.edu
binding using GSSAPI
perl: ../../../src/util/support/threads.c:351: krb5int_key_register: Assertion `destructors_set[keynum] == 0' failed.
Abort

All of the following must be true to trigger this:

1. Creating and using two separate Authen::SASL objects.  Just creating
   one will not trigger this bug.

2. Loading Authen::Krb5 (note that it's not used).  If it's not loaded,
   this won't be a problem.

3. Not loading any other module that loads libgssapi_krb5 into Perl's
   context.  If you add "use Net::Remctl;" to the script, the assertion
   goes away; similarly for Authen::Krb5::Admin, or anything else that
   loads the GSSAPI library.

My theory of what's happening here:

1. Authen::Krb5 loads libkrb5support but not libgssapi_krb5.

2. Cyrus loads the GSSAPI module when the SASL object is created and
   used, which loads libgssapi_krb5 and initializes it.

3. Cyrus unloads the GSSAPI module when the Authen::SASL object goes
   out of scope, which then unloads libgssapi_krb5, but something
   doesn't work properly about cleaning up the library initialization.
   libkrb5support is not unloaded and hangs on to that library
   initialization data.  (If Authen::Krb5 weren't loaded, it wouldn't
   stay loaded, and this problem then doesn't occur.)

4. When Cyrus loads the GSSAPI module again, it reloads libgssapi_krb5,
   which tries to initialize itself again.  Since libkrb5support thinks
   it's already initialized, it asserts.

Assuming this theory is correct, the question is why, when libgssai_krb5
is unloaded, it isn't cleaning up its initialization properly.

#635847#10
Date:
2011-11-25 22:36:37 UTC
From:
To:
Hello,

I face this bug.

For me it's quite anoying because I use Authen::Krb5 in order to read a
keytab and get a tgt ticket so that I can do GSSAPI in SASL without the
need to have a password in clear text.

Would be great to see this bug fixed.

Matthieu.

#635847#15
Date:
2014-08-27 20:53:08 UTC
From:
To:
We added a debian-local change to never unload GSS mechanisms back in
krb5-1.10.1+dfsg-3; I am curious if this is issue is worked around by that
patch.

#635847#20
Date:
2014-08-27 21:42:24 UTC
From:
To:
    Benjamin> We added a debian-local change to never unload GSS
    Benjamin> mechanisms back in krb5-1.10.1+dfsg-3; I am curious if
    Benjamin> this is issue is worked around by that patch.

I would be surprised because I don't think the issue was gss mechanism
related and our patch was fairly local.

However later, upstream made a more invasive change in how dlopen was
called (including RTLD_NODELETE) which probably does address this issue.
I don't know if we've picked up that change yet though.