Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dynamic loading of libpthread on Linux RedHat 6.2, SIGSEGV on dl_close

2 views
Skip to first unread message

CKime

unread,
Jul 20, 2001, 11:50:13 AM7/20/01
to
I am wondering if the dynamic loading of the libpthread that
ships with Linux RedHat 6.2 is supported. I have glibc-2.1.3-15
installed. Some background...

I have a PAM module which requires functionality contained
in some 3rd party shared libraries. The 3rd party shared libraries
link against libpthread. The PAM module and dependent libraries are
loaded fine, but on the unload the progarm unloading the module
receives SIGSEGV. I removed all code from the PAM module so that
it consisted of stub routines, linked it against libpthread and
reproduced the problem. So the problem appears to be related to
the dynamic loading/unloading of libpthread. The stack of the
failure, when run under gdb:
[root@dhcp107-119 security]# gdb /usr/bin/passwd
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-redhat-linux"...
(gdb) run
Starting program: /usr/bin/passwd
New UNIX password:
BAD PASSWORD: it is based on a dictionary word
Retype new UNIX password:
Cannot access memory at address 0x401eab14
(gdb) where
#0 0x4000af21 in _dl_debug_state () at dl-debug.c:56
#1 0x40158156 in _dl_close (map=0x804e328) at dl-close.c:195
#2 0x4001b430 in dlclose_doit (handle=0x804e328) at dlclose.c:26
#3 0x4000ac3b in _dl_catch_error (errstring=0x4001d080,
operate=0x4001b418 <dlclose_doit>, args=0x804e328) at
dl-error.c:141
#4 0x4001b8b9 in _dlerror_run (operate=0x4001b418 <dlclose_doit>,
args=0x804e328) at dlerror.c:125
#5 0x4001b3fe in dlclose (handle=0x804e328) at dlclose.c:32
#6 0x40021bba in _pam_free_handlers () from /lib/libpam.so.0
#7 0x4001ff70 in pam_end () from /lib/libpam.so.0
#8 0x804966b in main (argc=1, argv=0xbffffd44) at passwd.c:305
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x4001a000 0x4001d08c Yes /lib/libdl.so.2
0x4001e000 0x40025cd8 Yes /lib/libpam.so.0
0x40026000 0x40028960 Yes /lib/libpam_misc.so.0
0x40029000 0x4007183c Yes /lib/libpwdb.so.0
0x40073000 0x40078bfc Yes /usr/lib/libpopt.so.0
0x40079000 0x4016d85c Yes /lib/libc.so.6
0x40000000 0x40013ed0 Yes /lib/ld-linux.so.2
0x4016e000 0x4019ad7c Yes /lib/libcrypt.so.1
0x4019b000 0x401b0828 Yes /lib/libnsl.so.1
0x401b1000 0x401b9e20 Yes /lib/libnss_files.so.2
0x401ba000 0x401c2924 Yes /lib/security/pam_pwdb.so
0x401c3000 0x401ca980 Yes /lib/security/pam_cracklib.so
0x401d0000 0x401dacc0 Yes /usr/lib/libcrack.so.2
0x40016000 0x40017a64 Yes /lib/security/pam_mypam.so.1
0x401db000 0x401ed138 Yes /lib/libpthread.so.0
0x40018000 0x40019a28 Yes /lib/security/pam_deny.so

The address 0x401eab14 that cannot be accessed is clearly in the
libpthread.so.0 (0x401db000 < 0x401eab14 < 0x401ed138).

The library pam_mypam.so.1 is linked with the following command:
gcc -shared -O <...-L{libpaths} deleted...> -o pam_mypam.so.1
/home/ckime/nightly/obj/x86_linux_2/oss/login/pam/pdos_mypam.o
-lpthread -lpam

The pdos_mypam file contains stub routines for the PAM entry points:
/* pdos_mypam.c */
/* PAM stub C code begin */
#include <security/pam_appl.h>
#include <security/pam_modules.h>

int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
const char **argv)
{ return(PAM_SUCCESS); }

int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char
**argv)
{ return(PAM_SUCCESS); }

int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc,
const char **argv)
{ return(PAM_SUCCESS); }

int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc,
const char **argv)
{ return(PAM_SUCCESS); }

int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc,const char
**argv)
{ return(PAM_SUCCESS); }

int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char
**argv)
{ return(PAM_SUCCESS); }
/* PAM stub C code end */


Removing the -lpthread from the link command eliminates the problem.
Unfortunately, as mentioned earlier, the libraries with the functions
that I need link with libpthread, leading to the above described
SIGSEGV on the dl_close.

This works fine on Solaris platforms.

If the dynamic loading of libpthread is NOT supported, why is that?

Thanks for any info,

Chris Kime
ck...@austin.ibm.com

Arthur H. Gold

unread,
Jul 20, 2001, 9:41:08 PM7/20/01
to

Several things:

1) Do not use `-lpthread' when linking _anything_ (unless you know
_exactly_ what you're doing and have a good reason). Use `-pthread'
instead, which does two things: it sets the _REENTRANT flag (which you
need) and ensures that the link order is correct. In fact, due to these
constraints, when building a shared library, the option `-pthread' is
turned into a NOOP via the specs file for gcc (to see the specs file, do
a `gcc -v' to get its name on your installation).

2) The aforementioned link order is crucial, as libpthread.so must
interpose upon several system call wrappers within glibc for things to
work right.

3) Because of such things, dynamic loading of libpthread.so is basically
impossible.

The main reason that it works differently from Solaris is that the
Solaris kernel supplies the thread support, whereas linuxthreads is a
mostly user-space implementation, whose only kernel support is in the
__clone() system call, which is used to create a child process that
shares its parent's virtual memory space.

Further, the reason that you do _not_ need to link libraries directly
against libpthread.so (and you don't want to in any case) is that glibc
provides weak stubs for pthread functions (that `do the right thing' if
the application does not link to libpthread.so/do threading.

<OT>
If you need further explanation of these issues, I would be happy to
take this offline if you'd like; since I'm in town (and looking for
work) I'd also be happy to continue this in person in either an informal
or formal capacity.
</OT>

HTH,
--ag
--
Artie Gold, Austin, TX (finger the cs.utexas.edu account for more info)
mailto:ag...@bga.com or mailto:ag...@cs.utexas.edu
--
He looked like hell, but the devil was smiling.

Kaz Kylheku

unread,
Jul 20, 2001, 10:06:14 PM7/20/01
to
In article <6c73975a.01072...@posting.google.com>, CKime wrote:
>I am wondering if the dynamic loading of the libpthread that
>ships with Linux RedHat 6.2 is supported.

No. libpthread is integrated into libc. When a program is linked against
libpthread, the behavior of libc changes because libpthread overrides a
few symbols in libc. This provides thread safety to some internal modules
within libc (example: malloc and stdio become thread safe), and adds
some necessary multithreaded semantics to certain functions (example:
fork() calls pthread_atfork handlers, sets up threading environment in
child process).

Not only can you not dynamically load the threading library, but in
general you cannot dynamically load a shared library which uses threads
into an executable that was not compiled and linked for multithreading.

If some program is to support multithreaded plugins, it should be
compiled as a multithreaded application.

Paul Pluzhnikov

unread,
Jul 20, 2001, 11:14:50 PM7/20/01
to
"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
news:qs567.1072$zb.2...@news1.rdc1.bc.home.com...

> In article <6c73975a.01072...@posting.google.com>, CKime wrote:
> >I am wondering if the dynamic loading of the libpthread that
> >ships with Linux RedHat 6.2 is supported.
>
> If some program is to support multithreaded plugins, it should be
> compiled as a multithreaded application.
>
And I should add that if this works on Solaris as OP indicated,
it does so purely by accident, and may stop working upon
slightest change in the functionality of the plugin, subminor
patch of any libraries involved, or for no reason whatsoever ;-)


0 new messages