]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: restore RSB for sigpanic call on mips64x
authorAustin Clements <austin@google.com>
Wed, 31 Jan 2018 19:34:36 +0000 (14:34 -0500)
committerAustin Clements <austin@google.com>
Wed, 31 Jan 2018 20:57:53 +0000 (20:57 +0000)
preparePanic must set all registers expected by Go runtime conventions
in case the sigpanic is being injected into C code. However, on
mips64x it fails to restore RSB (R28). As a result, if C code modifies
RSB and then raises a signal that turns into a sigpanic call, sigpanic
may crash when it attempts to lock runtime.debuglock (the first global
it references).

Fix this by restoring RSB in the signal context using the same
convention as main and sigtramp.

Fixes #23641.

Change-Id: Ib47e83df89e2a3eece10f480e4e91ce9e4424388
Reviewed-on: https://go-review.googlesource.com/91156
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/signal_linux_mips64x.go
src/runtime/signal_mips64x.go

index 9e0cf42c706ae05191875d5a78b28a7d32d8cf9e..b608197d605a1503acb8fe4121b0763d59bab9ed 100644 (file)
@@ -66,6 +66,7 @@ func (c *sigctxt) hi() uint64   { return c.regs().sc_mdhi }
 func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
 func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
 
+func (c *sigctxt) set_r28(x uint64)  { c.regs().sc_regs[28] = x }
 func (c *sigctxt) set_r30(x uint64)  { c.regs().sc_regs[30] = x }
 func (c *sigctxt) set_pc(x uint64)   { c.regs().sc_pc = x }
 func (c *sigctxt) set_sp(x uint64)   { c.regs().sc_regs[29] = x }
index 9546a5af997bc49a7a52be35d8b00c420f97c21e..35b356c2fb104ebcd1ee5d134922c327abbdc849 100644 (file)
@@ -89,6 +89,8 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
        }
 
        // In case we are panicking from external C code
+       sigpanicPC := uint64(funcPC(sigpanic))
+       c.set_r28(sigpanicPC >> 32 << 32) // RSB register
        c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
-       c.set_pc(uint64(funcPC(sigpanic)))
+       c.set_pc(sigpanicPC)
 }