Package: libc6
Version: 2.1.3-10
Severity: normal


[This report was also sent to the upstream maintainers. I'm filing it
 also with the Debian BTS for completeness and possibly a quicker fix.]

Description
-----------

        As mentioned in the BUGS file [i.e. /usr/share/doc/libc6/BUGS.gz],
        there are problems with signal handling when using LinuxThreads. One
        of them is in sysdeps/posix/signal.c:
        
        libpthread overrides glibc's sigaction() function (which is declared
        as a weak alias in glibc) and provides its own (see
        linuxthreads/signal.c). This custom function stores the old signal
        handler in a custom struct. Now glibc's signal() function ultimately
        calls __sigaction(), a glibc internal function that calls Linux'
        rt_sigaction() syscall, *without* calling LinuxThreads' overloaded
        sigaction() function. Of course, the returned signal handler is
        different than the actual signal handler.
        
        Imagine a case where a threaded application (let's call it nscd)
        sets up a signal handler (SIG_IGN) for SIGPIPE using sigaction().
        Now this application uses a library (let's call this one
        libnss_pgsql/libpgsql) that also wants to protect against I/O errors
        and sets up a signal handler (SIG_IGN) for SIGPIPE using signal()
        just before doing I/O. Now, because of the bug, signal() does not
        return the real signal handler but the SIG_DFL handler. After doing
        I/O the library tries to re-set the handler to the one returned by
        the former signal() call - the wrong one! This leads to nscd exiting
        if there is an I/O error. (Like pressing CTRL-C while doing "ls -l".)
        
        Kudos go to Michael Karcher for hunting down the actual location of the
        bug.

How to Repeat
-------------

        srittau@moby:~$ cat sig.c
        #include <stdio.h>
        #include <signal.h>
        
        int main()
        {
          struct sigaction old;
        
          signal(SIGPIPE, SIG_IGN);
          sigaction(SIGPIPE, NULL, &old);
          printf("%p\n", old.sa_handler);
        
          return 0;
        }
        srittau@moby:~$ gcc sig.c -o sig    
        srittau@moby:~$ ./sig 
        0x1                                            [i.e. SIG_IGN]
        srittau@moby:~$ gcc sig.c -o sig -lpthread
        srittau@moby:~$ ./sig
        (nil)                                          [i.e. SIG_DFL]
        srittau@moby:~$ 

Fix
---

        Apply the following patch (by Michael) to sysdeps/posix/signal.c:
        
        --- glibc-2.1.3/sysdeps/posix/signal.c.buggy    Thu Jul  6 10:25:00 2000
        +++ glibc-2.1.3/sysdeps/posix/signal.c  Thu Jul  6 10:25:18 2000
        @@ -43,7 +43,7 @@
           if (__sigemptyset (&act.sa_mask) < 0)
             return SIG_ERR;
           act.sa_flags = __sigismember (&_sigintr, sig) ? 0 : SA_RESTART;
        -  if (__sigaction (sig, &act, &oact) < 0)
        +  if (sigaction (sig, &act, &oact) < 0)
             return SIG_ERR;
        
           return oact.sa_handler;
        
        This patch causes signal() to use the weak sigaction() function which
        can be overloaded by libraries like libpthread.

 - Sebastian

-- System Information
Debian Release: 2.2
Architecture: i386
Kernel: Linux moby 2.4.0-test2 #1 Don Jun 29 19:05:32 CEST 2000 i686

Versions of packages libc6 depends on:
ii  ldso                          1.9.11-9   The Linux dynamic linker, library 



--  
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to