diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-11-24 08:59:54 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-11-24 10:01:01 +0100 |
commit | f9592d65f2eb7381ff0ff8b9b92ffc41e562fb0a (patch) | |
tree | 761c0b729f8a2c58ee451506c98b2537be408115 | |
parent | 94c91ce23106ec21905e1c01afbec0323aacc4e6 (diff) | |
download | glibc-f9592d65f2eb7381ff0ff8b9b92ffc41e562fb0a.tar.gz glibc-f9592d65f2eb7381ff0ff8b9b92ffc41e562fb0a.tar.xz glibc-f9592d65f2eb7381ff0ff8b9b92ffc41e562fb0a.zip |
nptl: Do not set signal mask on second setjmp return [BZ #28607]
__libc_signal_restore_set was in the wrong place: It also ran when setjmp returned the second time (after pthread_exit or pthread_cancel). This is observable with blocked pending signals during thread exit. Fixes commit b3cae39dcbfa2432b3f3aa28854d8ac57f0de1b8 ("nptl: Start new threads with all signals blocked [BZ #25098]"). Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> (cherry picked from commit e186fc5a31e46f2cbf5ea1a75223b4412907f3d8)
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | nptl/pthread_create.c | 4 | ||||
-rw-r--r-- | sysdeps/pthread/Makefile | 1 | ||||
-rw-r--r-- | sysdeps/pthread/tst-pthread-exit-signal.c | 45 |
4 files changed, 49 insertions, 2 deletions
diff --git a/NEWS b/NEWS index 979a012dba..a7a235eb89 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,7 @@ The following bugs are resolved with this release: [27706] select fails to update timeout on error [27744] Support different libpthread/ld.so load orders for gdb -p [27892] powerpc: scv ABI error handling fails to check IS_ERR_VALUE + [28607] Masked signals are delivered on thread exit Version 2.33 diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index f13d8e44a4..337a7dcba6 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -434,8 +434,6 @@ START_THREAD_DEFN unwind_buf.priv.data.prev = NULL; unwind_buf.priv.data.cleanup = NULL; - __libc_signal_restore_set (&pd->sigmask); - /* Allow setxid from now onwards. */ if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2)) futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE); @@ -445,6 +443,8 @@ START_THREAD_DEFN /* Store the new cleanup handler info. */ THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf); + __libc_signal_restore_set (&pd->sigmask); + /* We are either in (a) or (b), and in either case we either own PD already (2) or are about to own PD (1), and so our only restriction would be that we can't free PD until we know we diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 53b65ef349..2df947cb0d 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -108,6 +108,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-unload \ tst-unwind-thread \ tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ + tst-pthread-exit-signal \ # Files which must not be linked with libpthread. diff --git a/sysdeps/pthread/tst-pthread-exit-signal.c b/sysdeps/pthread/tst-pthread-exit-signal.c new file mode 100644 index 0000000000..b4526fe663 --- /dev/null +++ b/sysdeps/pthread/tst-pthread-exit-signal.c @@ -0,0 +1,45 @@ +/* Test that pending signals are not delivered on thread exit (bug 28607). + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Due to bug 28607, pthread_kill (or pthread_cancel) restored the + signal mask during during thread exit, triggering the delivery of a + blocked pending signal (SIGUSR1 in this test). */ + +#include <support/xthread.h> +#include <support/xsignal.h> + +static void * +threadfunc (void *closure) +{ + sigset_t sigmask; + sigfillset (&sigmask); + xpthread_sigmask (SIG_SETMASK, &sigmask, NULL); + xpthread_kill (pthread_self (), SIGUSR1); + pthread_exit (NULL); + return NULL; +} + +static int +do_test (void) +{ + pthread_t thr = xpthread_create (NULL, threadfunc, NULL); + xpthread_join (thr); + return 0; +} + +#include <support/test-driver.c> |