Subject: lib/2791: dlsym() finds symbols outside of specified module
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mathieu.herrb@mipnet.fr>
List: netbsd-bugs
Date: 09/29/1996 10:20:26
>Number:         2791
>Category:       lib
>Synopsis:       dlsym() finds symbols outside of specified module
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 29 01:35:00 1996
>Last-Modified:
>Originator:     Matthieu Herrb
>Organization:
	MIPNET Toulouse, France
>Release:        1.2_BETA
>Environment:
System: NetBSD 1.2_BETA (COUGAR) #13: Sun Sep  1 01:36:51 MET DST 1996


>Description:

The man page says:

	dlsym() looks for a definition of symbol in the shared object
	designated by handle. 

But if 2 modules loaded by dlopen() use the same symbol name, dlsym()
never returns the address in the 2nd module.

>How-To-Repeat:

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	Makefile
#	mod1.c
#	mod2.c
#	main.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XCC = cc
XCFLAGS = -g $(SHARED_CFLAGS)
XSHARED_CFLAGS = -fpic
X.SUFFIXES: .so
X
XMODULE_SOURCES = mod1.c mod2.c
X
XMODULES = mod1.so mod2.so
X
XMAIN_SOURCE = main.c
X
XPROG = testmod
X
Xall: $(PROG) $(MODULES)
X
X
X
X$(PROG): $(MAIN_SOURCE)
X	$(CC) -o $(PROG) $(MAIN_SOURCE)
X
Xshar testmod.shar:	Makefile $(MODULE_SOURCES) $(MAIN_SOURCE)
X	shar Makefile $(MODULE_SOURCES) $(MAIN_SOURCE) > testmod.shar
X
X.c.so:
X	$(CC) -o tmp.o -c $(CFLAGS) $<
X	$(LD) -Bshareable -o $@ tmp.o
X
END-of-Makefile
echo x - mod1.c
sed 's/^X//' >mod1.c << 'END-of-mod1.c'
X#include <stdio.h>
X
Xvoid
Xinit_module(void)
X{
X    printf("init module 1\n");
X}
X
X
END-of-mod1.c
echo x - mod2.c
sed 's/^X//' >mod2.c << 'END-of-mod2.c'
X#include <stdio.h>
X
Xvoid
Xinit_module(void)
X{
X    printf("init module 2\n");
X}
X
X
X
END-of-mod2.c
echo x - main.c
sed 's/^X//' >main.c << 'END-of-main.c'
X#include <stdio.h>
X#include <dlfcn.h>
X
Xtypedef void (*initmodule_funcptr)(void);
X
Xvoid 
Xmain(int argc, char *argv[])
X{
X    void *module;
X    initmodule_funcptr moduleInit;
X
X    /* Open and initialize 1st module */
X    module = dlopen("mod1.so", DL_LAZY);
X    if (module == NULL) {
X	perror("dlopen(mod1.so)");
X	exit(1);
X    }
X    moduleInit = dlsym(module, "_init_module");
X    if (moduleInit == NULL) {
X	perror("dlsym()");
X	exit(1);
X    }
X    (*moduleInit)();
X    
X
X    /* Open and initialize 2n module */
X    module = dlopen("mod2.so", DL_LAZY);
X    if (module == NULL) {
X	perror("dlopen(mod2.so)");
X	exit(1);
X    }
X    moduleInit = dlsym(module, "_init_module");
X    if (moduleInit == NULL) {
X	perror("dlsym()");
X	exit(1);
X    }
X    (*moduleInit)();
X    
X    exit(0);
X}
X
X
END-of-main.c
exit


>Fix:

Theo De Raadt <deraadt@theos.com> commited the following fix to
OpenBSD to correct this problem (it applies as is to NetBSD sources):

*** rtld.c	1996/01/16 01:25:38	1.4
--- rtld.c	1996/09/28 18:15:02
***************
*** 1451,1456 ****
--- 1451,1457 ----
  	if (load_subs(smp) != 0)
  		return NULL;
  
+ 	LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
  	init_maps(smp);
  	return smp;
  }

>Audit-Trail:
>Unformatted: