[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#222130: [PATCH] : fix invalid __libc_dlclose() in nsswitch.c



tags 222130 patch
quit

Hi,

I get similar behavior here on a variety of Debian systems (stable,
testing and probably unstable too since I checked glibc cvs and the
bug is there).  I believe this is the same bug as the original
submitter reported, at least the valgrind spew at exit is strikengly
similar.  The previous spews are somethign different, but it isn't
clear that the submitter is worried about those.

The problem occurs at program shutdown when there is an invalid lookup
method in /etc/nsswitch.conf and the program has tried to use that
method.  See [1] for a demonstration.

Debian by default installs a /etc/nsswith.conf that looks like:

protocols:      db files

On at least a stable and a testing system here the 'db' lookup method
does not have a corresponding library (there is no libnss_db* on the
system).  That means that most systems should be able to demonstrate
this bug as long as /etc/nsswitch.conf has not been fixed.  If you
want to ensure that you see the bug, just add an invalid lookup method
to the front of the list:

protocols:      invalid_method db files

The patch [0] fixes the problem by not trying to close an invalid
library handle.  It took some reading to see why we check for -1 and
not NULL.  If __nss_lookup_function() fails to open a lookup method it
found in /etc/nsswitch.conf it marks the handle as -1 at line 354 of
nsswitch.c.  The -1 is used so that the next time through it doesn't
waste resources looking for a method that isn't available.  NULL is
used only for libraries that might exist (__nss_lookup_function()
hasn't yet looked for those libraries).

Thanks for all the good work,

David

[0] : A patch that fixes the problem.

* nss/nsswitch.c (free_mem) : Don't try to close a library handle
  if the handle is invalid.  The handle will be marked as '-1' if
  a previous attempt to open that library was unsuccessful.

--- nss/nsswitch.c.orig	Mon Feb 23 15:58:40 2004
+++ nss/nsswitch.c	Mon Feb 23 16:10:53 2004
@@ -746,7 +746,8 @@
     {
       service_library *oldl = library;
 
-      __libc_dlclose (library->lib_handle);
+      if (library->lib_handle !=  (void *) -1l)
+        __libc_dlclose (library->lib_handle);
 
       library = library->next;
       free (oldl);


[1] Demonstration of the SIGSEGV

$ cat nssbug.c
#include <netdb.h>
int
main(int argc, char *argv[]) {
        struct protoent *protoent;
        protoent = getprotobyname("udp");
        return 0;
}
$ gcc nssbug.c -o nssbug
$ valgrind --num-callers=6 ./nssbug
==24898== Memcheck, a memory error detector for x86-linux.
==24898== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==24898== Using valgrind-2.1.0, a program supervision framework for x86-linux.
==24898== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==24898== Estimated CPU clock rate is 1390 MHz
==24898== For more details, rerun with: -v
==24898== 
==24898== Invalid read of size 1
==24898==    at 0x40315F6F: _dl_close (dl-close.c:51)
==24898==    by 0x40316B0A: do_dlclose (dl-libc.c:93)
==24898==    by 0x40009ACA: _dl_catch_error (in /lib/ld-2.2.5.so)
==24898==    by 0x40316A4F: dlerror_run (dl-libc.c:42)
==24898==    by 0x40316BB0: __libc_dlclose (dl-libc.c:121)
==24898==    by 0x402FBF0C: free_mem (nsswitch.c:749)
==24898==  Address 0x18F is not stack'd, malloc'd or free'd
==24898== 
==24898== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==24898==  Address not mapped to object at address 0x18F
==24898==    at 0x40315F6F: _dl_close (dl-close.c:51)
==24898==    by 0x40316B0A: do_dlclose (dl-libc.c:93)
==24898==    by 0x40009ACA: _dl_catch_error (in /lib/ld-2.2.5.so)
==24898==    by 0x40316A4F: dlerror_run (dl-libc.c:42)
==24898==    by 0x40316BB0: __libc_dlclose (dl-libc.c:121)
==24898==    by 0x402FBF0C: free_mem (nsswitch.c:749)
==24898== 
==24898== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==24898== malloc/free: in use at exit: 1732 bytes in 9 blocks.
==24898== malloc/free: 43 allocs, 34 frees, 3431 bytes allocated.
==24898== For a detailed leak analysis,  rerun with: --leak-check=yes
==24898== For counts of detected errors, rerun with: -v
Segmentation fault (core dumped)
$



Reply to: