• Austin Clements's avatar
    runtime: restore the Go-allocated signal stack in unminit · 292558be
    Austin Clements authored
    Currently, when we minit on a thread that already has an alternate
    signal stack (e.g., because the M was an extram being used for a cgo
    callback, or to handle a signal on a C thread, or because the
    platform's libc always allocates a signal stack like on Android), we
    simply drop the Go-allocated gsignal stack on the floor.
    
    This is a problem for Ms on the extram list because those Ms may later
    be reused for a different thread that may not have its own alternate
    signal stack. On tip, this manifests as a crash in sigaltstack because
    we clear the gsignal stack bounds in unminit and later try to use
    those cleared bounds when we re-minit that M. On 1.9 and earlier, we
    didn't clear the bounds, so this manifests as running more than one
    signal handler on the same signal stack, which could lead to arbitrary
    memory corruption.
    
    This CL fixes this problem by saving the Go-allocated gsignal stack in
    a new field in the m struct when overwriting it with a system-provided
    signal stack, and then restoring the original gsignal stack in
    unminit.
    
    This CL is designed to be easy to back-port to 1.9. It won't quite
    cherry-pick cleanly, but it should be sufficient to simply ignore the
    change in mexit (which didn't exist in 1.9).
    
    Now that we always have a place to stash the original signal stack in
    the m struct, there are some simplifications we can make to the signal
    stack handling. We'll do those in a later CL.
    
    Fixes #22930.
    
    Change-Id: I55c5a6dd9d97532f131146afdef0b216e1433054
    Reviewed-on: https://go-review.googlesource.com/81476
    Run-TryBot: Austin Clements <austin@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
    292558be
Name
Last commit
Last update
..
archive Loading commit data...
bufio Loading commit data...
builtin Loading commit data...
bytes Loading commit data...
cmd Loading commit data...
compress Loading commit data...
container Loading commit data...
context Loading commit data...
crypto Loading commit data...
database/sql Loading commit data...
debug Loading commit data...
encoding Loading commit data...
errors Loading commit data...
expvar Loading commit data...
flag Loading commit data...
fmt Loading commit data...
go Loading commit data...
hash Loading commit data...
html Loading commit data...
image Loading commit data...
index/suffixarray Loading commit data...
internal Loading commit data...
io Loading commit data...
log Loading commit data...
math Loading commit data...
mime Loading commit data...
net Loading commit data...
os Loading commit data...
path Loading commit data...
plugin Loading commit data...
reflect Loading commit data...
regexp Loading commit data...
runtime Loading commit data...
sort Loading commit data...
strconv Loading commit data...
strings Loading commit data...
sync Loading commit data...
syscall Loading commit data...
testing Loading commit data...
text Loading commit data...
time Loading commit data...
unicode Loading commit data...
unsafe Loading commit data...
vendor/golang_org/x Loading commit data...
Make.dist Loading commit data...
all.bash Loading commit data...
all.bat Loading commit data...
all.rc Loading commit data...
androidtest.bash Loading commit data...
bootstrap.bash Loading commit data...
buildall.bash Loading commit data...
clean.bash Loading commit data...
clean.bat Loading commit data...
clean.rc Loading commit data...
cmp.bash Loading commit data...
iostest.bash Loading commit data...
make.bash Loading commit data...
make.bat Loading commit data...
make.rc Loading commit data...
naclmake.bash Loading commit data...
nacltest.bash Loading commit data...
race.bash Loading commit data...
race.bat Loading commit data...
run.bash Loading commit data...
run.bat Loading commit data...
run.rc Loading commit data...