I read all of the diffs between 1.4.1 and 1.4.4 but didn't find any likely suspects. However, tracing the library initialization in gdb, I found the specific problem.
Ordinarily gnutls will initialize the gcrypt library, if no app has done so already. In the gnutls initialization, it specifically turns gcrypt's secure malloc off, and everything works fine.
However, in my trace on Lucid, libnss-ldap is linked to libldap_r, not libldap. And because libldap_r has to support threads, it is required to initialize libgcrypt's thread callbacks, and it must do this before doing anything else with libgcrypt or gnutls.
The problem with that is, once we do this thread initialization, libgcrypt considers itself fully initialized. When we next call gnutls's init function, it checks to see if gcrypt is init'd or not, sees that it is, and skips any further init'ing. So the secure malloc stuff remains enabled.
I guess in this case we could do the initialization that gnutls skips, but that's rather ugly, libldap shouldn't have to know or duplicate the initialization steps inside gnutls_global_init(). Alternatively, libgcrypt could be changed to not call its global_init() right after setting the thread callbacks, since it's obvious that the caller still has other initialization calls that it needs to make. (Frankly I think this is the correct option.)
Finally, gnutls_global_init() could be changed to check for initialization_finished, instead of initialization_started. (i.e., check for GCRYCTL_INITIALIZATION_FINISHED_P, instead of GCRYCTL_ANY_INITIALIZATION_P). But this latter is pretty dicey, gnutls really has no way to know if it should be meddling in a half-initialized libgcrypt or not.
I'm trying really hard not to say "I told you so" again, but I just can't stop myself.
I read all of the diffs between 1.4.1 and 1.4.4 but didn't find any likely suspects. However, tracing the library initialization in gdb, I found the specific problem.
Ordinarily gnutls will initialize the gcrypt library, if no app has done so already. In the gnutls initialization, it specifically turns gcrypt's secure malloc off, and everything works fine.
However, in my trace on Lucid, libnss-ldap is linked to libldap_r, not libldap. And because libldap_r has to support threads, it is required to initialize libgcrypt's thread callbacks, and it must do this before doing anything else with libgcrypt or gnutls.
http:// www.gnupg. org/documentati on/manuals/ gcrypt/ Multi_002dThrea ding.html# Multi_002dThrea ding
The problem with that is, once we do this thread initialization, libgcrypt considers itself fully initialized. When we next call gnutls's init function, it checks to see if gcrypt is init'd or not, sees that it is, and skips any further init'ing. So the secure malloc stuff remains enabled.
I guess in this case we could do the initialization that gnutls skips, but that's rather ugly, libldap shouldn't have to know or duplicate the initialization steps inside gnutls_ global_ init(). Alternatively, libgcrypt could be changed to not call its global_init() right after setting the thread callbacks, since it's obvious that the caller still has other initialization calls that it needs to make. (Frankly I think this is the correct option.)
Finally, gnutls_ global_ init() could be changed to check for initialization_ finished, instead of initialization_ started. (i.e., check for GCRYCTL_ INITIALIZATION_ FINISHED_ P, instead of GCRYCTL_ ANY_INITIALIZAT ION_P). But this latter is pretty dicey, gnutls really has no way to know if it should be meddling in a half-initialized libgcrypt or not.
I'm trying really hard not to say "I told you so" again, but I just can't stop myself.