From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1231 invoked from network); 30 Apr 2007 19:46:56 -0000 X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,FORGED_RCVD_HELO autolearn=ham version=3.1.8 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 30 Apr 2007 19:46:56 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 81785 invoked from network); 30 Apr 2007 19:46:50 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 30 Apr 2007 19:46:50 -0000 Received: (qmail 16638 invoked by alias); 30 Apr 2007 19:46:48 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 23364 Received: (qmail 16628 invoked from network); 30 Apr 2007 19:46:46 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 30 Apr 2007 19:46:46 -0000 Received: (qmail 81472 invoked from network); 30 Apr 2007 19:46:46 -0000 Received: from smtp3-g19.free.fr (212.27.42.29) by a.mx.sunsite.dk with SMTP; 30 Apr 2007 19:46:42 -0000 Received: from [192.168.0.3] (bar06-2-82-224-157-131.fbx.proxad.net [82.224.157.131]) by smtp3-g19.free.fr (Postfix) with ESMTP id 7529B5DFCC for ; Mon, 30 Apr 2007 21:46:42 +0200 (CEST) Message-ID: <4636477B.8050608@yahoo.fr> Date: Mon, 30 Apr 2007 21:46:03 +0200 From: Guillaume Chazarain User-Agent: Thunderbird 1.5.0.10 (X11/20070302) MIME-Version: 1.0 To: zsh-workers@sunsite.dk Subject: [Patch] Fix race with signals in signal_block() Content-Type: multipart/mixed; boundary="------------060806040308090000060906" This is a multi-part message in MIME format. --------------060806040308090000060906 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi ! Here is patch to fix a bug where zsh can become unkillable (except of course with SIGKILL), I use Linux-2.6/i386 so the POSIX_SIGNALS macro is defined. signal_block() and signal_unblock() use two global variables dummy_sigset1 and dummy_sigset2. I observed a race between child_block() and oldmask = signal_block(newmask); /* Block all signals temporarily */ called in the zhandler() signal handler. The attached patch fixes the problem by getting rid of the global variables, and instead using the signal_block() and signal_unblock() functions. Hopefully I did not break the NO_SIGNAL_BLOCKING, SYSV_SIGNALS and BSD_SIGNALS cases. Cheers. -- Guillaume --------------060806040308090000060906 Content-Type: text/x-patch; name="zsh-signal-race.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="zsh-signal-race.diff" --- zsh-4.3.4/Src/signals.c +++ zsh-4.3.4/Src/signals.c @@ -200,15 +200,6 @@ signal_mask(int sig) * set. Return the old signal set. */ /**/ -#ifdef POSIX_SIGNALS - -/**/ -mod_export sigset_t dummy_sigset1, dummy_sigset2; - -/**/ -#else - -/**/ #ifndef BSD_SIGNALS sigset_t @@ -216,7 +207,11 @@ signal_block(sigset_t set) { sigset_t oset; -#ifdef SYSV_SIGNALS +#ifdef POSIX_SIGNALS + sigprocmask(SIG_BLOCK, &set, &oset); + +#else +# ifdef SYSV_SIGNALS int i; oset = blocked_set; @@ -226,7 +221,7 @@ signal_block(sigset_t set) sighold(i); } } -#else /* NO_SIGNAL_BLOCKING */ +# else /* NO_SIGNAL_BLOCKING */ /* We will just ignore signals if the system doesn't have * * the ability to block them. */ int i; @@ -238,7 +233,8 @@ signal_block(sigset_t set) signal_ignore(i); } } -#endif /* SYSV_SIGNALS */ +# endif /* SYSV_SIGNALS */ +#endif /* POSIX_SIGNALS */ return oset; } @@ -246,19 +242,17 @@ signal_block(sigset_t set) /**/ #endif /* BSD_SIGNALS */ -/**/ -#endif /* POSIX_SIGNALS */ - /* Unblock the signals in the given signal * * set. Return the old signal set. */ -#ifndef POSIX_SIGNALS - sigset_t signal_unblock(sigset_t set) { sigset_t oset; - + +#ifdef POSIX_SIGNALS + sigprocmask(SIG_UNBLOCK, &set, &oset); +#else # ifdef BSD_SIGNALS sigfillset(&oset); oset = sigsetmask(oset); @@ -288,12 +282,11 @@ signal_unblock(sigset_t set) } # endif /* SYSV_SIGNALS */ # endif /* BSD_SIGNALS */ +#endif /* POSIX_SIGNALS */ return oset; } -#endif /* POSIX_SIGNALS */ - /* set the process signal mask to * * be the given signal mask */ --- zsh-4.3.4/Src/signals.h +++ zsh-4.3.4/Src/signals.h @@ -100,26 +100,10 @@ #define restore_queue_signals(q) (queueing_enabled = (q)) -/* Make some signal functions faster. */ - -#ifdef POSIX_SIGNALS -#define signal_block(S) \ - ((dummy_sigset1 = (S)), \ - sigprocmask(SIG_BLOCK, &dummy_sigset1, &dummy_sigset2), \ - dummy_sigset2) -#else -# ifdef BSD_SIGNALS +#ifdef BSD_SIGNALS #define signal_block(S) sigblock(S) -# else +#else extern sigset_t signal_block _((sigset_t)); -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ +#endif /* BSD_SIGNALS */ -#ifdef POSIX_SIGNALS -#define signal_unblock(S) \ - ((dummy_sigset1 = (S)), \ - sigprocmask(SIG_UNBLOCK, &dummy_sigset1, &dummy_sigset2), \ - dummy_sigset2) -#else extern sigset_t signal_unblock _((sigset_t)); -#endif /* POSIX_SIGNALS */ --------------060806040308090000060906--