Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <87o8d5ppah.fsf@oldenburg.str.redhat.com>
Date: Thu, 20 May 2021 14:23:18 +0200
From: Florian Weimer <fweimer@...hat.com>
To: libc-coord@...ts.openwall.com
Subject: Alternate signal stacks allocation

I've drafted an API proposal for supporting the allocation of stacks
with sigaltstack (but they could be used for stackful coroutines as
well).  The need for this became clear to me after a change to
MINSIGSTKSZ revealed that many applications use rather idiosyncratic
ways to allocate these stacks, and those ways are increasingly
incompatible with changing kernel and hardware requirements.

Thanks,
Florian

Allocating Stacks
=====================

With the ‘cstack_’ family of functions, the GNU C Library provides
functions for allocating “call stacks” or “C stacks”.  Such stacks can
be used to implement cooperative (non-preemptive) multi-threading or
coroutines.  They are also useful as alternate signal stacks.  *Note
Signal Stack::

   These stacks do not come with their own thread control block and
therefore need to be scheduled on an existing thread.  On most targets,
resuming a pending computation with its own stack on a different thread
than the one it was suspended on is undefined because active stack
frames are typically tied to one particlar thread control block.

   By default, allocated stacks are bracketed by guard regions.
Applications that would otherwise run into the map limit can optionally
disable these guard pages.  For targets which fully support the GCC
‘-fstack-clash-protection’ option, the guard region at the top of the
stack is sized so that it can reliable detect stack overflow
(exhaustion).

   Allocated stacks are not explicitly allocated with executable memory
even if the current process image uses an executable stack.  The stacks
can still be executable for other reasons, e.g., lack of hardware
support for non-executable stacks.

 -- Data Type: cstack_t
     Values of this type are handles for allocated stacks.  Handles
     become invalid when freed by the ‘cstack_free’ function, and
     further use of them is invalid.

     The value ‘NULL’ is not a valid stack handle and is used to
     indicate errors.

 -- Function: cstack_t cstack_allocate (size_t SIZE, uint64_t FLAGS)

     | MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt | *Note POSIX
     Safety Concepts::.

     This function allocates a stack memory area and returns its handle.
     The SIZE argument indicates the number of bytes on the stack that
     are available for use by the application.  The GNU C Library
     ensures that in addition to the requested space, there is enough
     memory available to deliver one signal to code running on this
     stack, plus some extra reservation for the signal handler itself.

     If the specified stack size is zero, the function picks a
     reasonable stack size that provides enough space for delivering one
     (non-nested) signal and invoking most functions provided by the GNU
     C Library.

     The FLAGS argument is the bitwise-or of a set of flag constants.
     The following flags are defined

     ‘CSTACK_ALLOCATE_NOBOTTOMGUARD’

          This flags requests that ‘cstack_allocate’ does not allocate a
          guard region at the bottom of the stack (below the first
          activation frame).  This guard region can sometimes catch
          stack-based buffer overflows and turn them into a segmentation
          fault.

     ‘CSTACK_ALLOCATE_NOTOPGUARD’
          This flags requests that no guard region is allocated at the
          top end of the stack.  This guard region can be used to detect
          stack overflow (exahustion) and generate a segmentation fault
          in such sitations.

     If allocating the stack fails, ‘cstack_allocate’ returns ‘NULL’ to
     indicate an error.  The following errors are specific to this
     function:

     ‘ENOMEM’
          Insufficient memory is available to allocate the stack, or
          SIZE is too large.

     ‘EINVAL’
          The FLAGS argument contains unsupported flags.

 -- Function: void cstack_free (cstack_t STACK)

     | MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt | *Note POSIX
     Safety Concepts::.

     This functions deallocations the stack handle STACK and deallocates
     the associated memory.

 -- Function: void cstack_get (cstack_t STACK, stack_t *ALTSTACK)

     | MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt | *Note POSIX
     Safety Concepts::.

     This function obtains the usable stack region of STACK (excluding
     any guard regions) and writes it to ALTSTACK.  The resulting
     structure is suitable for use with the ‘sigaltstack’ function.

     The ‘ss_flags’ member of the ‘stack_t’ result is currently set to
     zero.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.