This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
nsswitch.c loads shared libraries without specifying __RTLD_DLOPEN.
- From: "VY Newsum" <newsum at fel dot tno dot nl>
- To: libc-alpha at sources dot redhat dot com
- Date: Sun, 07 Nov 2004 12:23:00 +0100
- Subject: nsswitch.c loads shared libraries without specifying __RTLD_DLOPEN.
- Organization: TNO-FEL
Hi,
I've just compiled and installed a reasonably fresh (20041104) copy of
the toolchain and various packages and am now confronted with a problem
loading one of the shared libraries.
The problem manifests itself using the nss subsystem, in combination
with the libnss_ldap library.
A very simple testcase that triggers the problem:
====
#include <sys/types.h>
#include <pwd.h>
#define NONEXISTENTUID 12000
main()
{
getpwuid(NONEXISTENTUID);
}
====
The NONEXISTENTUID should refer to a uid that can not be resolved using
other services.
My nsswitch.conf entry for the 'passwd' database is:
passwd: files ldap
Whenever I perform a lookup for a name that is not resolvable by the
'files' service, it tries to load the libnss_ldap library and all the
auxiliary libraries that it depends on.
It is during that process that I receive a segmentation fault
(loading 'libcrypto.so.0.9.7').
Using gdb, I can pinpoint the location where the segfault occurs:
Line 1335 in elf/dl-load.c: __stack_prot |= PROT_EXEC;
This is what I think is going on:
As 'readelf -l libcrypto.so.0.9.7' confirms it:
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg
Align
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
the, 'libcrypto' library needs its stack to be executable.
in 'nss/nsswitch.c', the service specific shared library is loaded at
line 344:
ni->library->lib_handle = __libc_dlopen (shlib_name);
According to 'include/dlfcn.h', line 15:
#define __libc_dlopen(name) __libc_dlopen_mode (name, RTLD_LAZY);
So here the problem is: __libc_dlopen_mode is called without specifying
the __RTLD_DLOPEN flag, so the condition at
Line 1321 of elf/dl-load.c: if (mode & __RTLD_DLOPEN)
is always false, and as a result, an attempt to modify __stack_prot is
made at line 1335 of elf/dl-load.c.
Because __stack_prot has the attribute_relro attribute, the
segmentation fault is generated.
The way I see it there are two possible solutions to this problem:
1) modify 'nss/nsswitch.c' at line 344 to:
ni->library->lib_handle =
__libc_dlopen_mode (shlib_name, (__RTLD_DLOPEN | RTLD_LAZY));
or
2) modify 'include/dlfcn.h' at line 15 to:
#define __libc_dlopen(name) \
__libc_dlopen_mode (name, (__RTLD_DLOPEN | RTLD_LAZY));
I cannot foresee the consequences of these changes, so I leave this up
to you guys.
I personnaly tried the first option because I thought it had the least
impact and this indeed seems to work for me.
In case I'm totally wrong about this, I'd appreciate some hints about
what to do instead.
As an afterthought: Searching for this in bugzilla, I found a bug report
that might be related to this:
http://sources.redhat.com/bugzilla/show_bug.cgi?id=419
(ld.so crashes if libgcc_s.so.1 has an executable stack)
It think so because at various locations in the glibc tree,
'libgcc_s.so.1' is loaded by means of
void *handle = __libc_dlopen ("libgcc_s.so.1");
which, as I explained above, doesn't pass the __RTLD_DLOPEN flag.
That could therefore be the cause of the segmentation fault there,
so if option 2) above would be chosen, those kinds of problems
would also be fixed.
Regards,
Vincent Newsum.
PS: Here is the patch that I applied:
=======
diff -Naur glibc-2.3.4-20041104.orig/nss/nsswitch.c
glibc-2.3.4-20041104/nss/nsswitch.c
--- glibc-2.3.4-20041104.orig/nss/nsswitch.c 2004-06-15
22:10:03.000000000 +0200
+++ glibc-2.3.4-20041104/nss/nsswitch.c 2004-11-07 11:14:19.628167352
+0100
@@ -341,7 +341,8 @@
".so"),
__nss_shlib_revision);
- ni->library->lib_handle = __libc_dlopen (shlib_name);
+ ni->library->lib_handle = __libc_dlopen_mode (shlib_name,
+ (__RTLD_DLOPEN | RTLD_LAZY));
if (ni->library->lib_handle == NULL)
{
/* Failed to load the library. */
--
------------------------------------------------------------------------------
The disclaimer that applies to e-mail from
TNO Physics and Electronics Laboratory
can be found on: http://www.tno.nl/disclaimer/email.html
------------------------------------------------------------------------------