Fix systrap TLS handling on ARM.

With context decoupling off, TLS was not initialized properly because upon
creation of a sysmsg thread the sighandler overwrote TLS with 0. The fix for
this is to write the correct TLS only _after_ the sysmsg thread is initialized.

With context decoupling on, retrieveArchSpecificState was not being used, which
means that TLS was not saved to the sentry at all. So in this case, sysmsg
threads would initially have the correct TLS value, but as soon as it changed
during runtime it would become incorrect.

Reported-by: syzbot+1cbe57d0e13ba2aa1898@syzkaller.appspotmail.com
PiperOrigin-RevId: 518626789
This commit is contained in:
Konstantin Bogomolov
2023-03-22 11:35:37 -07:00
committed by gVisor bot
parent ca7e83b679
commit 08920d098b
2 changed files with 12 additions and 10 deletions
+9 -9
View File
@@ -694,19 +694,19 @@ func (t *thread) NotifyInterrupt() {
// The second return value is true if a syscall instruction can be replaced on
// a function call.
func (s *subprocess) switchToApp(c *context, ac *arch.Context64) (isSyscall bool, shouldPatchSyscall bool, err error) {
// Reset necessary registers.
regs := &ac.StateData().Regs
s.resetSysemuRegs(regs)
ctx := c.sharedContext
ctx.shared.Regs = regs.PtraceRegs
restoreArchSpecificState(ctx.shared, ac)
// Get sysmsg thread bound to the context; no-op if contextDecoupling is on.
regs := &ac.StateData().Regs
sysThread, err := s.getSysmsgThread(regs, c, ac)
if err != nil {
return false, false, err
}
// Reset necessary registers.
s.resetSysemuRegs(regs)
ctx := c.sharedContext
ctx.shared.Regs = regs.PtraceRegs
restoreArchSpecificState(ctx.shared, ac)
// Check for interrupts, and ensure that future interrupts signal the context.
if !c.interrupt.Enable(c.sharedContext) {
// Pending interrupt; simulate.
@@ -757,11 +757,11 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) (isSyscall bool
return false, false, err
}
}
retrieveArchSpecificState(ctx.shared, ac)
}
// Copy register state locally.
regs.PtraceRegs = ctx.shared.Regs
retrieveArchSpecificState(ctx.shared, ac)
// We have a signal. We verify however, that the signal was
// either delivered from the kernel or from this process. We
// don't respect other signals.
@@ -193,7 +193,9 @@ func restoreArchSpecificState(ctx *sysmsg.ThreadContext, ac *arch.Context64) {
func setArchSpecificRegs(sysThread *sysmsgThread, regs *arch.Registers) {
if contextDecouplingExp {
// Set the start function and initial stack.
// Set the start function and initial stack. On ARM __export_start does not
// actually get used because we send a signal to the thread upon startup
// right away (see archSpecificSysmsgThreadInit below).
regs.PtraceRegs.Pc = uint64(stubSysmsgStart + uintptr(sysmsg.Sighandler_blob_offset____export_start))
regs.PtraceRegs.Sp = uint64(sysmsg.StackAddrToSyshandlerStack(sysThread.sysmsgPerThreadMemAddr()))
}