linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Documenting sigaltstack SS_AUTODISRM
@ 2017-05-22 20:38 Michael Kerrisk (man-pages)
  2017-05-22 23:36 ` Stas Sergeev
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-05-22 20:38 UTC (permalink / raw)
  To: Stas Sergeev; +Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Stas,

I have attempted to document the SS_AUTODISARM feature that you added
in Linux 4.7.

Could you please take a look at the SS_AUTODISARM pieces in the
sigaltstack() man page below? There is also one FIXME that I would
like help with.

It seems to me that the API has become rather odd now. It is no longer
possible to simply check whether code is executing on an alternative
stack by using

    sigaltstack(NULL, &old_ss);
    if (old_ss.ss_flags & SS_ONSTACK)
        ....

Thanks,

Michael


NAME
       sigaltstack - set and/or get signal stack context

SYNOPSIS
       #include <signal.h>

       int sigaltstack(const stack_t *ss, stack_t *old_ss);

   Feature    Test    Macro   Requirements   for   glibc   (see   fea‐
   ture_test_macros(7)):

       sigaltstack():
           _XOPEN_SOURCE >= 500
               || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
               || /* Glibc versions <= 2.19: */ _BSD_SOURCE

DESCRIPTION
       sigaltstack() allows a process to define a new alternate signal
       stack and/or retrieve the state of an existing alternate signal
       stack.  An alternate signal stack is used during the  execution
       of  a  signal handler if the establishment of that handler (see
       sigaction(2)) requested it.

       The normal sequence of events for  using  an  alternate  signal
       stack is the following:

       1. Allocate an area of memory to be used for the alternate sig‐
          nal stack.

       2. Use sigaltstack() to inform the system of the existence  and
          location of the alternate signal stack.

       3. When  establishing  a  signal  handler  using  sigaction(2),
          inform the system that the signal handler should be executed
          on  the  alternate signal stack by specifying the SA_ONSTACK
          flag.

       The ss argument is used  to  specify  a  new  alternate  signal
       stack,  while  the old_ss argument is used to retrieve informa‐
       tion about the currently established signal stack.  If  we  are
       interested  in  performing  just  one  of these tasks, then the
       other argument can be specified as NULL.

       The stack_t type used to type the arguments of this function is
       defined as follows:

           typedef struct {
               void  *ss_sp;     /* Base address of stack */
               int    ss_flags;  /* Flags */
               size_t ss_size;   /* Number of bytes in stack */
           } stack_t;

       To  establish  a new alternate signal stack, the fields of this
       structure are set as follows:

       ss.ss_flags
              This field contains either 0, or the following flag:

              SS_AUTODISARM (since Linux 4.7)
                     Clear the  alternate  signal  stack  settings  on
                     entry  to  the  signal  handler.  When the signal
                     handler returns, the  previous  alternate  signal
                     stack settings are restored.

                     This  flag  was  added  in  order make it safe to
                     switch away from the signal handler with swapcon‐
                     text(3).   Without this flag, a subsequently han‐
                     dled  signal  will  corrupt  the  state  of   the
                     switched-away  signal  handler.  On kernels where
                     this flag is not supported,  sigaltstack()  fails
                     with the error EINVAL when this flag is supplied.

       ss.ss_sp
              This  field specifies the starting address of the stack.
              When a signal handler is invoked on the alternate stack,
              the  kernel  automatically  aligns  the address given in
              ss.ss_sp to a suitable address boundary for the underly‐
              ing hardware architecture.

       ss.ss_size
              This  field  specifies  the size of the stack.  The con‐
              stant SIGSTKSZ is defined to be large  enough  to  cover
              the  usual  size  requirements  for  an alternate signal
              stack, and the constant MINSIGSTKSZ defines the  minimum
              size required to execute a signal handler.

       To  disable  an  existing stack, specify ss.ss_flags as SS_DIS‐
       ABLE.  In this case, the kernel  ignores  any  other  flags  in
       ss.ss_flags and the remaining fields in ss.

       If  old_ss  is  not NULL, then it is used to return information
       about the alternate signal stack which was in effect  prior  to
       the call to sigaltstack().  The old_ss.ss_sp and old_ss.ss_size
       fields return the starting address and size of that stack.  The
       old_ss.ss_flags may return either of the following values:

       SS_ONSTACK
              The process is currently executing on the alternate sig‐
              nal stack.  (Note that it is not possible to change  the
              alternate  signal stack if the process is currently exe‐
              cuting on it.)

       SS_DISABLE
              The alternate signal stack is currently disabled.

              Alternatively, this value is returned if the process  is
              currently  executing  on  an alternate signal stack that
              was established using the SS_AUTODISARM flag.   In  this
              case,  it is safe to switch away from the signal handler
              with swapcontext(3).  It is also possible to  set  up  a
              different  alternative signal stack using a further call
              to sigaltstack().


              ┌─────────────────────────────────────────────────────┐
              │FIXME                                                │
              ├─────────────────────────────────────────────────────┤
              │Was it intended that one  can  set  up  a  different │
              │alternative signal stack in this scenario? (In pass‐ │
              │ing,  if  one  does  this,   the   sigaltstack(NULL, │
              │&old_ss)  now returns old_ss.ss_flags==SS_AUTODISARM │
              │rather  than  old_ss.ss_flags==SS_DISABLE.  The  API │
              │design here seems confusing...                       │
              └─────────────────────────────────────────────────────┘

       SS_AUTODISARM
              The  alternate  signal  stack  has  been  marked  to  be
              autodisarmed as described above.

       By specifying ss as NULL, and old_ss as a non-NULL  value,  one
       can  obtain the current settings for the alternate signal stack
       without changing them.

RETURN VALUE
       sigaltstack() returns 0 on success, or -1 on failure with errno
       set to indicate the error.

ERRORS
       EFAULT Either  ss  or  old_ss is not NULL and points to an area
              outside of the process's address space.

       EINVAL ss is not  NULL  and  the  ss_flags  field  contains  an
              invalid flag.

       ENOMEM The  specified  size  of  the new alternate signal stack
              ss.ss_size was less than MINSTKSZ.

       EPERM  An attempt was made to change the alternate signal stack
              while  it was active (i.e., the process was already exe‐
              cuting on the current alternate signal stack).

ATTRIBUTES
       For an explanation of the  terms  used  in  this  section,  see
       attributes(7).

       ┌──────────────┬───────────────┬─────────┐
       │Interface     │ Attribute     │ Value   │
       ├──────────────┼───────────────┼─────────┤
       │sigaltstack() │ Thread safety │ MT-Safe │
       └──────────────┴───────────────┴─────────┘
CONFORMING TO
       POSIX.1-2001, POSIX.1-2009, SUSv2, SVr4.

       The SS_AUTODISARM flag is a Linux extension.

NOTES
       The most common usage of an alternate signal stack is to handle
       the SIGSEGV signal that is generated if the space available for
       the  normal  process stack is exhausted: in this case, a signal
       handler for SIGSEGV cannot be invoked on the process stack;  if
       we wish to handle it, we must use an alternate signal stack.

       Establishing  an  alternate signal stack is useful if a process
       expects that it may  exhaust  its  standard  stack.   This  may
       occur,  for  example,  because the stack grows so large that it
       encounters the upwardly growing heap, or  it  reaches  a  limit
       established  by  a  call to setrlimit(RLIMIT_STACK, &rlim).  If
       the standard stack is exhausted, the kernel sends the process a
       SIGSEGV  signal.   In these circumstances the only way to catch
       this signal is on an alternate signal stack.

       On most hardware architectures supported by Linux, stacks  grow
       downward.   sigaltstack()  automatically  takes  account of the
       direction of stack growth.

       Functions called from a signal handler executing on  an  alter‐
       nate  signal  stack  will  also use the alternate signal stack.
       (This also applies to any handlers invoked  for  other  signals
       while  the process is executing on the alternate signal stack.)
       Unlike the standard stack, the system  does  not  automatically
       extend  the  alternate  signal  stack.  Exceeding the allocated
       size of the alternate signal stack will lead  to  unpredictable
       results.

       A  successful  call to execve(2) removes any existing alternate
       signal stack.  A child process created via fork(2)  inherits  a
       copy of its parent's alternate signal stack settings.

       sigaltstack()  supersedes the older sigstack() call.  For back‐
       ward compatibility, glibc also provides  sigstack().   All  new
       applications should be written using sigaltstack().

   History
       4.2BSD  had  a sigstack() system call.  It used a slightly dif‐
       ferent struct, and had the major disadvantage that  the  caller
       had to know the direction of stack growth.

EXAMPLE
       The  following  code  segment  demonstrates  the use of sigalt‐
       stack():

           stack_t ss;

           ss.ss_sp = malloc(SIGSTKSZ);
           if (ss.ss_sp == NULL)
               /* Handle error */;
           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = 0;
           if (sigaltstack(&ss, NULL) == -1)
               /* Handle error */;

BUGS
       In the lead up to the development  of  the  Linux  2.4  kernel,
       someone   got   confused  and  allowed  the  kernel  to  accept
       SS_ONSTACK in ss.ss_flags, which results behavior that  is  the
       same  as  when  ss_flags  is  0.  On other implementations, and
       according to POSIX.1, SS_ONSTACK appears  only  as  a  reported
       flag in old_ss.ss_flags.  There is no need ever to specify this
       flag in ss.ss_flags.

SEE ALSO
       execve(2),    setrlimit(2),    sigaction(2),     siglongjmp(3),
       sigsetjmp(3), signal(7)


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-22 20:38 Documenting sigaltstack SS_AUTODISRM Michael Kerrisk (man-pages)
@ 2017-05-22 23:36 ` Stas Sergeev
  2017-05-23 10:35   ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-05-22 23:36 UTC (permalink / raw)
  To: mtk.manpages; +Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

22.05.2017 23:38, Michael Kerrisk (man-pages) пишет:
> Stas,
>
> I have attempted to document the SS_AUTODISARM feature that you added
> in Linux 4.7.
>
> Could you please take a look at the SS_AUTODISARM pieces in the
> sigaltstack() man page below? There is also one FIXME that I would
> like help with.
>
> It seems to me that the API has become rather odd now. It is no longer
> possible to simply check whether code is executing on an alternative
> stack by using
>
>      sigaltstack(NULL, &old_ss);
>      if (old_ss.ss_flags & SS_ONSTACK)
You mean, if SS_AUTODISARM was previously used, right?
Because I don't think we broke the existing code, or did we?
I can vaguely recall that I was submitting the patches
that were returning SS_ONSTACK even when SS_AUTODISARM
was used, but they were considered too complex.
This is possible to implement, but the agreement was
that it is not a big deal.

>         ss.ss_flags
>                This field contains either 0, or the following flag:
Is this correct?
AFAIK it can be SS_DISABLE too, and posix seems to allow any
other value for enable, which can be (on linux) SS_ONSTACK,
not only 0.
And SS_AUTODISARM can be ORed with the value.

>                ┌─────────────────────────────────────────────────────┐
>                │FIXME                                                │
>                ├─────────────────────────────────────────────────────┤
>                │Was it intended that one  can  set  up  a  different │
>                │alternative signal stack in this scenario? (In pass‐ │
>                │ing,  if  one  does  this,   the   sigaltstack(NULL, │
>                │&old_ss)  now returns old_ss.ss_flags==SS_AUTODISARM │
>                │rather  than  old_ss.ss_flags==SS_DISABLE.  The  API │
>                │design here seems confusing...                       │
>                └─────────────────────────────────────────────────────┘
My memory may be wrong here, but I think setting
up another alt stack was not supposed because the
previous settings would be restored upon sighandler
return. AFAIK I was trying to make up a proposal to
get such attempts explicitly blocked rather than
silently ignored, but again the simplicity was chosen.

>         SS_AUTODISARM
>                The  alternate  signal  stack  has  been  marked  to  be
>                autodisarmed as described above.
Initially this flag was supposed to be ORed with
the old values. Your descrition is correct, but if
more bit flags are added, this may became a
problem, as you are always treating it as a separate
value, not a bit flag.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-22 23:36 ` Stas Sergeev
@ 2017-05-23 10:35   ` Michael Kerrisk (man-pages)
  2017-05-23 11:03     ` Stas Sergeev
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-05-23 10:35 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: mtk.manpages, linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello Stas,

On 05/23/2017 01:36 AM, Stas Sergeev wrote:
> 22.05.2017 23:38, Michael Kerrisk (man-pages) пишет:
>> Stas,
>>
>> I have attempted to document the SS_AUTODISARM feature that you added
>> in Linux 4.7.
>>
>> Could you please take a look at the SS_AUTODISARM pieces in the
>> sigaltstack() man page below? There is also one FIXME that I would
>> like help with.
>>
>> It seems to me that the API has become rather odd now. It is no longer
>> possible to simply check whether code is executing on an alternative
>> stack by using
>>
>>      sigaltstack(NULL, &old_ss);
>>      if (old_ss.ss_flags & SS_ONSTACK)

> You mean, if SS_AUTODISARM was previously used, right?

Yes, that's what I meant.

> Because I don't think we broke the existing code, or did we?

Probably not, but it seems to me that there is some small
possibility that library code that makes use of sigaltstack()
to test whether a signal is being handled on an alternate signal 
stack, unaware that the main program employed SS_AUTODISARM,
could be confused/broken. I've no idea how likely this scenario 
is though. (I imagine it's rather unlikely.)

> I can vaguely recall that I was submitting the patches
> that were returning SS_ONSTACK even when SS_AUTODISARM
> was used, but they were considered too complex.
> This is possible to implement, but the agreement was
> that it is not a big deal.
> 
>>         ss.ss_flags
>>                This field contains either 0, or the following flag:
> Is this correct?
> AFAIK it can be SS_DISABLE too, 

It's correct in context. Just above in the man page its says:

       To  establish  a new alternate signal stack, the fields of this
       structure are set as follows:

The discussion of SS_DISABLE to disable the SS is lower in the page.

> and posix seems to allow any
> other value for enable, which can be (on linux) SS_ONSTACK,
> not only 0.

Yes, long ago someone got confused, as I've noted in a recently added
BUGS section in the page:

    BUGS
       In the lead up to the development  of  the  Linux  2.4  kernel,
       someone   got   confused  and  allowed  the  kernel  to  accept
       SS_ONSTACK in ss.ss_flags, which results behavior that  is  the
       same  as  when  ss_flags  is  0.  On other implementations, and
       according to POSIX.1, SS_ONSTACK appears  only  as  a  reported
       flag in old_ss.ss_flags.  There is no need ever to specify this
       flag in ss.ss_flags.

> And SS_AUTODISARM can be ORed with the value.
> 
>>                ┌─────────────────────────────────────────────────────┐
>>                │FIXME                                                │
>>                ├─────────────────────────────────────────────────────┤
>>                │Was it intended that one  can  set  up  a  different │
>>                │alternative signal stack in this scenario? (In pass‐ │
>>                │ing,  if  one  does  this,   the   sigaltstack(NULL, │
>>                │&old_ss)  now returns old_ss.ss_flags==SS_AUTODISARM │
>>                │rather  than  old_ss.ss_flags==SS_DISABLE.  The  API │
>>                │design here seems confusing...                       │
>>                └─────────────────────────────────────────────────────┘
> My memory may be wrong here, but I think setting
> up another alt stack was not supposed because the
> previous settings would be restored upon sighandler
> return. AFAIK I was trying to make up a proposal to
> get such attempts explicitly blocked rather than
> silently ignored, but again the simplicity was chosen.

So, I've done only limited experimentation here, but this is what 
I see in one experiment:

[[
* Set up two handlers for SIGX and SIGY, both using SA_ONSTACK.
* Establish alternate SS (1) using SS_AUTODISARM
  
  [SIGA is delivered]

* Handler for SIGA is called and handler is executed on alternate SS 1.
* The handler establishes a new alternate SS (2) with SS_AUTODISARM.

  [SIGB is delivered]

* Handler for SIGB is called and handler is executed on alternate SS 2.
* Handler for SIGB returns

  [SIGB is delivered]

* Handler for SIGB is called and handler is executed on alternate SS 2.
* Handler for SIGB returns
* Handler of SIGA returns

  [SIGA is delivered]

* Handler for SIGA is called and handler is executed on alternate SS 1.
]]

Summary: setting up another alternate signal stack seems to "work".
API history is littered with stories where users found out that
something unforeseen "worked", and so they used it. The question
is: what can go wrong if people do try using this "feature"?

>>         SS_AUTODISARM
>>                The  alternate  signal  stack  has  been  marked  to  be
>>                autodisarmed as described above.
> Initially this flag was supposed to be ORed with
> the old values. Your descrition is correct, but if
> more bit flags are added, this may became a
> problem, as you are always treating it as a separate
> value, not a bit flag.

Thanks for the confirmation.

At the end of this mail is a test program that I used to experiment
with this stuff. Here's a sample run that demonstrates the scenario
described above:

[[
$ ./t_sigaltstack_SS_AUTODISARM d 1
Autodisarm:                          YES
Try to establish new SS while on SS: YES
Initial SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]

Top of standard stack is near 0x7ffc2b16382c
Signal stack allocated at 0x69a000-0x6ae000
About to change SS: sp = 0x69a000; size = 81920; flags = [ SS_AUTODISARM ]
SS after change:    sp = 0x69a000; size = 81920; flags = [ SS_AUTODISARM ]

Send me a SIGQUIT (^\) or a SIGTSTP (^Z)
^\

Caught signal 3 (Quit)
Top of handler stack near       0x6adaa8
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]

Now try establishing a new signal stack while still executing on this one (1)
Signal stack allocated at 0x1baf000-0x1bc3000
Modifying SS to: sp = 0x1baf000; size = 81920; flags = [ SS_AUTODISARM ]
SS after update: sp = 0x1baf000; size = 81920; flags = [ SS_AUTODISARM ]

sleep(2) before displaying SS (send a signal now, if desired)
^Z

Caught signal 20 (Stopped)
Top of handler stack near      0x1bc2aa8
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]

sleep(2) before displaying SS (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
sleep(2) before return from handler (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
Returning from handler for signal 20
current SS: sp = 0x1baf000; size = 81920; flags = [ SS_AUTODISARM ]
sleep(2) before return from handler (send a signal now, if desired)
^Z

Caught signal 20 (Stopped)
Top of handler stack near      0x1bc2aa8
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]

sleep(2) before displaying SS (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
sleep(2) before return from handler (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
Returning from handler for signal 20
current SS: sp = 0x1baf000; size = 81920; flags = [ SS_AUTODISARM ]
Returning from handler for signal 3
===============================

Back in main
current SS: sp = 0x69a000; size = 81920; flags = [ SS_AUTODISARM ]
^\

Caught signal 3 (Quit)
Top of handler stack near       0x6adaa8
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]

sleep(2) before displaying SS (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
sleep(2) before return from handler (send a signal now, if desired)
current SS: sp = (nil); size = 0; flags = [ SS_DISABLE ]
Returning from handler for signal 3
===============================

Back in main
current SS: sp = 0x69a000; size = 81920; flags = [ SS_AUTODISARM ]
^C
]]
Cheers,

Michael

/*#* t_sigaltstack_SS_AUTODISARM.c

   COPYRIGHT-NOTICE
*/
#define _GNU_SOURCE
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define errExit(msg)    do { fprintf(stderr, "[FAILED] "); \
                             perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

#define errExitEN(en, msg) \
                        do { errno = en; perror(msg); \
                        exit(EXIT_FAILURE); } while (0)

#define SS_AUTODISARM   (1U << 31)

static int tryNewStack = 0;

static void
showSS(char *prefix, stack_t * osp)
{
    printf("%ssp = %p; size = %ld; flags = ", prefix,
           osp->ss_sp, (long) osp->ss_size);
    if (osp->ss_flags != 0) {
        printf("[ ");
        if (osp->ss_flags & SS_ONSTACK)
            printf("SS_ONSTACK ");
        if (osp->ss_flags & SS_DISABLE)
            printf("SS_DISABLE ");
        if (osp->ss_flags & SS_AUTODISARM)
            printf("SS_AUTODISARM ");
        printf("]");
    }
    printf("\n");
}

static void
showCurrentSS(char *msg)
{
    stack_t os;

    if (sigaltstack(NULL, &os) == -1)
        errExit("sigaltstack");
    showSS((msg != NULL) ? msg : "current SS: ", &os);
}

static const size_t stackSize = 10 * SIGSTKSZ;

static void
allocateSS(void **ss_sp)
{
    int s;
    void *p;

    s = posix_memalign(ss_sp, 4096, stackSize);
    if (s != 0)
        errExitEN(s, "posix_memalign");
    printf("Signal stack allocated at %p-%p\n",
           *ss_sp, (char *) *ss_sp + stackSize);
    for (s = 0; s < 256; s++)
        posix_memalign(&p, 4096, stackSize);
}

static void
handler(int sig)
{
    int x;

    printf("\n\nCaught signal %d (%s)\n", sig, strsignal(sig));
    printf("Top of handler stack near     %10p\n", (void *) &x);
    fflush(NULL);

    showCurrentSS(NULL);

    if (tryNewStack > 0) {
        stack_t sigstack, os;
        int s;

        printf("\nNow try establishing a new signal stack "
               "while still executing on this one (%d)\n", tryNewStack);

        tryNewStack--;

        allocateSS(&sigstack.ss_sp);
        sigstack.ss_size = stackSize;
        sigstack.ss_flags = SS_AUTODISARM;
        showSS("Modifying SS to: ", &sigstack);

        s = sigaltstack(&sigstack, NULL);
        if (s == -1) {
            fprintf(stderr, "[FAILED] ");
            perror("sigaltstack");
        }
        if (sigaltstack(NULL, &os) == -1)
            errExit("sigaltstack");
        else
            showCurrentSS("SS after update: ");
    }
    printf("\nsleep(2) before displaying SS "
            "(send a signal now, if desired)\n");
    sleep(2);
    showCurrentSS(NULL);
    printf("sleep(2) before return from handler"
            "(send a signal now, if desired)\n");
    sleep(2);
    showCurrentSS(NULL);
    printf("Returning from handler for signal %d\n", sig);
}

int
main(int argc, char *argv[])
{
    stack_t sigstack;
    struct sigaction sa;
    int j;
    int autodisarm;

    autodisarm = 0;
    if (argc > 1) {
        if (strchr(argv[1], 'd') != NULL)
            autodisarm = 1;
    }

    tryNewStack = (argc > 2) ? atoi(argv[2]) : 0;

    printf("Autodisarm:                          %s\n",
           autodisarm ? "YES" : "NO");
    printf("Try to establish new SS while on SS: %s\n",
           tryNewStack ? "YES" : "NO");

    showCurrentSS("Initial SS: ");

    printf("\nTop of standard stack is near %10p\n", (void *) &j);

    /* Allocate alternate stack and inform kernel of its existence */

    allocateSS(&sigstack.ss_sp);
    sigstack.ss_size = stackSize;
    sigstack.ss_flags = autodisarm ? SS_AUTODISARM : 0;
    showSS("About to change SS: ", &sigstack);
    if (sigaltstack(&sigstack, NULL) == -1)
        errExit("sigaltstack");

    showCurrentSS("SS after change:    ");

    /* Establish handlers for SIGQUIT and SIGTSTP */

    sa.sa_handler = handler;    
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_ONSTACK | SA_NODEFER;
        /* SA_NODEFER to allow experiments with interrupted handlers */

    if (sigaction(SIGQUIT, &sa, NULL) == -1)
        errExit("sigaction");
    if (sigaction(SIGTSTP, &sa, NULL) == -1)
        errExit("sigaction");

    printf("\nSend me a SIGQUIT (^\\) or a SIGTSTP (^Z)\n");

    for (;;) {
        pause();
        printf("===============================\n");
        printf("\nBack in main\n");

        showCurrentSS(NULL);
    }
}



-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-23 10:35   ` Michael Kerrisk (man-pages)
@ 2017-05-23 11:03     ` Stas Sergeev
  2017-05-23 12:26       ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-05-23 11:03 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

23.05.2017 13:35, Michael Kerrisk (man-pages) пишет:
> Hello Stas,
Hi. :)


>> Because I don't think we broke the existing code, or did we?
> Probably not, but it seems to me that there is some small
> possibility that library code that makes use of sigaltstack()
> to test whether a signal is being handled on an alternate signal
> stack, unaware that the main program employed SS_AUTODISARM,
> could be confused/broken. I've no idea how likely this scenario
> is though. (I imagine it's rather unlikely.)
OK, so the original problem was that to get the
more consistent checks, you'd need to keep alt
stack still set up but disarmed, while inside the
sighandler. If someone uses siglongjmp() at that
point, then it will be left dangling. Likely there are
ways around this, but nothing simple that I could
think of.

>> and posix seems to allow any
>> other value for enable, which can be (on linux) SS_ONSTACK,
>> not only 0.
> Yes, long ago someone got confused, as I've noted in a recently added
> BUGS section in the page:
But my understanding differs.
http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaltstack.html
---
The /ss_flags/ member specifies the new stack state.
If it is set to SS_DISABLE, the stack is disabled and /ss_sp/
and /ss_size/ are ignored. Otherwise, the stack shall be enabled
---

As you can see, it doesn't say "SS_DISABLE or 0 are
only possible values". It does not even mention 0 at all
as being a possible or suggested value, it only uses it in
an example.
So what you call a confusion, looks valid to me, according
to the above spec. Moreover, I use it in a real-life code,
and it would be interesting to know how many other people
do the same. If its just me, its one thing, but if it is a common
practice, then perhaps this part of a man page should be
reconsidered.

>> And SS_AUTODISARM can be ORed with the value.
>>
>>>                 ┌─────────────────────────────────────────────────────┐
>>>                 │FIXME                                                │
>>>                 ├─────────────────────────────────────────────────────┤
>>>                 │Was it intended that one  can  set  up  a  different │
>>>                 │alternative signal stack in this scenario? (In pass‐ │
>>>                 │ing,  if  one  does  this,   the   sigaltstack(NULL, │
>>>                 │&old_ss)  now returns old_ss.ss_flags==SS_AUTODISARM │
>>>                 │rather  than  old_ss.ss_flags==SS_DISABLE.  The  API │
>>>                 │design here seems confusing...                       │
>>>                 └─────────────────────────────────────────────────────┘
>> My memory may be wrong here, but I think setting
>> up another alt stack was not supposed because the
>> previous settings would be restored upon sighandler
>> return. AFAIK I was trying to make up a proposal to
>> get such attempts explicitly blocked rather than
>> silently ignored, but again the simplicity was chosen.
> So, I've done only limited experimentation here, but this is what
> I see in one experiment:
>
> [[
> * Set up two handlers for SIGX and SIGY, both using SA_ONSTACK.
> * Establish alternate SS (1) using SS_AUTODISARM
>    
>    [SIGA is delivered]
>
> * Handler for SIGA is called and handler is executed on alternate SS 1.
> * The handler establishes a new alternate SS (2) with SS_AUTODISARM.
>
>    [SIGB is delivered]
>
> * Handler for SIGB is called and handler is executed on alternate SS 2.
> * Handler for SIGB returns
>
>    [SIGB is delivered]
>
> * Handler for SIGB is called and handler is executed on alternate SS 2.
> * Handler for SIGB returns
> * Handler of SIGA returns
At this point the alt stack is set back to SS1,
undoing the effect of the just-done sigaltstack()
call.

>    [SIGA is delivered]
>
> * Handler for SIGA is called and handler is executed on alternate SS 1.
> ]]
>
> Summary: setting up another alternate signal stack seems to "work".
Only if you deliver SIGB while still inside SIGA handler,
which is a bit unusual. Certainly not worth calling this
"works" IMHO. The fact that this will be undone at SIGA
exit, is much more confusing to the user, so I'd say just
don't do that.
There IS a way to set a new alt stack while inside SIGA,
and I use that in a real-life code. It is to write the new
values to uc_stack. If you do this, the new settings will
be activated at the return from SIGA handler. Maybe
you can mention this possibility instead.

> API history is littered with stories where users found out that
> something unforeseen "worked", and so they used it. The question
> is: what can go wrong if people do try using this "feature"?
It will disappear at the exit from SIGA.
To me this is "wrong enough" to not suggest doing so.

>>>          SS_AUTODISARM
>>>                 The  alternate  signal  stack  has  been  marked  to  be
>>>                 autodisarmed as described above.
>> Initially this flag was supposed to be ORed with
>> the old values. Your descrition is correct, but if
>> more bit flags are added, this may became a
>> problem, as you are always treating it as a separate
>> value, not a bit flag.
> Thanks for the confirmation.
>
> At the end of this mail is a test program that I used to experiment
> with this stuff. Here's a sample run that demonstrates the scenario
> described above:
The kernel already has the sigaltstack test-case,
so maybe you can add some checks to it from your
test-case.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-23 11:03     ` Stas Sergeev
@ 2017-05-23 12:26       ` Michael Kerrisk (man-pages)
  2017-05-23 23:01         ` Stas Sergeev
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-05-23 12:26 UTC (permalink / raw)
  To: Stas Sergeev; +Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello Stas,

On 23 May 2017 at 13:03, Stas Sergeev <stsp@list.ru> wrote:
> 23.05.2017 13:35, Michael Kerrisk (man-pages) пишет:
>>
>> Hello Stas,
>
> Hi. :)
>
>
>>> Because I don't think we broke the existing code, or did we?
>>
>> Probably not, but it seems to me that there is some small
>> possibility that library code that makes use of sigaltstack()
>> to test whether a signal is being handled on an alternate signal
>> stack, unaware that the main program employed SS_AUTODISARM,
>> could be confused/broken. I've no idea how likely this scenario
>> is though. (I imagine it's rather unlikely.)
>
> OK, so the original problem was that to get the
> more consistent checks, you'd need to keep alt
> stack still set up but disarmed, while inside the
> sighandler. If someone uses siglongjmp() at that
> point, then it will be left dangling. Likely there are
> ways around this, but nothing simple that I could
> think of.

Okay.

>>> and posix seems to allow any
>>> other value for enable, which can be (on linux) SS_ONSTACK,
>>> not only 0.
>>
>> Yes, long ago someone got confused, as I've noted in a recently added
>> BUGS section in the page:
>
> But my understanding differs.
> http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaltstack.html
> ---
> The /ss_flags/ member specifies the new stack state.
> If it is set to SS_DISABLE, the stack is disabled and /ss_sp/
> and /ss_size/ are ignored. Otherwise, the stack shall be enabled
> ---
>
> As you can see, it doesn't say "SS_DISABLE or 0 are
> only possible values". It does not even mention 0 at all
> as being a possible or suggested value, it only uses it in
> an example.
> So what you call a confusion, looks valid to me, according
> to the above spec.

I think this is a misreading of the spec. The spec is saying that

    (ss_flags & SS_DISABLE) != 0

means disable the stack and

    (ss_flags & SS_DISABLE) == 0

means disable the stack.

POSIX.1 make no statement about the use of SS_ONSTACK to enable the
stack. And as far as I know, no other implementation attaches meaning
to SS_ONSTACK when establishing a signal stack. Some systems' man
pages are loosely worded in the manner of POSIX, but others are quite
explicit, with Solaris 8 and Irix 6.5 containing text such as the
following:

     If    ss is not NULL,    it points to a structure specifying the
  alternate
     signal stack that will take effect    upon return from sigaltstack.  [...]
    The ss_flags field specifies the new stack state and may be set
     to    the following:

     SS_DISABLE       The stack is    to be disabled and ss_sp and ss_size are
           ignored.  If    SS_DISABLE is not set, the stack will be
           enabled.

The strong implication there is that no value other than SS_DISABLE is
meaningful in ss.ss_flags. No other man page that I could find (and I
have quite a collection) suggested the (ss.ss_flags == SSONSTACK) is
meaningful.

> Moreover, I use it in a real-life code,
> and it would be interesting to know how many other people
> do the same. If its just me, its one thing, but if it is a common
> practice, then perhaps this part of a man page should be
> reconsidered.

By "use it" I presume you mean (ss.ss_flags == SS_ONSTACK).

Sure, you can use it on Linux, but it's a no-op there. And I just went
to check the Illumos source (which presumably mirrors its Solaris
ancestry), and there is this check in the sigaltstack()
implementation:

               if (ss.ss_flags & ~SS_DISABLE)
                        return (set_errno(EINVAL));

And in the FreeBSD source we find similar:

                if ((ss->ss_flags & ~SS_DISABLE) != 0)
                        return (EINVAL);

So, using SS_ONSTACK on Linux is a no-op that decreases code
portability. (And I am supposing that you use (ss.ss_flags ==
SS_ONSTACK) only because you've been misled into thinking its
legitimate from reading the kernel source.)

>>> And SS_AUTODISARM can be ORed with the value.
>>>
>>>>                 ┌─────────────────────────────────────────────────────┐
>>>>                 │FIXME                                                │
>>>>                 ├─────────────────────────────────────────────────────┤
>>>>                 │Was it intended that one  can  set  up  a  different │
>>>>                 │alternative signal stack in this scenario? (In pass‐ │
>>>>                 │ing,  if  one  does  this,   the   sigaltstack(NULL, │
>>>>                 │&old_ss)  now returns old_ss.ss_flags==SS_AUTODISARM │
>>>>                 │rather  than  old_ss.ss_flags==SS_DISABLE.  The  API │
>>>>                 │design here seems confusing...                       │
>>>>                 └─────────────────────────────────────────────────────┘
>>>
>>> My memory may be wrong here, but I think setting
>>> up another alt stack was not supposed because the
>>> previous settings would be restored upon sighandler
>>> return. AFAIK I was trying to make up a proposal to
>>> get such attempts explicitly blocked rather than
>>> silently ignored, but again the simplicity was chosen.
>>
>> So, I've done only limited experimentation here, but this is what
>> I see in one experiment:
>>
>> [[
>> * Set up two handlers for SIGX and SIGY, both using SA_ONSTACK.
>> * Establish alternate SS (1) using SS_AUTODISARM
>>       [SIGA is delivered]
>>
>> * Handler for SIGA is called and handler is executed on alternate SS 1.
>> * The handler establishes a new alternate SS (2) with SS_AUTODISARM.
>>
>>    [SIGB is delivered]
>>
>> * Handler for SIGB is called and handler is executed on alternate SS 2.
>> * Handler for SIGB returns
>>
>>    [SIGB is delivered]
>>
>> * Handler for SIGB is called and handler is executed on alternate SS 2.
>> * Handler for SIGB returns
>> * Handler of SIGA returns
>
> At this point the alt stack is set back to SS1,
> undoing the effect of the just-done sigaltstack()
> call.

(Yes.)

>
>>    [SIGA is delivered]
>>
>> * Handler for SIGA is called and handler is executed on alternate SS 1.
>> ]]
>>
>> Summary: setting up another alternate signal stack seems to "work".
>
> Only if you deliver SIGB while still inside SIGA handler,
> which is a bit unusual. Certainly not worth calling this
> "works" IMHO. The fact that this will be undone at SIGA
> exit, is much more confusing to the user, so I'd say just
> don't do that.

I agree that it is an unusual scenario. But, user-space programmers
outnumber kernel developers 10000 to 1, and over time they will find
every possible way to creatively use an API if it "works for them".
[1]

> There IS a way to set a new alt stack while inside SIGA,
> and I use that in a real-life code. It is to write the new
> values to uc_stack. If you do this, the new settings will
> be activated at the return from SIGA handler. Maybe
> you can mention this possibility instead.
>
>> API history is littered with stories where users found out that
>> something unforeseen "worked", and so they used it. The question
>> is: what can go wrong if people do try using this "feature"?
>
> It will disappear at the exit from SIGA.
> To me this is "wrong enough" to not suggest doing so.

See my comment above. It's weird because it will disappear at exit
from SIGA, but not "wrong". And it would not surprise me if one day
someone decided they had a use for it. (And the "don't document it" or
even "warn people in the documentation that they should not do it"
will not stop some intrepid souls from tying it.)

>>>>          SS_AUTODISARM
>>>>                 The  alternate  signal  stack  has  been  marked  to  be
>>>>                 autodisarmed as described above.
>>>
>>> Initially this flag was supposed to be ORed with
>>> the old values. Your descrition is correct, but if
>>> more bit flags are added, this may became a
>>> problem, as you are always treating it as a separate
>>> value, not a bit flag.
>>
>> Thanks for the confirmation.
>>
>> At the end of this mail is a test program that I used to experiment
>> with this stuff. Here's a sample run that demonstrates the scenario
>> described above:
>
> The kernel already has the sigaltstack test-case,
> so maybe you can add some checks to it from your
> test-case.

I must admit I'm still trying to grasp some details of what's
possible. What tests do you think could be usefully added?

Cheers,

Michael

[1] I mean, people are always aghast when I explain the existence of
libsigsegv and most people are surprised to learn that a file
permissions mask such as rw----r-- is actually used by some
applications to deny access to a group. I don't suppose either notion
was in the mind of the original UNIX kernel developers.

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-23 12:26       ` Michael Kerrisk (man-pages)
@ 2017-05-23 23:01         ` Stas Sergeev
  2017-05-24 11:09           ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-05-23 23:01 UTC (permalink / raw)
  To: mtk.manpages; +Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

23.05.2017 15:26, Michael Kerrisk (man-pages) пишет:
>>>> and posix seems to allow any
>>>> other value for enable, which can be (on linux) SS_ONSTACK,
>>>> not only 0.
>>> Yes, long ago someone got confused, as I've noted in a recently added
>>> BUGS section in the page:
>> But my understanding differs.
>> http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaltstack.html
>> ---
>> The /ss_flags/ member specifies the new stack state.
>> If it is set to SS_DISABLE, the stack is disabled and /ss_sp/
>> and /ss_size/ are ignored. Otherwise, the stack shall be enabled
>> ---
>>
>> As you can see, it doesn't say "SS_DISABLE or 0 are
>> only possible values". It does not even mention 0 at all
>> as being a possible or suggested value, it only uses it in
>> an example.
>> So what you call a confusion, looks valid to me, according
>> to the above spec.
> I think this is a misreading of the spec. The spec is saying that
>
>      (ss_flags & SS_DISABLE) != 0
>
> means disable the stack and
>
>      (ss_flags & SS_DISABLE) == 0
>
> means disable the stack.
You probably meant to say "enable" somewhere along
the lines.
Could you please point and cite the spec that says
exactly this?

> POSIX.1 make no statement about the use of SS_ONSTACK to enable the
> stack.
Unfortunately the spec mentions only "SS_DISABLE"
and "otherwise". So the one can assume "SS_DISABLE+1",
"SS_DISABLE-1" and "SS_DISABLE+100" to enable sas,
but never 0.
0 can be assumed _only_ if you know exactly that
flags is a bit-mask and SS_DISABLE is its (only possible)
bit. You claim above that "spec is saying" it to be a bit-mask.
Unfortunately I haven't seen such spec, and until that
I assume SS_DISABLE is a value, not a bit of bitmask.
And the value can itself be 0, so unless the spec is very
clear on this (and it is likely not), I assume it is much
safer to use SS_ONSTACK for the very simple fact: it is
guaranteed to not be equal to SS_DISABLE, while 0,
with my understanding of spec, is not guaranteed to
be different from SS_DISABLE.

>   And as far as I know, no other implementation attaches meaning
> to SS_ONSTACK when establishing a signal stack. Some systems' man
> pages are loosely worded in the manner of POSIX, but others are quite
> explicit, with Solaris 8 and Irix 6.5 containing text such as the
> following:
>
>       If    ss is not NULL,    it points to a structure specifying the
>    alternate
>       signal stack that will take effect    upon return from sigaltstack.  [...]
>      The ss_flags field specifies the new stack state and may be set
>       to    the following:
>
>       SS_DISABLE       The stack is    to be disabled and ss_sp and ss_size are
>             ignored.  If    SS_DISABLE is not set, the stack will be
>             enabled.
>
> The strong implication there is that no value other than SS_DISABLE is
I guess you take "SS_DISABLE is not set" as a witness that
it is a bitmask, but I wonder if that solaris-specific witness
is strong enough to claim that the linux implementation is
a confusion...

> meaningful in ss.ss_flags. No other man page that I could find (and I
> have quite a collection) suggested the (ss.ss_flags == SSONSTACK) is
> meaningful.
SS_ONSTACK is meaningful in a sense to always be != SS_DISABLE.

> So, using SS_ONSTACK on Linux is a no-op that decreases code
> portability. (And I am supposing that you use (ss.ss_flags ==
> SS_ONSTACK) only because you've been misled into thinking its
> legitimate from reading the kernel source.)
How about me supposing you use SS_DISABLE as a bitmask
only because you took that view from the opensolaris and
freebsd sources? :)
Well, this is definitely under-specced, so we are unlikely to
find any kind of "truth" here. But I am disappointed with the
fact that the linux implementation was called a "confusion"
based on a very small evidence from the solaris man page.
IMHO to put such claims into a man page, the one had to
open a defect report to posix, asking them to clarify first.
And even if they confirm this view, the linux implementation
should not be regarded as a confusion, but as a "consequence
of the ambiguous wording in posix".

>>>     [SIGA is delivered]
>>>
>>> * Handler for SIGA is called and handler is executed on alternate SS 1.
>>> ]]
>>>
>>> Summary: setting up another alternate signal stack seems to "work".
>> Only if you deliver SIGB while still inside SIGA handler,
>> which is a bit unusual. Certainly not worth calling this
>> "works" IMHO. The fact that this will be undone at SIGA
>> exit, is much more confusing to the user, so I'd say just
>> don't do that.
> I agree that it is an unusual scenario. But, user-space programmers
> outnumber kernel developers 10000 to 1, and over time they will find
> every possible way to creatively use an API if it "works for them".
Another danger is someone trying to set up the
same sas before exiting from the sighandler. If
they set up same sas and get nested handler, the
stack will be corrupted. This was not possible before,
because without SS_AUTODISARM you'd get EPERM
in such case.

>>> API history is littered with stories where users found out that
>>> something unforeseen "worked", and so they used it. The question
>>> is: what can go wrong if people do try using this "feature"?
>> It will disappear at the exit from SIGA.
>> To me this is "wrong enough" to not suggest doing so.
> See my comment above. It's weird because it will disappear at exit
> from SIGA, but not "wrong".
What do you mean?
There was no any notion of the "sigaltstack scope",
so with the existing semantic it is wrong, because
currently sigaltstack has no scope and can't change
at random moments. You can make it "not wrong"
by inventing a new semantic with some notion of
the "sigaltstack scope" though. Whether it worth the
troubles, is what we will see. :)

>> The kernel already has the sigaltstack test-case,
>> so maybe you can add some checks to it from your
>> test-case.
> I must admit I'm still trying to grasp some details of what's
> possible. What tests do you think could be usefully added?
If you are going to add the scoped/nested sigaltstacks,
then perhaps you should add the test that nesting works
correctly (you have that already in your test-case), and
maybe also the direct manipulations to uc_stack, as this
is the only _reliable_ way to set the new sas inside the
sighandler, that I can think of.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-23 23:01         ` Stas Sergeev
@ 2017-05-24 11:09           ` Michael Kerrisk (man-pages)
  2017-05-24 20:12             ` Stas Sergeev
  2017-05-25  9:17             ` Stas Sergeev
  0 siblings, 2 replies; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-05-24 11:09 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: mtk.manpages, linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello Stas,

On 05/24/2017 01:01 AM, Stas Sergeev wrote:
> 23.05.2017 15:26, Michael Kerrisk (man-pages) пишет:
>>>>> and posix seems to allow any
>>>>> other value for enable, which can be (on linux) SS_ONSTACK,
>>>>> not only 0.
>>>> Yes, long ago someone got confused, as I've noted in a recently added
>>>> BUGS section in the page:
>>> But my understanding differs.
>>> http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaltstack.html
>>> ---
>>> The /ss_flags/ member specifies the new stack state.
>>> If it is set to SS_DISABLE, the stack is disabled and /ss_sp/
>>> and /ss_size/ are ignored. Otherwise, the stack shall be enabled
>>> ---
>>>
>>> As you can see, it doesn't say "SS_DISABLE or 0 are
>>> only possible values". It does not even mention 0 at all
>>> as being a possible or suggested value, it only uses it in
>>> an example.

I missed this point earlier, but I think that detail is also relevant.

>>> So what you call a confusion, looks valid to me, according
>>> to the above spec.
>> I think this is a misreading of the spec. The spec is saying that
>>
>>      (ss_flags & SS_DISABLE) != 0
>>
>> means disable the stack and
>>
>>      (ss_flags & SS_DISABLE) == 0
>>
>> means disable the stack.
> You probably meant to say "enable" somewhere along
> the lines.

Yes.

> Could you please point and cite the spec that says
> exactly this?

I take your point: the text of the spec could be more precise. It
does not provide a complete support for my assertion. 

But, I do think the interpretation I suggest is the more natural one, 
for many reasons:

1. The field is named '*flags', which commonly means a bit mask.
2. The example in that you mention that is in the spec is part of 
   the spec. It illustrates the understanding of the developers
   of the spec about the interface they were specifying.
3. Various existing implementations treat the field as a bit mask
   for which there is only one valid bit (SS_DISABLE), doing
   tests of the form (ss.ss_flags & SS_DISABLE).
4. Some implementations (including *all* the ones that I looked at 
   the source code for, that is Illumos, FreeBSD, OpenBSD)
   explicitly error if ss.ss_flags has bits other than SS_DISABLE set.
5. The man pages on Solaris and Irix explicitly note that SS_DISABLE
   is the only value (other than no value, i.e., 0) that may be
   placed in ss.ss_flags. No man page that I can find suggests the 
   use of SS_ONSTACK in ss.ss_flags.
6. Before kernel 2.4 (Jan 2001), Linux also used to do 3 & 4!
7. Re points 3 and 4, POSIX/SUS normally specifies existing behavior.
   The SUS specification of sigaltstack() dates back at least to 
   1994 (SUSv1). This presumably means that the text came from 
   the original POSIX.1-1990. The SUSv1 spec includes the example
   code snippet.
8. The standard explicitly mentions that SS_ONSTACK may be returned
   in old_ss.ss_flags, but makes no mention of the use of SS_ONSTACK 
   in ss.ss_flags. That fact should, IMO, be taken as a strong hint
   that the standard developers did not believe that SS_ONSTACK was
   to be used with ss.ss_flags.

On top of the above (to repeat what I already said earlier):

* SS_ONSTACK in ss.ss_flags is a no-op on Linux.
* SS_ONSTACK in ss.ss_flags in flags explicitly errors on various
  implementations (see points 4 and 6 above).
   
>> POSIX.1 make no statement about the use of SS_ONSTACK to enable the
>> stack.
> Unfortunately the spec mentions only "SS_DISABLE"
> and "otherwise". So the one can assume "SS_DISABLE+1",
> "SS_DISABLE-1" and "SS_DISABLE+100" to enable sas,
> but never 0.

That's a possible reading of the standard, but not a natural one I 
would say, given the points above.

> 0 can be assumed _only_ if you know exactly that
> flags is a bit-mask and SS_DISABLE is its (only possible)
> bit. You claim above that "spec is saying" it to be a bit-mask.
> Unfortunately I haven't seen such spec, and until that
> I assume SS_DISABLE is a value, not a bit of bitmask.
> And the value can itself be 0, so unless the spec is very
> clear on this (and it is likely not), I assume it is much
> safer to use SS_ONSTACK for the very simple fact: it is
> guaranteed to not be equal to SS_DISABLE, while 0,

That's my point. It is not safe: it breaks portability.

> with my understanding of spec, is not guaranteed to
> be different from SS_DISABLE.
> 
>>   And as far as I know, no other implementation attaches meaning
>> to SS_ONSTACK when establishing a signal stack. Some systems' man
>> pages are loosely worded in the manner of POSIX, but others are quite
>> explicit, with Solaris 8 and Irix 6.5 containing text such as the
>> following:
>>
>>       If    ss is not NULL,    it points to a structure specifying the
>>    alternate
>>       signal stack that will take effect    upon return from sigaltstack.  [...]
>>      The ss_flags field specifies the new stack state and may be set
>>       to    the following:
>>
>>       SS_DISABLE       The stack is    to be disabled and ss_sp and ss_size are
>>             ignored.  If    SS_DISABLE is not set, the stack will be
>>             enabled.
>>
>> The strong implication there is that no value other than SS_DISABLE is
> I guess you take "SS_DISABLE is not set" as a witness that
> it is a bitmask, but I wonder if that solaris-specific witness
> is strong enough to claim that the linux implementation is
> a confusion...

It's not just Solaris specific. By now we have Solaris (Illumos), 
FreeBSD, OpenBSD, and Irix. How many more do you need ? :-)

>> meaningful in ss.ss_flags. No other man page that I could find (and I
>> have quite a collection) suggested the (ss.ss_flags == SSONSTACK) is
>> meaningful.
> SS_ONSTACK is meaningful in a sense to always be != SS_DISABLE.
> 
>> So, using SS_ONSTACK on Linux is a no-op that decreases code
>> portability. (And I am supposing that you use (ss.ss_flags ==
>> SS_ONSTACK) only because you've been misled into thinking its
>> legitimate from reading the kernel source.)
> How about me supposing you use SS_DISABLE as a bitmask
> only because you took that view from the opensolaris and
> freebsd sources? :)

Well, you could suppose that :-). But actually, it's from my reading
of the standards 15+ years ago. (I only read the opensolkaris and 
FreeBSD source code yesterday.)

> Well, this is definitely under-specced, so we are unlikely to
> find any kind of "truth" here. But I am disappointed with the
> fact that the linux implementation was called a "confusion"
> based on a very small evidence from the solaris man page.

Solaris (Illumos), FreeBSD, OpenBSD, Irix...

> IMHO to put such claims into a man page, the one had to
> open a defect report to posix, asking them to clarify first.
> And even if they confirm this view, the linux implementation
> should not be regarded as a confusion, but as a "consequence
> of the ambiguous wording in posix".

One could do this I suppose, but I read POSIX differently from
you and, more importantly, SS_ONSTACK breaks portability on 
numerous other systems and is a no-op on Linux. So, the Linux man 
page really should warn against its use in the strongest terms.

>>>>     [SIGA is delivered]
>>>>
>>>> * Handler for SIGA is called and handler is executed on alternate SS 1.
>>>> ]]
>>>>
>>>> Summary: setting up another alternate signal stack seems to "work".
>>> Only if you deliver SIGB while still inside SIGA handler,
>>> which is a bit unusual. Certainly not worth calling this
>>> "works" IMHO. The fact that this will be undone at SIGA
>>> exit, is much more confusing to the user, so I'd say just
>>> don't do that.
>> I agree that it is an unusual scenario. But, user-space programmers
>> outnumber kernel developers 10000 to 1, and over time they will find
>> every possible way to creatively use an API if it "works for them".
> Another danger is someone trying to set up the
> same sas before exiting from the sighandler. If
> they set up same sas and get nested handler, the
> stack will be corrupted. This was not possible before,
> because without SS_AUTODISARM you'd get EPERM
> in such case.
> 
>>>> API history is littered with stories where users found out that
>>>> something unforeseen "worked", and so they used it. The question
>>>> is: what can go wrong if people do try using this "feature"?
>>> It will disappear at the exit from SIGA.
>>> To me this is "wrong enough" to not suggest doing so.
>> See my comment above. It's weird because it will disappear at exit
>> from SIGA, but not "wrong".
> What do you mean?
> There was no any notion of the "sigaltstack scope",
> so with the existing semantic it is wrong, because
> currently sigaltstack has no scope and can't change

I'm not sure what you mean by "currently" here. I'm pointing
out that whereas before one could not change the signal stack 
while executing a handler that is using a signal stack, now it
seems to be possible. But, it's not random: the programmer must
explicitly make this happen (and be lucky in the timing of signals).

> at random moments. You can make it "not wrong"
> by inventing a new semantic with some notion of
> the "sigaltstack scope" though. Whether it worth the
> troubles, is what we will see. :)

I don't think I'm inventing a new semantic. I think you already 
did that :-). The question is what we should say about it in the 
man page. I don't think being silent on this detail is the way to
go. Perhaps noting a few details and warning the reader strongly
against relying on this "feature" in any way is appropriate?

>>> The kernel already has the sigaltstack test-case,
>>> so maybe you can add some checks to it from your
>>> test-case.
>> I must admit I'm still trying to grasp some details of what's
>> possible. What tests do you think could be usefully added?
> If you are going to add the scoped/nested sigaltstacks,
> then perhaps you should add the test that nesting works
> correctly (you have that already in your test-case), and
> maybe also the direct manipulations to uc_stack, as this
> is the only _reliable_ way to set the new sas inside the
> sighandler, that I can think of.

See above. I'm not sure that we want to specify things to this
level. But my point is that in the lack of any text in the man 
page on the topic, some user-space programmers will discover the
feature and perhaps try to use it. The question is what the man 
page should say to those programmers. Do you see what I mean?

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-24 11:09           ` Michael Kerrisk (man-pages)
@ 2017-05-24 20:12             ` Stas Sergeev
  2017-10-30 12:38               ` Michael Kerrisk (man-pages)
  2017-05-25  9:17             ` Stas Sergeev
  1 sibling, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-05-24 20:12 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello,

24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>> Could you please point and cite the spec that says
>> exactly this?
> I take your point: the text of the spec could be more precise. It
> does not provide a complete support for my assertion.
>
> But, I do think the interpretation I suggest is the more natural one,
> for many reasons:
Note: below I am not arguing to whether it is
good or bad to use SS_ONSTACK. This question
is closed as soon as you pointed to EINVAL in
other OSes (it doesn't make it bad immediately,
but at least the outcome of its usage is now
pretty clear for me).
What I still want to point out is the fact that the
implementation in linux was very unlikely caused
by a confusion. It was the decision made in agreement
with the most straight-forward reading of the posix
spec, just maybe without knowing about this EINVAL
problem. And it can't create a compatibility problem
by itself because no one have explicitly promoted its
use: 0 is still accepted.
Why it could create a compatibility problem is only
because people suddenly started to use it, and for
the very simple reason (judging by myself): I was
absolutely confused with this '0' in the example, and
after many attempts to find even a slightest hint in
the same doc why it is safe (why SS_DISABLE can't
be 0), I resorted to looking into the kernel and the
code of other projects. And SS_ONSTACK looked
like a perfectly valid solution, fully agreeing with
the text (i.e. SS_ONSTACK != SS_DISABLE).
So what really creates a compatibility problem here,
is only a misleading text (or a misleading implementation
of it in other OSes). And as such, stating that "someone
was confused" looks more like an unjustified insult to me. :)

> 1. The field is named '*flags', which commonly means a bit mask.
Indeed, but the value suggests otherwise.
The name for a flag could be "SS_DISABLED"
(with D at the end), while "SS_DISABLE" suggests
an action. And indeed, it doesn't change a property
of a performing action the way SS_AUTODISARM
does. Instead it changes the action itself: the sas
get cleared instead of being set, and all the other
arguments are ignored. Eg I would be very surprised
seeing the "MAP_UNMAP" flag to mmap() that turns
it into munmap(). This more resembles the "action"
argument of the sigprocmask() call.

> 2. The example in that you mention that is in the spec is part of
>     the spec. It illustrates the understanding of the developers
>     of the spec about the interface they were specifying.
> 3. Various existing implementations treat the field as a bit mask
>     for which there is only one valid bit (SS_DISABLE), doing
>     tests of the form (ss.ss_flags & SS_DISABLE).
> 4. Some implementations (including *all* the ones that I looked at
>     the source code for, that is Illumos, FreeBSD, OpenBSD)
>     explicitly error if ss.ss_flags has bits other than SS_DISABLE set.
Well, yes, those are the practical arguments that
can't be ignored... Of course the one can try to
submit the patch to these projects that nullifies
this argument. :)

> 6. Before kernel 2.4 (Jan 2001), Linux also used to do 3 & 4!
Is there a discussion about this change somewhere?

> 8. The standard explicitly mentions that SS_ONSTACK may be returned
>     in old_ss.ss_flags, but makes no mention of the use of SS_ONSTACK
>     in ss.ss_flags. That fact should, IMO, be taken as a strong hint
>     that the standard developers did not believe that SS_ONSTACK was
>     to be used with ss.ss_flags.
But this doesn't matter as they "seemingly" allow
any other value than SS_DISABLE, and this one is
the most reasonable value of all (unless you know
this is a bitmask, of course).

So to make it clear: I am not arguing to what is
better or more portable. I am just not satisfied
with the statement that whoever implemented
it that way (and whoever uses it, too, obviously),
was confused or read the standard badly. It is
not the case. Also I don't agree that this implementation
can create any (portability or any other) kind of
problem: it still accepts 0, and its author didn't
advice anyone to use SS_ONSTACK. So in my eyes
the implementation is perfectly valid, no ifs no
buts. :) Man page can warn people to not use
SS_ONSTACK, but it shouldn't blame the author
of the kernel code in question IMHO.

>>>>> API history is littered with stories where users found out that
>>>>> something unforeseen "worked", and so they used it. The question
>>>>> is: what can go wrong if people do try using this "feature"?
>>>> It will disappear at the exit from SIGA.
>>>> To me this is "wrong enough" to not suggest doing so.
>>> See my comment above. It's weird because it will disappear at exit
>>> from SIGA, but not "wrong".
>> What do you mean?
>> There was no any notion of the "sigaltstack scope",
>> so with the existing semantic it is wrong, because
>> currently sigaltstack has no scope and can't change
> I'm not sure what you mean by "currently" here. I'm pointing
> out that whereas before one could not change the signal stack
> while executing a handler that is using a signal stack, now it
> seems to be possible. But, it's not random: the programmer must
> explicitly make this happen (and be lucky in the timing of signals).
By "random points" I meant that sas swaps back
to the previous one on a sighandler return. This
sighandler return is just a random point for anyone
who assumes the global scope of the sas. And the
scope of sas was always global, so from that POV
it doesn't work reliably. If you invent some notion
of the scoped sigaltstacks, then you will turn that
into a working functionality with new semantic.
But I don't think you can call this "working" without
first inventing an adequate semantic for it.

>> at random moments. You can make it "not wrong"
>> by inventing a new semantic with some notion of
>> the "sigaltstack scope" though. Whether it worth the
>> troubles, is what we will see. :)
> I don't think I'm inventing a new semantic. I think you already
> did that :-). The question is what we should say about it in the
> man page. I don't think being silent on this detail is the way to
> go. Perhaps noting a few details and warning the reader strongly
> against relying on this "feature" in any way is appropriate?
This is entirely up to you. My point is just that it is
not a "few details", but really a new semantic with
a notion of a sas's scope. I.e. when the control goes
out of current scope (sighandler return), sas reverts
to the one of the parent scope. Since this was not
envisioned and is unlikely needed to anyone, I was
just suggesting to not do this, but if you want to spec
this all - why not. :)

>>>> The kernel already has the sigaltstack test-case,
>>>> so maybe you can add some checks to it from your
>>>> test-case.
>>> I must admit I'm still trying to grasp some details of what's
>>> possible. What tests do you think could be usefully added?
>> If you are going to add the scoped/nested sigaltstacks,
>> then perhaps you should add the test that nesting works
>> correctly (you have that already in your test-case), and
>> maybe also the direct manipulations to uc_stack, as this
>> is the only _reliable_ way to set the new sas inside the
>> sighandler, that I can think of.
> See above. I'm not sure that we want to specify things to this
> level. But my point is that in the lack of any text in the man
> page on the topic, some user-space programmers will discover the
> feature and perhaps try to use it. The question is what the man
> page should say to those programmers. Do you see what I mean?
Yes, but I don't see what the man page should say
to those programmers. :) Or if I do, the description
would became too lengthy and complex.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-24 11:09           ` Michael Kerrisk (man-pages)
  2017-05-24 20:12             ` Stas Sergeev
@ 2017-05-25  9:17             ` Stas Sergeev
  2017-10-30 10:04               ` Michael Kerrisk (man-pages)
  1 sibling, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-05-25  9:17 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
> One could do this I suppose, but I read POSIX differently from
> you and, more importantly, SS_ONSTACK breaks portability on
> numerous other systems and is a no-op on Linux. So, the Linux man
> page really should warn against its use in the strongest terms.
So how about instead of the strongest terms towards
the code's author, just explain that SS_ONSTACK is a
bit-value on some/many OSes, and as such, 0 is a
valid value to enable sas on them, plus all the other
values would give EINVAL?
No strongest terms will help w/o an explanation,
because people will keep looking for something that
suits as a missing SS_ENABLE.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-25  9:17             ` Stas Sergeev
@ 2017-10-30 10:04               ` Michael Kerrisk (man-pages)
  2017-10-30 10:21                 ` walter harms
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-10-30 10:04 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: mtk.manpages, linux-man, Andy Lutomirski, Oleg Nesterov, lkml

[So, things fell on the floor, a while back.]

On 05/25/2017 11:17 AM, Stas Sergeev wrote:
> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>> One could do this I suppose, but I read POSIX differently from
>> you and, more importantly, SS_ONSTACK breaks portability on
>> numerous other systems and is a no-op on Linux. So, the Linux man
>> page really should warn against its use in the strongest terms.
> So how about instead of the strongest terms towards
> the code's author, just explain that SS_ONSTACK is a
> bit-value on some/many OSes, and as such, 0 is a
> valid value to enable sas on them, plus all the other
> values would give EINVAL?
> No strongest terms will help w/o an explanation,
> because people will keep looking for something that
> suits as a missing SS_ENABLE.

Fair enough. I've removed the statement in the manual page
about "confusion". By now the page says:

    BUGS
       In the lead up to the release of the Linux 2.4  kernel,  a  change
       was   made   to   allow  sigaltstack()  to  accept  SS_ONSTACK  in
       ss.ss_flags, which results in behavior that is the  same  as  when
       ss_flags is 0 (i.e., the inclusion of SS_ONSTACK in ss.ss_flags is
       a no-op).  On other implementations,  and  according  to  POSIX.1,
       SS_ONSTACK appears only as a reported flag in old_ss.ss_flags.  On
       Linux, there is no need ever to specify this flag in  ss.ss_flags,
       and indeed doing so should be avoided on portability grounds: var‐
       ious other systems give an error if  SS_ONSTACK  is  specified  in
       ss.ss_flags.

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-10-30 10:04               ` Michael Kerrisk (man-pages)
@ 2017-10-30 10:21                 ` walter harms
  2017-10-30 10:50                   ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: walter harms @ 2017-10-30 10:21 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: Stas Sergeev, linux-man, Andy Lutomirski, Oleg Nesterov, lkml



Am 30.10.2017 11:04, schrieb Michael Kerrisk (man-pages):
> [So, things fell on the floor, a while back.]
> 
> On 05/25/2017 11:17 AM, Stas Sergeev wrote:
>> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>>> One could do this I suppose, but I read POSIX differently from
>>> you and, more importantly, SS_ONSTACK breaks portability on
>>> numerous other systems and is a no-op on Linux. So, the Linux man
>>> page really should warn against its use in the strongest terms.
>> So how about instead of the strongest terms towards
>> the code's author, just explain that SS_ONSTACK is a
>> bit-value on some/many OSes, and as such, 0 is a
>> valid value to enable sas on them, plus all the other
>> values would give EINVAL?
>> No strongest terms will help w/o an explanation,
>> because people will keep looking for something that
>> suits as a missing SS_ENABLE.
> 
> Fair enough. I've removed the statement in the manual page
> about "confusion". By now the page says:
> 
>     BUGS
>        In the lead up to the release of the Linux 2.4  kernel,  a  change
>        was   made   to   allow  sigaltstack()  to  accept  SS_ONSTACK  in
>        ss.ss_flags, which results in behavior that is the  same  as  when
>        ss_flags is 0 (i.e., the inclusion of SS_ONSTACK in ss.ss_flags is
>        a no-op).  On other implementations,  and  according  to  POSIX.1,

i am confused, i understand that:
           ss.ss_sp = malloc(SIGSTKSZ);

           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = 0;
           if (sigaltstack(&ss, NULL) == -1)

is equivalent to:
           ss.ss_sp = malloc(SIGSTKSZ);

           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = SS_ONSTACK ;
           if (sigaltstack(&ss, NULL) == -1)

but also to
           ss.ss_sp = malloc(SIGSTKSZ);

           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = SS_ONSTACK | SOMETHING_FLAG ;
           if (sigaltstack(&ss, NULL) == -1)

so the use of SS_ONSTACK would result in ss.ss_flags = 0 no matter what.
OR
SS_ONSTACK is a no-op in Linux

re,
 wh

>        SS_ONSTACK appears only as a reported flag in old_ss.ss_flags.  On
>        Linux, there is no need ever to specify this flag in  ss.ss_flags,
>        and indeed doing so should be avoided on portability grounds: var‐
>        ious other systems give an error if  SS_ONSTACK  is  specified  in
>        ss.ss_flags.
> 
> Cheers,
> 
> Michael
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-10-30 10:21                 ` walter harms
@ 2017-10-30 10:50                   ` Michael Kerrisk (man-pages)
  2017-10-30 10:58                     ` Stas Sergeev
  2017-10-30 12:54                     ` walter harms
  0 siblings, 2 replies; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-10-30 10:50 UTC (permalink / raw)
  To: wharms
  Cc: mtk.manpages, Stas Sergeev, linux-man, Andy Lutomirski,
	Oleg Nesterov, lkml

Hi Walter,

On 10/30/2017 11:21 AM, walter harms wrote:
> 
> 
> Am 30.10.2017 11:04, schrieb Michael Kerrisk (man-pages):
>> [So, things fell on the floor, a while back.]
>>
>> On 05/25/2017 11:17 AM, Stas Sergeev wrote:
>>> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>>>> One could do this I suppose, but I read POSIX differently from
>>>> you and, more importantly, SS_ONSTACK breaks portability on
>>>> numerous other systems and is a no-op on Linux. So, the Linux man
>>>> page really should warn against its use in the strongest terms.
>>> So how about instead of the strongest terms towards
>>> the code's author, just explain that SS_ONSTACK is a
>>> bit-value on some/many OSes, and as such, 0 is a
>>> valid value to enable sas on them, plus all the other
>>> values would give EINVAL?
>>> No strongest terms will help w/o an explanation,
>>> because people will keep looking for something that
>>> suits as a missing SS_ENABLE.
>>
>> Fair enough. I've removed the statement in the manual page
>> about "confusion". By now the page says:
>>
>>     BUGS
>>        In the lead up to the release of the Linux 2.4  kernel,  a  change
>>        was   made   to   allow  sigaltstack()  to  accept  SS_ONSTACK  in
>>        ss.ss_flags, which results in behavior that is the  same  as  when
>>        ss_flags is 0 (i.e., the inclusion of SS_ONSTACK in ss.ss_flags is
>>        a no-op).  On other implementations,  and  according  to  POSIX.1,
> 
> i am confused, i understand that:
>            ss.ss_sp = malloc(SIGSTKSZ);
> 
>            ss.ss_size = SIGSTKSZ;
>            ss.ss_flags = 0;
>            if (sigaltstack(&ss, NULL) == -1)
> 
> is equivalent to:
>            ss.ss_sp = malloc(SIGSTKSZ);
> 
>            ss.ss_size = SIGSTKSZ;
>            ss.ss_flags = SS_ONSTACK ;
>            if (sigaltstack(&ss, NULL) == -1)
> 
> but also to
>            ss.ss_sp = malloc(SIGSTKSZ);
> 
>            ss.ss_size = SIGSTKSZ;
>            ss.ss_flags = SS_ONSTACK | SOMETHING_FLAG ;
>            if (sigaltstack(&ss, NULL) == -1)
> 
> so the use of SS_ONSTACK would result in ss.ss_flags = 0 no matter what.
> OR
> SS_ONSTACK is a no-op in Linux

I see what you mean. The point is back then that SS_ONSTACK was
the only flag that could (on Linux) be specified in ss.ss_flags,
so that "SS_ONSTACK | SOMETHING_FLAG" was a nonexistent case.
These days, it's possible to specify the new SS_AUTODISARM
flag in ss.ss_flags, which I think is why you are doubtful
about the new page text. How about this, as a tightened-up 
version:

    BUGS
       In Linux 2.2 and earlier, the only flag that could be specified in
       ss.sa_flags  was SS_DISABLE.  In the lead up to the release of the
       Linux 2.4 kernel, a change was  made  to  allow  sigaltstack()  to
       allow   ss.ss_flags==SS_ONSTACK   with   the   same   meaning   as
       ss.ss_flags==0 (i.e., the inclusion of SS_ONSTACK  in  ss.ss_flags
       is  a no-op).  On other implementations, and according to POSIX.1,
       SS_ONSTACK appears only as a reported flag in old_ss.ss_flags.  On
       Linux, there is no need ever to specify SS_ONSTACK in ss.ss_flags,
       and indeed doing so should be avoided on portability grounds: var‐
       ious  other  systems  give  an error if SS_ONSTACK is specified in
       ss.ss_flags.

?

Thanks,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-10-30 10:50                   ` Michael Kerrisk (man-pages)
@ 2017-10-30 10:58                     ` Stas Sergeev
  2017-10-30 12:54                     ` walter harms
  1 sibling, 0 replies; 18+ messages in thread
From: Stas Sergeev @ 2017-10-30 10:58 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages), wharms
  Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

30.10.2017 13:50, Michael Kerrisk (man-pages) пишет:
> I see what you mean. The point is back then that SS_ONSTACK was
> the only flag that could (on Linux) be specified in ss.ss_flags,
> so that "SS_ONSTACK | SOMETHING_FLAG" was a nonexistent case.
> These days, it's possible to specify the new SS_AUTODISARM
> flag in ss.ss_flags, which I think is why you are doubtful
> about the new page text. How about this, as a tightened-up
> version:
>
>      BUGS
>         In Linux 2.2 and earlier, the only flag that could be specified in
>         ss.sa_flags  was SS_DISABLE.  In the lead up to the release of the
>         Linux 2.4 kernel, a change was  made  to  allow  sigaltstack()  to
>         allow   ss.ss_flags==SS_ONSTACK   with   the   same   meaning   as
>         ss.ss_flags==0 (i.e., the inclusion of SS_ONSTACK  in  ss.ss_flags
>         is  a no-op).  On other implementations, and according to POSIX.1,
>         SS_ONSTACK appears only as a reported flag in old_ss.ss_flags.  On
>         Linux, there is no need ever to specify SS_ONSTACK in ss.ss_flags,
>         and indeed doing so should be avoided on portability grounds: var‐
>         ious  other  systems  give  an error if SS_ONSTACK is specified in
>         ss.ss_flags.
>
And after all these amendments it seems to
no longer belong to BUGS section but to NOTES.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-05-24 20:12             ` Stas Sergeev
@ 2017-10-30 12:38               ` Michael Kerrisk (man-pages)
  2017-11-06 22:26                 ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-10-30 12:38 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: mtk.manpages, linux-man, Andy Lutomirski, Oleg Nesterov, lkml

On 05/24/2017 10:12 PM, Stas Sergeev wrote:
> Hello,
> 
> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>>> Could you please point and cite the spec that says
>>> exactly this?
>> I take your point: the text of the spec could be more precise. It
>> does not provide a complete support for my assertion.
>>
>> But, I do think the interpretation I suggest is the more natural one,
>> for many reasons:
> Note: below I am not arguing to whether it is
> good or bad to use SS_ONSTACK. This question
> is closed as soon as you pointed to EINVAL in
> other OSes (it doesn't make it bad immediately,
> but at least the outcome of its usage is now
> pretty clear for me).
> What I still want to point out is the fact that the
> implementation in linux was very unlikely caused
> by a confusion. It was the decision made in agreement
> with the most straight-forward reading of the posix
> spec, just maybe without knowing about this EINVAL
> problem. And it can't create a compatibility problem
> by itself because no one have explicitly promoted its
> use: 0 is still accepted.
> Why it could create a compatibility problem is only
> because people suddenly started to use it, and for
> the very simple reason (judging by myself): I was
> absolutely confused with this '0' in the example, and
> after many attempts to find even a slightest hint in
> the same doc why it is safe (why SS_DISABLE can't
> be 0), I resorted to looking into the kernel and the
> code of other projects. And SS_ONSTACK looked
> like a perfectly valid solution, fully agreeing with
> the text (i.e. SS_ONSTACK != SS_DISABLE).
> So what really creates a compatibility problem here,
> is only a misleading text (or a misleading implementation
> of it in other OSes). And as such, stating that "someone
> was confused" looks more like an unjustified insult to me. :)

See previous mail :-).

Just by the bye, the correct (according to my definition)
way of doing things (ss.ss_flags == 0 to establish an
alternate signal stack) has been documented in the manual
page since 2001. (That page documented the Linux 2.2
behavior.)

>> 1. The field is named '*flags', which commonly means a bit mask.
> Indeed, but the value suggests otherwise.
> The name for a flag could be "SS_DISABLED"
> (with D at the end), while "SS_DISABLE" suggests
> an action. And indeed, it doesn't change a property
> of a performing action the way SS_AUTODISARM
> does. Instead it changes the action itself: the sas
> get cleared instead of being set, and all the other
> arguments are ignored. Eg I would be very surprised
> seeing the "MAP_UNMAP" flag to mmap() that turns
> it into munmap(). This more resembles the "action"
> argument of the sigprocmask() call.
> 
>> 2. The example in that you mention that is in the spec is part of
>>     the spec. It illustrates the understanding of the developers
>>     of the spec about the interface they were specifying.
>> 3. Various existing implementations treat the field as a bit mask
>>     for which there is only one valid bit (SS_DISABLE), doing
>>     tests of the form (ss.ss_flags & SS_DISABLE).
>> 4. Some implementations (including *all* the ones that I looked at
>>     the source code for, that is Illumos, FreeBSD, OpenBSD)
>>     explicitly error if ss.ss_flags has bits other than SS_DISABLE set.
> Well, yes, those are the practical arguments that
> can't be ignored... Of course the one can try to
> submit the patch to these projects that nullifies
> this argument. :)
> 
>> 6. Before kernel 2.4 (Jan 2001), Linux also used to do 3 & 4!
> Is there a discussion about this change somewhere?
> 
>> 8. The standard explicitly mentions that SS_ONSTACK may be returned
>>     in old_ss.ss_flags, but makes no mention of the use of SS_ONSTACK
>>     in ss.ss_flags. That fact should, IMO, be taken as a strong hint
>>     that the standard developers did not believe that SS_ONSTACK was
>>     to be used with ss.ss_flags.
> But this doesn't matter as they "seemingly" allow
> any other value than SS_DISABLE, and this one is
> the most reasonable value of all (unless you know
> this is a bitmask, of course).
> 
> So to make it clear: I am not arguing to what is
> better or more portable. I am just not satisfied
> with the statement that whoever implemented
> it that way (and whoever uses it, too, obviously),
> was confused or read the standard badly. It is
> not the case. Also I don't agree that this implementation
> can create any (portability or any other) kind of
> problem: it still accepts 0, and its author didn't
> advice anyone to use SS_ONSTACK. So in my eyes
> the implementation is perfectly valid, no ifs no
> buts. :) Man page can warn people to not use
> SS_ONSTACK, but it shouldn't blame the author
> of the kernel code in question IMHO.
> 
>>>>>> API history is littered with stories where users found out that
>>>>>> something unforeseen "worked", and so they used it. The question
>>>>>> is: what can go wrong if people do try using this "feature"?
>>>>> It will disappear at the exit from SIGA.
>>>>> To me this is "wrong enough" to not suggest doing so.
>>>> See my comment above. It's weird because it will disappear at exit
>>>> from SIGA, but not "wrong".
>>> What do you mean?
>>> There was no any notion of the "sigaltstack scope",
>>> so with the existing semantic it is wrong, because
>>> currently sigaltstack has no scope and can't change
>> I'm not sure what you mean by "currently" here. I'm pointing
>> out that whereas before one could not change the signal stack
>> while executing a handler that is using a signal stack, now it
>> seems to be possible. But, it's not random: the programmer must
>> explicitly make this happen (and be lucky in the timing of signals).
> By "random points" I meant that sas swaps back
> to the previous one on a sighandler return. This
> sighandler return is just a random point for anyone
> who assumes the global scope of the sas. And the
> scope of sas was always global, so from that POV
> it doesn't work reliably. If you invent some notion
> of the scoped sigaltstacks, then you will turn that
> into a working functionality with new semantic.
> But I don't think you can call this "working" without
> first inventing an adequate semantic for it.
> 
>>> at random moments. You can make it "not wrong"
>>> by inventing a new semantic with some notion of
>>> the "sigaltstack scope" though. Whether it worth the
>>> troubles, is what we will see. :)
>> I don't think I'm inventing a new semantic. I think you already
>> did that :-). The question is what we should say about it in the
>> man page. I don't think being silent on this detail is the way to
>> go. Perhaps noting a few details and warning the reader strongly
>> against relying on this "feature" in any way is appropriate?
> This is entirely up to you. My point is just that it is
> not a "few details", but really a new semantic with
> a notion of a sas's scope. I.e. when the control goes
> out of current scope (sighandler return), sas reverts
> to the one of the parent scope. Since this was not
> envisioned and is unlikely needed to anyone, I was
> just suggesting to not do this, but if you want to spec
> this all - why not. :)
> 
>>>>> The kernel already has the sigaltstack test-case,
>>>>> so maybe you can add some checks to it from your
>>>>> test-case.
>>>> I must admit I'm still trying to grasp some details of what's
>>>> possible. What tests do you think could be usefully added?
>>> If you are going to add the scoped/nested sigaltstacks,
>>> then perhaps you should add the test that nesting works
>>> correctly (you have that already in your test-case), and
>>> maybe also the direct manipulations to uc_stack, as this
>>> is the only _reliable_ way to set the new sas inside the
>>> sighandler, that I can think of.
>> See above. I'm not sure that we want to specify things to this
>> level. But my point is that in the lack of any text in the man
>> page on the topic, some user-space programmers will discover the
>> feature and perhaps try to use it. The question is what the man
>> page should say to those programmers. Do you see what I mean?
> Yes, but I don't see what the man page should say
> to those programmers. :) Or if I do, the description
> would became too lengthy and complex.

So, the man page text currently says:

       If old_ss is not NULL, then it is used to return information about
       the  alternate  signal stack which was in effect prior to the call
       to sigaltstack().   The  old_ss.ss_sp  and  old_ss.ss_size  fields
       return   the  starting  address  and  size  of  that  stack.   The
       old_ss.ss_flags may return either of the following values:

       SS_ONSTACK
              The process is currently executing on the alternate  signal
              stack.   (Note that it is not possible to change the alter‐
              nate signal stack if the process is currently executing  on
              it.)

       SS_DISABLE
              The alternate signal stack is currently disabled.

              Alternatively,  this  value  is  returned if the process is
              currently executing on an alternate signal stack  that  was
              established using the SS_AUTODISARM flag.  In this case, it
              is safe to switch away from the signal handler  with  swap‐
              context(3).   It  is  also  possible  to set up a different
              alternative signal stack using a further  call  to  sigalt‐
              stack().

So, given the discussion so far, I think that last sentence needs to 
be changed. A simple change would be to just remove the sentence.
However, as I've tried to bring out, I think that *not* documenting
something is generally not a winning strategy. Eventually, people
figure out what's possible, and someone may try using the feature.
So, as well as removing that sentence, how about some text something 
like the following in NOTES:

    When old_ss.ss_flags returns SS_DISABLE, meaning the
    process is currently executing a signal handler ("X")
    on an alternate signal stack that was established
    using the SS_AUTODISARM flag, then it is
    possible inside that handler to set up a new
    alternative signal stack using a further call to
    sigaltstack(). However, this is not recommended. Taking
    advantage of this possibility is inherently racy, since
    the new alternate signal stack settings will be removed
    when signal handler "X" returns.

?

Thanks,

Michael





-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-10-30 10:50                   ` Michael Kerrisk (man-pages)
  2017-10-30 10:58                     ` Stas Sergeev
@ 2017-10-30 12:54                     ` walter harms
  1 sibling, 0 replies; 18+ messages in thread
From: walter harms @ 2017-10-30 12:54 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: Stas Sergeev, linux-man, Andy Lutomirski, Oleg Nesterov, lkml



Am 30.10.2017 11:50, schrieb Michael Kerrisk (man-pages):
> Hi Walter,
> 
> On 10/30/2017 11:21 AM, walter harms wrote:
>>
>>
>> Am 30.10.2017 11:04, schrieb Michael Kerrisk (man-pages):
>>> [So, things fell on the floor, a while back.]
>>>
>>> On 05/25/2017 11:17 AM, Stas Sergeev wrote:
>>>> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>>>>> One could do this I suppose, but I read POSIX differently from
>>>>> you and, more importantly, SS_ONSTACK breaks portability on
>>>>> numerous other systems and is a no-op on Linux. So, the Linux man
>>>>> page really should warn against its use in the strongest terms.
>>>> So how about instead of the strongest terms towards
>>>> the code's author, just explain that SS_ONSTACK is a
>>>> bit-value on some/many OSes, and as such, 0 is a
>>>> valid value to enable sas on them, plus all the other
>>>> values would give EINVAL?
>>>> No strongest terms will help w/o an explanation,
>>>> because people will keep looking for something that
>>>> suits as a missing SS_ENABLE.
>>>
>>> Fair enough. I've removed the statement in the manual page
>>> about "confusion". By now the page says:
>>>
>>>     BUGS
>>>        In the lead up to the release of the Linux 2.4  kernel,  a  change
>>>        was   made   to   allow  sigaltstack()  to  accept  SS_ONSTACK  in
>>>        ss.ss_flags, which results in behavior that is the  same  as  when
>>>        ss_flags is 0 (i.e., the inclusion of SS_ONSTACK in ss.ss_flags is
>>>        a no-op).  On other implementations,  and  according  to  POSIX.1,
>>
>> i am confused, i understand that:
>>            ss.ss_sp = malloc(SIGSTKSZ);
>>
>>            ss.ss_size = SIGSTKSZ;
>>            ss.ss_flags = 0;
>>            if (sigaltstack(&ss, NULL) == -1)
>>
>> is equivalent to:
>>            ss.ss_sp = malloc(SIGSTKSZ);
>>
>>            ss.ss_size = SIGSTKSZ;
>>            ss.ss_flags = SS_ONSTACK ;
>>            if (sigaltstack(&ss, NULL) == -1)
>>
>> but also to
>>            ss.ss_sp = malloc(SIGSTKSZ);
>>
>>            ss.ss_size = SIGSTKSZ;
>>            ss.ss_flags = SS_ONSTACK | SOMETHING_FLAG ;
>>            if (sigaltstack(&ss, NULL) == -1)
>>
>> so the use of SS_ONSTACK would result in ss.ss_flags = 0 no matter what.
>> OR
>> SS_ONSTACK is a no-op in Linux
> 
> I see what you mean. The point is back then that SS_ONSTACK was
> the only flag that could (on Linux) be specified in ss.ss_flags,
> so that "SS_ONSTACK | SOMETHING_FLAG" was a nonexistent case.
> These days, it's possible to specify the new SS_AUTODISARM
> flag in ss.ss_flags, which I think is why you are doubtful
> about the new page text. How about this, as a tightened-up 
> version:
> 
>     BUGS
>        In Linux 2.2 and earlier, the only flag that could be specified in
>        ss.sa_flags  was SS_DISABLE.  In the lead up to the release of the
>        Linux 2.4 kernel, a change was  made  to  allow  sigaltstack()  to
>        allow   ss.ss_flags==SS_ONSTACK   with   the   same   meaning   as
>        ss.ss_flags==0 (i.e., the inclusion of SS_ONSTACK  in  ss.ss_flags
>        is  a no-op).  On other implementations, and according to POSIX.1,
>        SS_ONSTACK appears only as a reported flag in old_ss.ss_flags.  On
>        Linux, there is no need ever to specify SS_ONSTACK in ss.ss_flags,
>        and indeed doing so should be avoided on portability grounds: var‐
>        ious  other  systems  give  an error if SS_ONSTACK is specified in
>        ss.ss_flags.
> 
> ?

what about the other way around (general to special) ....

 the inclusion of SS_ONSTACK in ss.ss_flags is a no-op (setting ss.ss_flags=SS_ONSTACK
 will result in ss.ss_flags=0).

The details about older release will be helpful for upgrading pruposes.
So we can say:

Since Linux 2.4 the inclusion ....

does this help ?

re,
 wh


> 
> Thanks,
> 
> Michael
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-10-30 12:38               ` Michael Kerrisk (man-pages)
@ 2017-11-06 22:26                 ` Michael Kerrisk (man-pages)
  2017-11-06 22:28                   ` Stas Sergeev
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-11-06 22:26 UTC (permalink / raw)
  To: Stas Sergeev
  Cc: mtk.manpages, linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello Stas,

Ping on the below?

Cheers,

Michael

On 10/30/2017 01:38 PM, Michael Kerrisk (man-pages) wrote:
> On 05/24/2017 10:12 PM, Stas Sergeev wrote:
>> Hello,
>>
>> 24.05.2017 14:09, Michael Kerrisk (man-pages) пишет:
>>>> Could you please point and cite the spec that says
>>>> exactly this?
>>> I take your point: the text of the spec could be more precise. It
>>> does not provide a complete support for my assertion.
>>>
>>> But, I do think the interpretation I suggest is the more natural one,
>>> for many reasons:
>> Note: below I am not arguing to whether it is
>> good or bad to use SS_ONSTACK. This question
>> is closed as soon as you pointed to EINVAL in
>> other OSes (it doesn't make it bad immediately,
>> but at least the outcome of its usage is now
>> pretty clear for me).
>> What I still want to point out is the fact that the
>> implementation in linux was very unlikely caused
>> by a confusion. It was the decision made in agreement
>> with the most straight-forward reading of the posix
>> spec, just maybe without knowing about this EINVAL
>> problem. And it can't create a compatibility problem
>> by itself because no one have explicitly promoted its
>> use: 0 is still accepted.
>> Why it could create a compatibility problem is only
>> because people suddenly started to use it, and for
>> the very simple reason (judging by myself): I was
>> absolutely confused with this '0' in the example, and
>> after many attempts to find even a slightest hint in
>> the same doc why it is safe (why SS_DISABLE can't
>> be 0), I resorted to looking into the kernel and the
>> code of other projects. And SS_ONSTACK looked
>> like a perfectly valid solution, fully agreeing with
>> the text (i.e. SS_ONSTACK != SS_DISABLE).
>> So what really creates a compatibility problem here,
>> is only a misleading text (or a misleading implementation
>> of it in other OSes). And as such, stating that "someone
>> was confused" looks more like an unjustified insult to me. :)
> 
> See previous mail :-).
> 
> Just by the bye, the correct (according to my definition)
> way of doing things (ss.ss_flags == 0 to establish an
> alternate signal stack) has been documented in the manual
> page since 2001. (That page documented the Linux 2.2
> behavior.)
> 
>>> 1. The field is named '*flags', which commonly means a bit mask.
>> Indeed, but the value suggests otherwise.
>> The name for a flag could be "SS_DISABLED"
>> (with D at the end), while "SS_DISABLE" suggests
>> an action. And indeed, it doesn't change a property
>> of a performing action the way SS_AUTODISARM
>> does. Instead it changes the action itself: the sas
>> get cleared instead of being set, and all the other
>> arguments are ignored. Eg I would be very surprised
>> seeing the "MAP_UNMAP" flag to mmap() that turns
>> it into munmap(). This more resembles the "action"
>> argument of the sigprocmask() call.
>>
>>> 2. The example in that you mention that is in the spec is part of
>>>     the spec. It illustrates the understanding of the developers
>>>     of the spec about the interface they were specifying.
>>> 3. Various existing implementations treat the field as a bit mask
>>>     for which there is only one valid bit (SS_DISABLE), doing
>>>     tests of the form (ss.ss_flags & SS_DISABLE).
>>> 4. Some implementations (including *all* the ones that I looked at
>>>     the source code for, that is Illumos, FreeBSD, OpenBSD)
>>>     explicitly error if ss.ss_flags has bits other than SS_DISABLE set.
>> Well, yes, those are the practical arguments that
>> can't be ignored... Of course the one can try to
>> submit the patch to these projects that nullifies
>> this argument. :)
>>
>>> 6. Before kernel 2.4 (Jan 2001), Linux also used to do 3 & 4!
>> Is there a discussion about this change somewhere?
>>
>>> 8. The standard explicitly mentions that SS_ONSTACK may be returned
>>>     in old_ss.ss_flags, but makes no mention of the use of SS_ONSTACK
>>>     in ss.ss_flags. That fact should, IMO, be taken as a strong hint
>>>     that the standard developers did not believe that SS_ONSTACK was
>>>     to be used with ss.ss_flags.
>> But this doesn't matter as they "seemingly" allow
>> any other value than SS_DISABLE, and this one is
>> the most reasonable value of all (unless you know
>> this is a bitmask, of course).
>>
>> So to make it clear: I am not arguing to what is
>> better or more portable. I am just not satisfied
>> with the statement that whoever implemented
>> it that way (and whoever uses it, too, obviously),
>> was confused or read the standard badly. It is
>> not the case. Also I don't agree that this implementation
>> can create any (portability or any other) kind of
>> problem: it still accepts 0, and its author didn't
>> advice anyone to use SS_ONSTACK. So in my eyes
>> the implementation is perfectly valid, no ifs no
>> buts. :) Man page can warn people to not use
>> SS_ONSTACK, but it shouldn't blame the author
>> of the kernel code in question IMHO.
>>
>>>>>>> API history is littered with stories where users found out that
>>>>>>> something unforeseen "worked", and so they used it. The question
>>>>>>> is: what can go wrong if people do try using this "feature"?
>>>>>> It will disappear at the exit from SIGA.
>>>>>> To me this is "wrong enough" to not suggest doing so.
>>>>> See my comment above. It's weird because it will disappear at exit
>>>>> from SIGA, but not "wrong".
>>>> What do you mean?
>>>> There was no any notion of the "sigaltstack scope",
>>>> so with the existing semantic it is wrong, because
>>>> currently sigaltstack has no scope and can't change
>>> I'm not sure what you mean by "currently" here. I'm pointing
>>> out that whereas before one could not change the signal stack
>>> while executing a handler that is using a signal stack, now it
>>> seems to be possible. But, it's not random: the programmer must
>>> explicitly make this happen (and be lucky in the timing of signals).
>> By "random points" I meant that sas swaps back
>> to the previous one on a sighandler return. This
>> sighandler return is just a random point for anyone
>> who assumes the global scope of the sas. And the
>> scope of sas was always global, so from that POV
>> it doesn't work reliably. If you invent some notion
>> of the scoped sigaltstacks, then you will turn that
>> into a working functionality with new semantic.
>> But I don't think you can call this "working" without
>> first inventing an adequate semantic for it.
>>
>>>> at random moments. You can make it "not wrong"
>>>> by inventing a new semantic with some notion of
>>>> the "sigaltstack scope" though. Whether it worth the
>>>> troubles, is what we will see. :)
>>> I don't think I'm inventing a new semantic. I think you already
>>> did that :-). The question is what we should say about it in the
>>> man page. I don't think being silent on this detail is the way to
>>> go. Perhaps noting a few details and warning the reader strongly
>>> against relying on this "feature" in any way is appropriate?
>> This is entirely up to you. My point is just that it is
>> not a "few details", but really a new semantic with
>> a notion of a sas's scope. I.e. when the control goes
>> out of current scope (sighandler return), sas reverts
>> to the one of the parent scope. Since this was not
>> envisioned and is unlikely needed to anyone, I was
>> just suggesting to not do this, but if you want to spec
>> this all - why not. :)
>>
>>>>>> The kernel already has the sigaltstack test-case,
>>>>>> so maybe you can add some checks to it from your
>>>>>> test-case.
>>>>> I must admit I'm still trying to grasp some details of what's
>>>>> possible. What tests do you think could be usefully added?
>>>> If you are going to add the scoped/nested sigaltstacks,
>>>> then perhaps you should add the test that nesting works
>>>> correctly (you have that already in your test-case), and
>>>> maybe also the direct manipulations to uc_stack, as this
>>>> is the only _reliable_ way to set the new sas inside the
>>>> sighandler, that I can think of.
>>> See above. I'm not sure that we want to specify things to this
>>> level. But my point is that in the lack of any text in the man
>>> page on the topic, some user-space programmers will discover the
>>> feature and perhaps try to use it. The question is what the man
>>> page should say to those programmers. Do you see what I mean?
>> Yes, but I don't see what the man page should say
>> to those programmers. :) Or if I do, the description
>> would became too lengthy and complex.
> 
> So, the man page text currently says:
> 
>        If old_ss is not NULL, then it is used to return information about
>        the  alternate  signal stack which was in effect prior to the call
>        to sigaltstack().   The  old_ss.ss_sp  and  old_ss.ss_size  fields
>        return   the  starting  address  and  size  of  that  stack.   The
>        old_ss.ss_flags may return either of the following values:
> 
>        SS_ONSTACK
>               The process is currently executing on the alternate  signal
>               stack.   (Note that it is not possible to change the alter‐
>               nate signal stack if the process is currently executing  on
>               it.)
> 
>        SS_DISABLE
>               The alternate signal stack is currently disabled.
> 
>               Alternatively,  this  value  is  returned if the process is
>               currently executing on an alternate signal stack  that  was
>               established using the SS_AUTODISARM flag.  In this case, it
>               is safe to switch away from the signal handler  with  swap‐
>               context(3).   It  is  also  possible  to set up a different
>               alternative signal stack using a further  call  to  sigalt‐
>               stack().
> 
> So, given the discussion so far, I think that last sentence needs to 
> be changed. A simple change would be to just remove the sentence.
> However, as I've tried to bring out, I think that *not* documenting
> something is generally not a winning strategy. Eventually, people
> figure out what's possible, and someone may try using the feature.
> So, as well as removing that sentence, how about some text something 
> like the following in NOTES:
> 
>     When old_ss.ss_flags returns SS_DISABLE, meaning the
>     process is currently executing a signal handler ("X")
>     on an alternate signal stack that was established
>     using the SS_AUTODISARM flag, then it is
>     possible inside that handler to set up a new
>     alternative signal stack using a further call to
>     sigaltstack(). However, this is not recommended. Taking
>     advantage of this possibility is inherently racy, since
>     the new alternate signal stack settings will be removed
>     when signal handler "X" returns.
> 
> ?
> 
> Thanks,
> 
> Michael
> 
> 
> 
> 
> 


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-11-06 22:26                 ` Michael Kerrisk (man-pages)
@ 2017-11-06 22:28                   ` Stas Sergeev
  2017-11-08  7:41                     ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 18+ messages in thread
From: Stas Sergeev @ 2017-11-06 22:28 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

07.11.2017 01:26, Michael Kerrisk (man-pages) пишет:
> Hello Stas,
>
> Ping on the below?
Hi, the change with the "not recommended" warning
looks good to me.
Acked-by: Stas Sergeev <stsp@list.ru>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Documenting sigaltstack SS_AUTODISRM
  2017-11-06 22:28                   ` Stas Sergeev
@ 2017-11-08  7:41                     ` Michael Kerrisk (man-pages)
  0 siblings, 0 replies; 18+ messages in thread
From: Michael Kerrisk (man-pages) @ 2017-11-08  7:41 UTC (permalink / raw)
  To: Stas Sergeev; +Cc: linux-man, Andy Lutomirski, Oleg Nesterov, lkml

Hello Stas,

On 6 November 2017 at 23:28, Stas Sergeev <stsp@list.ru> wrote:
> 07.11.2017 01:26, Michael Kerrisk (man-pages) пишет:
>>
>> Hello Stas,
>>
>> Ping on the below?
>
> Hi, the change with the "not recommended" warning
> looks good to me.
> Acked-by: Stas Sergeev <stsp@list.ru>

Thanks. I've pushed these changes into the master branch on Git.

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-11-08  7:42 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-22 20:38 Documenting sigaltstack SS_AUTODISRM Michael Kerrisk (man-pages)
2017-05-22 23:36 ` Stas Sergeev
2017-05-23 10:35   ` Michael Kerrisk (man-pages)
2017-05-23 11:03     ` Stas Sergeev
2017-05-23 12:26       ` Michael Kerrisk (man-pages)
2017-05-23 23:01         ` Stas Sergeev
2017-05-24 11:09           ` Michael Kerrisk (man-pages)
2017-05-24 20:12             ` Stas Sergeev
2017-10-30 12:38               ` Michael Kerrisk (man-pages)
2017-11-06 22:26                 ` Michael Kerrisk (man-pages)
2017-11-06 22:28                   ` Stas Sergeev
2017-11-08  7:41                     ` Michael Kerrisk (man-pages)
2017-05-25  9:17             ` Stas Sergeev
2017-10-30 10:04               ` Michael Kerrisk (man-pages)
2017-10-30 10:21                 ` walter harms
2017-10-30 10:50                   ` Michael Kerrisk (man-pages)
2017-10-30 10:58                     ` Stas Sergeev
2017-10-30 12:54                     ` walter harms

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 NNTP newsgroup(s).