public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: Re: [PATCH 4/4] signal: Only handle on NSIG signals on signal functions (BZ #25657)
Date: Fri, 17 Apr 2020 10:25:26 -0300	[thread overview]
Message-ID: <c7bd12d4-9ce3-8f4e-700a-0d5e489abf38@linaro.org> (raw)
In-Reply-To: <20200313194827.4467-4-adhemerval.zanella@linaro.org>

Ping.

On 13/03/2020 16:48, Adhemerval Zanella wrote:
> The upper bits of the sigset_t s not fully initialized in the signal
> mask calls that return information from kernel (sigprocmask,
> sigpending, and pthread_sigmask), since the exported sigset_t size
> (1024 bits) is larger than Linux support one (64 or 128 bits).
> It might make sigisemptyset/sigorset/sigandset fail if the mask
> is filled prior the call.
> 
> This patch changes the internal signal function to handle up to
> supported Linux signal number (_NSIG), the remaining bits are
> untouched.
> 
> Checked on x86_64-linux-gnu and i686-linux-gnu.
> ---
>  nptl/Makefile                        |   2 +-
>  nptl/pthread_sigmask.c               |   7 +-
>  nptl/tst-signal8.c                   |  62 ++++++++++++
>  signal/Makefile                      |   1 +
>  signal/sigsetops.c                   |  12 +--
>  signal/tst-sigisemptyset.c           |  95 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/sigpending.c |   6 +-
>  sysdeps/unix/sysv/linux/sigsetops.h  | 143 +++++++++++++--------------
>  8 files changed, 236 insertions(+), 92 deletions(-)
>  create mode 100644 nptl/tst-signal8.c
>  create mode 100644 signal/tst-sigisemptyset.c
> 
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 4816fa254e..33fa03807e 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -293,7 +293,7 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
>  	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
>  	tst-flock1 tst-flock2 \
>  	tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
> -	tst-signal6 \
> +	tst-signal6 tst-signal8 \
>  	tst-exec1 tst-exec2 tst-exec3 tst-exec4 tst-exec5 \
>  	tst-exit1 tst-exit2 tst-exit3 \
>  	tst-stdio1 tst-stdio2 \
> diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
> index c6c6e83c08..d266d296c5 100644
> --- a/nptl/pthread_sigmask.c
> +++ b/nptl/pthread_sigmask.c
> @@ -29,12 +29,11 @@ __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
>    /* The only thing we have to make sure here is that SIGCANCEL and
>       SIGSETXID is not blocked.  */
>    if (newmask != NULL
> -      && (__builtin_expect (__sigismember (newmask, SIGCANCEL), 0)
> -	  || __builtin_expect (__sigismember (newmask, SIGSETXID), 0)))
> +      && (__glibc_unlikely (__sigismember (newmask, SIGCANCEL))
> +         || __glibc_unlikely (__sigismember (newmask, SIGSETXID))))
>      {
>        local_newmask = *newmask;
> -      __sigdelset (&local_newmask, SIGCANCEL);
> -      __sigdelset (&local_newmask, SIGSETXID);
> +      __clear_internal_signals (&local_newmask);
>        newmask = &local_newmask;
>      }
>  
> diff --git a/nptl/tst-signal8.c b/nptl/tst-signal8.c
> new file mode 100644
> index 0000000000..9da7e5ef07
> --- /dev/null
> +++ b/nptl/tst-signal8.c
> @@ -0,0 +1,62 @@
> +/* Tests for sigisemptyset and pthread_sigmask.
> +   Copyright (C) 2020 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/>.  */
> +
> +#include <signal.h>
> +
> +#include <support/check.h>
> +#include <support/xthread.h>
> +
> +static void *
> +tf (void *arg)
> +{
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (pthread_sigmask (SIG_BLOCK, 0, &set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigfillset (&set);
> +    TEST_COMPARE (pthread_sigmask (SIG_BLOCK, 0, &set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  return NULL;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  /* Ensure current SIG_BLOCK mask empty.  */
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (sigprocmask (SIG_BLOCK, &set, 0), 0);
> +  }
> +
> +  {
> +    pthread_t thr = xpthread_create (NULL, tf, NULL);
> +    xpthread_join (thr);
> +  }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/signal/Makefile b/signal/Makefile
> index 37de438bba..f3c19e2992 100644
> --- a/signal/Makefile
> +++ b/signal/Makefile
> @@ -49,6 +49,7 @@ tests		:= tst-signal tst-sigset tst-sigsimple tst-raise tst-sigset2 \
>  		   tst-sigwait-eintr tst-sigaction \
>  		   tst-minsigstksz-1 tst-minsigstksz-2 tst-minsigstksz-3 \
>  		   tst-minsigstksz-3a tst-minsigstksz-4 \
> +		   tst-sigisemptyset
>  
>  include ../Rules
>  
> diff --git a/signal/sigsetops.c b/signal/sigsetops.c
> index eb89e6780e..1165377876 100644
> --- a/signal/sigsetops.c
> +++ b/signal/sigsetops.c
> @@ -26,28 +26,28 @@
>  
>  int
>  attribute_compat_text_section
> -(__sigismember) (const __sigset_t *set, int sig)
> +__sigismember_compat (const __sigset_t *set, int sig)
>  {
>    return __sigismember (set, sig);
>  }
> -compat_symbol (libc, __sigismember, __sigismember, GLIBC_2_0);
> +compat_symbol (libc, __sigismember_compat, __sigismember, GLIBC_2_0);
>  
>  int
>  attribute_compat_text_section
> -(__sigaddset) (__sigset_t *set, int sig)
> +__sigaddset_compat (__sigset_t *set, int sig)
>  {
>    __sigaddset (set, sig);
>    return 0;
>  }
> -compat_symbol (libc, __sigaddset, __sigaddset, GLIBC_2_0);
> +compat_symbol (libc, __sigaddset_compat, __sigaddset, GLIBC_2_0);
>  
>  int
>  attribute_compat_text_section
> -(__sigdelset) (__sigset_t *set, int sig)
> +__sigdelset_compat (__sigset_t *set, int sig)
>  {
>    __sigdelset (set, sig);
>    return 0;
>  }
> -compat_symbol (libc, __sigdelset, __sigdelset, GLIBC_2_0);
> +compat_symbol (libc, __sigdelset_compat, __sigdelset, GLIBC_2_0);
>  
>  #endif
> diff --git a/signal/tst-sigisemptyset.c b/signal/tst-sigisemptyset.c
> new file mode 100644
> index 0000000000..9ed95496f2
> --- /dev/null
> +++ b/signal/tst-sigisemptyset.c
> @@ -0,0 +1,95 @@
> +/* Tests for sigisemptyset/sigorset/sigandset.
> +   Copyright (C) 2020 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/>.  */
> +
> +#include <signal.h>
> +
> +#include <support/check.h>
> +
> +static int
> +do_test (void)
> +{
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigfillset (&set);
> +    TEST_COMPARE (sigisemptyset (&set), 0);
> +  }
> +
> +  {
> +    sigset_t setfill, setempty, set;
> +    sigfillset (&setfill);
> +    sigemptyset (&setempty);
> +
> +    sigorset (&set, &setfill, &setempty);
> +    TEST_COMPARE (sigisemptyset (&set), 0);
> +
> +    sigandset (&set, &setfill, &setempty);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  /* Ensure current SIG_BLOCK mask empty.  */
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (sigprocmask (SIG_BLOCK, &set, 0), 0);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (sigprocmask (SIG_BLOCK, 0, &set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigfillset (&set);
> +    TEST_COMPARE (sigprocmask (SIG_BLOCK, 0, &set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  /* Block all signals.  */
> +  {
> +    sigset_t set;
> +    sigfillset (&set);
> +    TEST_COMPARE (sigprocmask (SIG_BLOCK, &set, 0), 0);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigemptyset (&set);
> +    TEST_COMPARE (sigpending (&set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  {
> +    sigset_t set;
> +    sigfillset (&set);
> +    TEST_COMPARE (sigpending (&set), 0);
> +    TEST_COMPARE (sigisemptyset (&set), 1);
> +  }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/sigpending.c b/sysdeps/unix/sysv/linux/sigpending.c
> index f6bedb5182..458a3cf99e 100644
> --- a/sysdeps/unix/sysv/linux/sigpending.c
> +++ b/sysdeps/unix/sysv/linux/sigpending.c
> @@ -15,13 +15,9 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
>  #include <signal.h>
> -#include <unistd.h>
> -
>  #include <sysdep.h>
> -#include <sys/syscall.h>
> -
> +#include <sigsetops.h>
>  
>  /* Change the set of blocked signals to SET,
>     wait until a signal arrives, and restore the set of blocked signals.  */
> diff --git a/sysdeps/unix/sysv/linux/sigsetops.h b/sysdeps/unix/sysv/linux/sigsetops.h
> index cb97c98b10..f6ca34c842 100644
> --- a/sysdeps/unix/sysv/linux/sigsetops.h
> +++ b/sysdeps/unix/sysv/linux/sigsetops.h
> @@ -28,81 +28,72 @@
>  /* Return the word index for SIG.  */
>  # define __sigword(sig) (((sig) - 1) / (8 * sizeof (unsigned long int)))
>  
> -# define __sigemptyset(set)					\
> -  (__extension__ ({						\
> -    int __cnt = _SIGSET_NWORDS;					\
> -    sigset_t *__set = (set);					\
> -    while (--__cnt >= 0)					\
> -      __set->__val[__cnt] = 0;					\
> -    (void)0;							\
> -  }))
> -
> -# define __sigfillset(set)					\
> -  (__extension__ ({						\
> -    int __cnt = _SIGSET_NWORDS;					\
> -    sigset_t *__set = (set);					\
> -    while (--__cnt >= 0)					\
> -      __set->__val[__cnt] = ~0UL;				\
> -    (void)0;							\
> -  }))
> -
> -# define __sigisemptyset(set)					\
> -  (__extension__ ({						\
> -    int __cnt = _SIGSET_NWORDS;					\
> -    const sigset_t *__set = (set);				\
> -    int __ret = __set->__val[--__cnt];				\
> -    while (!__ret && --__cnt >= 0)				\
> -      __ret = __set->__val[__cnt];				\
> -    __ret == 0;							\
> -  }))
> -
> -# define __sigandset(dest, left, right)				\
> -  (__extension__ ({						\
> -    int __cnt = _SIGSET_NWORDS;					\
> -    sigset_t *__dest = (dest);					\
> -    const sigset_t *__left = (left);				\
> -    const sigset_t *__right = (right);				\
> -    while (--__cnt >= 0)					\
> -      __dest->__val[__cnt] = (__left->__val[__cnt]		\
> -			      & __right->__val[__cnt]);		\
> -    (void)0;							\
> -  }))
> -
> -# define __sigorset(dest, left, right)				\
> -  (__extension__ ({						\
> -    int __cnt = _SIGSET_NWORDS;					\
> -    sigset_t *__dest = (dest);					\
> -    const sigset_t *__left = (left);				\
> -    const sigset_t *__right = (right);				\
> -    while (--__cnt >= 0)					\
> -      __dest->__val[__cnt] = (__left->__val[__cnt]		\
> -			      | __right->__val[__cnt]);		\
> -    (void)0;							\
> -  }))
> -
> -/* These macros needn't check for a bogus signal number;
> -   error checking is done in the non-__ versions.  */
> -# define __sigismember(set, sig)				\
> -  (__extension__ ({						\
> -    unsigned long int __mask = __sigmask (sig);			\
> -    unsigned long int __word = __sigword (sig);			\
> -    (set)->__val[__word] & __mask ? 1 : 0;			\
> -  }))
> -
> -# define __sigaddset(set, sig)					\
> -  (__extension__ ({						\
> -    unsigned long int __mask = __sigmask (sig);			\
> -    unsigned long int __word = __sigword (sig);			\
> -    (set)->__val[__word] |= __mask;				\
> -    (void)0;							\
> -  }))
> -
> -# define __sigdelset(set, sig)					\
> -  (__extension__ ({						\
> -    unsigned long int __mask = __sigmask (sig);			\
> -    unsigned long int __word = __sigword (sig);			\
> -    (set)->__val[__word] &= ~__mask;				\
> -    (void)0;							\
> - }))
> +# define __NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int )))
> +
> +static inline void
> +__sigemptyset (sigset_t *set)
> +{
> +  int cnt = __NSIG_WORDS;
> +  while (--cnt >= 0)
> +   set->__val[cnt] = 0;
> +}
> +
> +static inline void
> +__sigfillset (sigset_t *set)
> +{
> +  int cnt = __NSIG_WORDS;
> +  while (--cnt >= 0)
> +   set->__val[cnt] = ~0UL;
> +}
> +
> +static inline int
> +__sigisemptyset (const sigset_t *set)
> +{
> +  int cnt = __NSIG_WORDS;
> +  int ret = set->__val[--cnt];
> +  while (ret == 0 && --cnt >= 0)
> +    ret = set->__val[cnt];
> +  return ret == 0;
> +}
> +
> +static inline void
> +__sigandset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
> +{
> +  int cnt = __NSIG_WORDS;
> +  while (--cnt >= 0)
> +    dest->__val[cnt] = left->__val[cnt] & right->__val[cnt];
> +}
> +
> +static inline void
> +__sigorset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
> +{
> +  int cnt = __NSIG_WORDS;
> +  while (--cnt >= 0)
> +    dest->__val[cnt] = left->__val[cnt] | right->__val[cnt];
> +}
> +
> +static inline int
> +__sigismember (const sigset_t *set, int sig)
> +{
> +  unsigned long int mask = __sigmask (sig);
> +  unsigned long int word = __sigword (sig);
> +  return set->__val[word] & mask ? 1 : 0;
> +}
> +
> +static inline void
> +__sigaddset (sigset_t *set, int sig)
> +{
> +  unsigned long int mask = __sigmask (sig);
> +  unsigned long int word = __sigword (sig);
> +  set->__val[word] |= mask;
> +}
> +
> +static inline void
> +__sigdelset (sigset_t *set, int sig)
> +{
> +  unsigned long int mask = __sigmask (sig);
> +  unsigned long int word = __sigword (sig);
> +  set->__val[word] &= ~mask;
> +}
>  
>  #endif /* bits/sigsetops.h */
> 

  reply	other threads:[~2020-04-17 13:25 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-13 19:48 [PATCH v2 1/4] nptl: Move pthread_sigmask implementation to libc Adhemerval Zanella
2020-03-13 19:48 ` [PATCH 2/4] ia64: Remove sigprocmask/sigblock objects from libpthread Adhemerval Zanella
2020-04-17 13:25   ` Adhemerval Zanella
2020-04-21 11:56   ` Florian Weimer
2020-04-21 12:06     ` Adhemerval Zanella
2020-03-13 19:48 ` [PATCH v2 3/4] linux: Use pthread_sigmask on sigprocmask Adhemerval Zanella
2020-04-17 13:25   ` Adhemerval Zanella
2020-04-21 12:01   ` Florian Weimer
2020-04-21 12:30     ` Adhemerval Zanella
2020-04-21 12:35       ` Florian Weimer
2020-04-21 13:01         ` Adhemerval Zanella
2020-03-13 19:48 ` [PATCH 4/4] signal: Only handle on NSIG signals on signal functions (BZ #25657) Adhemerval Zanella
2020-04-17 13:25   ` Adhemerval Zanella [this message]
2020-04-21 12:53   ` Florian Weimer
2020-04-21 13:11     ` Adhemerval Zanella
2020-04-21 13:14       ` Florian Weimer
2020-04-21 13:29         ` Adhemerval Zanella
2020-04-21 13:47           ` Florian Weimer
2020-04-21 14:02             ` Adhemerval Zanella
2020-04-21 14:07               ` Florian Weimer
2020-04-21 14:10                 ` Adhemerval Zanella
2020-04-21 14:35                   ` Florian Weimer
2020-04-21 14:36                     ` Adhemerval Zanella
2020-04-21 15:05                   ` Andreas Schwab
2020-04-21 17:28                     ` Florian Weimer
2020-04-21 17:49                       ` Adhemerval Zanella
2020-04-21 18:40                         ` Andreas Schwab
2020-04-21 19:00                           ` Adhemerval Zanella
2020-04-21 21:14                             ` Andreas Schwab
2020-04-22  8:32                               ` Florian Weimer
2020-04-22 11:34                                 ` Adhemerval Zanella
2020-04-17 13:25 ` [PATCH v2 1/4] nptl: Move pthread_sigmask implementation to libc Adhemerval Zanella
2020-04-21 11:50 ` Florian Weimer
2020-04-21 14:06   ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c7bd12d4-9ce3-8f4e-700a-0d5e489abf38@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).