Use a range to identify SIGSEGV in stack guards
authorJosh Stone <jistone@redhat.com>
Wed, 31 Jan 2018 19:41:29 +0000 (11:41 -0800)
committerMoritz Mühlenhoff <jmm@debian.org>
Sun, 8 Jul 2018 19:39:35 +0000 (20:39 +0100)
commitf1552d828552261f8f70d78803e74e5f17feed5e
tree2112ac11214cbce05c404e862102591ad9820a6e
parent4e4bd5d5f3ce096d373bb590dd7d8e641d6b29a3
Use a range to identify SIGSEGV in stack guards

Previously, the `guard::init()` and `guard::current()` functions were
returning a `usize` address representing the top of the stack guard,
respectively for the main thread and for spawned threads.  The `SIGSEGV`
handler on `unix` targets checked if a fault was within one page below
that address, if so reporting it as a stack overflow.

Now `unix` targets report a `Range<usize>` representing the guard
memory, so it can cover arbitrary guard sizes.  Non-`unix` targets which
always return `None` for guards now do so with `Option<!>`, so they
don't pay any overhead.

For `linux-gnu` in particular, the previous guard upper-bound was
`stackaddr + guardsize`, as the protected memory was *inside* the stack.
This was a glibc bug, and starting from 2.27 they are moving the guard
*past* the end of the stack.  However, there's no simple way for us to
know where the guard page actually lies, so now we declare it as the
whole range of `stackaddr ± guardsize`, and any fault therein will be
called a stack overflow.  This fixes #47863.

Gbp-Pq: Name u-0002-Use-a-range-to-identify-SIGSEGV-in-stack-guards.patch
src/libstd/sys/redox/thread.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/wasm/thread.rs
src/libstd/sys/windows/thread.rs
src/libstd/sys_common/thread_info.rs