From: Austin Clements Date: Wed, 31 Jan 2018 19:34:36 +0000 (-0500) Subject: runtime: restore RSB for sigpanic call on mips64x X-Git-Tag: go1.10rc2~2^2~16 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e5186895fc7954c0992c345eb2a91f8c964b2099;p=gostls13.git runtime: restore RSB for sigpanic call on mips64x 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 Reviewed-by: Cherry Zhang TryBot-Result: Gobot Gobot --- diff --git a/src/runtime/signal_linux_mips64x.go b/src/runtime/signal_linux_mips64x.go index 9e0cf42c70..b608197d60 100644 --- a/src/runtime/signal_linux_mips64x.go +++ b/src/runtime/signal_linux_mips64x.go @@ -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 } diff --git a/src/runtime/signal_mips64x.go b/src/runtime/signal_mips64x.go index 9546a5af99..35b356c2fb 100644 --- a/src/runtime/signal_mips64x.go +++ b/src/runtime/signal_mips64x.go @@ -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) }