Subject: lib/11458: dlsym(3) returns the wrong symbols, ignoring handle
To: None <gnats-bugs@gnats.netbsd.org, rhialto@polderland.nl>
From: Olaf Seibert <rhialto@polderland.nl>
List: netbsd-bugs
Date: 11/09/2000 07:16:10
>Number:         11458
>Category:       lib
>Synopsis:       dlsym(3) returns the wrong symbols, ignoring handle
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Nov 09 07:16:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Olaf Seibert
>Release:        NetBSD/alpha 1.4.1 (ELF)
>Organization:
	
>Environment:
	
System: NetBSD azenomei.falu.nl 1.4.1 NetBSD 1.4.1 (AZENOMEI) #27: Wed Jun 14 01:41:57 CEST 2000     rhialto@azenomei.falu.nl:/usr/src/sys/arch/alpha/compile/AZENOMEI alpha


>Description:

Note: NetBSD/alpha uses ELF.

.From the manpage:

     void *
     dlsym(void *handle, const char *symbol);

     dlsym() looks for a definition of symbol in the shared object designated
     by handle.  The symbols address is returned.  If the symbol cannot be re-
     solved, NULL is returned.

This turns out not to be true. The handle argument turns out to be
ignored. If the symbol name can be found in either the main program or an
earlier loaded object, that symbol will be returned. It may even return
symbols from objects which failed to link at load time.

This horribly breaks gnupg module loading... :-(

To illustrate the problem with gpg:

gpg can load modules. Each of those modules exports two symbols, which
identify the modules and their entry points. Thesy are called
gnupgext_version and gnupgext_enum_func.

gpg uses el->handle = dlopen(el->name, RTLD_NOW), then dlsym(el->handle,
"gnupgext_version") to get the symbol gnupgext_version from the module.
(cipher/dynload.c)

Howerver, due to an oversight the symbol gnupgext_version also exists in
the main program, so I never got that symbol from the module. I got the
version from the main program. This results in gpg thinking I wanted to
add the twofish cipher, which it already has:

    $ gpg -v -v -v /tmp/xx.gpg
    :pubkey enc packet: version 3, algo 1, keyid 260A8308DAFEAFB5
	    data: [1536 bits]
    gpg: public key is DAFEAFB5

    You need a passphrase to unlock the secret key for
    user: "Olaf 'Rhialto' Seibert <rhialto@mbfys.kun.nl> 1536"
    gpg: loaded digest 2
    gpg: /usr/pkg/lib/gnupg/idea: TWOFISH ($Revision: 1.8.2.3 $)
    gpg: /usr/pkg/lib/gnupg/idea: provides cipher algorithm 10
    gpg: /usr/pkg/lib/gnupg/idea: provides cipher algorithm 102
    gpg: /usr/pkg/lib/gnupg/tiger: TWOFISH ($Revision: 1.8.2.3 $)
    gpg: /usr/pkg/lib/gnupg/tiger: provides cipher algorithm 10
    gpg: /usr/pkg/lib/gnupg/tiger: provides cipher algorithm 102
    1536-bit RSA key, ID DAFEAFB5, created 1997-07-08

Even when I fixed that (add static in front of gnupgext_version and
gnupgext_enum_func in cipher/twofish.c), for the second module that was
loaded I got the gnupgext_version from the first module.

gpg was already linked with -Wl,-export-dynamic. Removing it made
loading the first module fail:

gpg: /usr/pkg/lib/gnupg/idea: error loading extension: /usr/pkg/lib/gnupg/idea:
+Undefined PLT symbol "g10_log_fatal" (reloc type = 26, symnum = 38)

then the second module STILL got the wrong symbol:

gpg: /usr/pkg/lib/gnupg/tiger: IDEA ($Revision: 1.11 $)
gpg: /usr/pkg/lib/gnupg/tiger: provides cipher algorithm 1
gpg: loaded cipher 1 (IDEA)


>How-To-Repeat:

Compile gnupg package. Fetch idea.c from
ftp://ftp.gnupg.org/pub/gcrypt/contrib/idea.c .  Compile, install, and
wonder why it gives messages about cipher #10 (TWOFISH) instead of #1
(IDEA).

Install both idea and tiger (which comes with gnupg) for the second
problem. This can be done by adding the following to
$HOME/.gnupg/options:

    load-extension tiger
    load-extension idea

gpg -v -v -v testfile.gpg, where testfile is a file made by encrypting
with a key from PGP 2.6.x. Or you could try signing with the key. Gnupg
is smart enough that it only tries to load extensions when it needs any,
and the IDEA cipher is only needed with such old keys, to access the
private key. The modules are loaded in reverse order.

>Fix:
	I don't know :-(

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert - rhialto@polder    -- Ah only did well at school
\X/ land.nl       -- tae git intae an O level class tae git away fae Begbie.
Hi! I am a .signature virus. Copy me into your .signature to help me spread.
>Release-Note:
>Audit-Trail:
>Unformatted: