|
|
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.