Skip to content

Commit afee3fa

Browse files
nixprimegvisor-bot
authored andcommitted
platform/ptrace: return errors from switchToApp() rather than panicking
PiperOrigin-RevId: 820872406
1 parent 0828602 commit afee3fa

File tree

2 files changed

+19
-17
lines changed

2 files changed

+19
-17
lines changed

pkg/sentry/platform/ptrace/ptrace.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,10 @@ func (c *context) Switch(ctx pkgcontext.Context, mm platform.MemoryManager, ac *
110110
as := mm.AddressSpace()
111111
s := as.(*subprocess)
112112
restart:
113-
isSyscall := s.switchToApp(c, ac)
113+
isSyscall, err := s.switchToApp(c, ac)
114+
if err != nil {
115+
return nil, hostarch.NoAccess, err
116+
}
114117

115118
var (
116119
faultSP *subprocess

pkg/sentry/platform/ptrace/subprocess.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ func (t *thread) NotifyInterrupt() {
509509
// switchToApp is called from the main SwitchToApp entrypoint.
510510
//
511511
// This function returns true on a system call, false on a signal.
512-
func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
512+
func (s *subprocess) switchToApp(c *context, ac *arch.Context64) (bool, error) {
513513
// Lock the thread for ptrace operations.
514514
runtime.LockOSThread()
515515
defer runtime.UnlockOSThread()
@@ -532,19 +532,19 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
532532
if !c.interrupt.Enable(t) {
533533
// Pending interrupt; simulate.
534534
c.signalInfo = linux.SignalInfo{Signo: int32(platform.SignalInterrupt)}
535-
return false
535+
return false, nil
536536
}
537537
defer c.interrupt.Disable()
538538

539539
// Set registers.
540540
if err := t.setRegs(regs); err != nil {
541-
panic(fmt.Sprintf("ptrace set regs (%+v) failed: %v", regs, err))
541+
return false, fmt.Errorf("ptrace set regs (%+v) failed: %w", regs, err)
542542
}
543543
if err := t.setFPRegs(fpState, &c.archContext); err != nil {
544-
panic(fmt.Sprintf("ptrace set fpregs (%+v) failed: %v", fpState, err))
544+
return false, fmt.Errorf("ptrace set fpregs (%+v) failed: %w", fpState, err)
545545
}
546546
if err := t.setTLS(&tls); err != nil {
547-
panic(fmt.Sprintf("ptrace set tls (%+v) failed: %v", tls, err))
547+
return false, fmt.Errorf("ptrace set tls (%+v) failed: %w", tls, err)
548548
}
549549

550550
for {
@@ -554,14 +554,14 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
554554
unix.SYS_PTRACE,
555555
unix.PTRACE_SYSEMU_SINGLESTEP,
556556
uintptr(t.tid), 0, 0, 0, 0); errno != 0 {
557-
panic(fmt.Sprintf("ptrace sysemu failed: %v", errno))
557+
return false, fmt.Errorf("ptrace sysemu failed: %w", errno)
558558
}
559559
} else {
560560
if _, _, errno := unix.RawSyscall6(
561561
unix.SYS_PTRACE,
562562
unix.PTRACE_SYSEMU,
563563
uintptr(t.tid), 0, 0, 0, 0); errno != 0 {
564-
panic(fmt.Sprintf("ptrace sysemu failed: %v", errno))
564+
return false, fmt.Errorf("ptrace sysemu failed: %w", errno)
565565
}
566566
}
567567

@@ -576,16 +576,16 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
576576

577577
// Refresh all registers.
578578
if err := t.getRegs(regs); err != nil {
579-
panic(fmt.Sprintf("ptrace get regs failed: %v", err))
579+
return false, fmt.Errorf("ptrace get regs failed: %w", err)
580580
}
581581
if err := t.getFPRegs(fpState, &c.archContext); err != nil {
582-
panic(fmt.Sprintf("ptrace get fpregs failed: %v", err))
582+
return false, fmt.Errorf("ptrace get fpregs failed: %w", err)
583583
}
584584
if err := t.getTLS(&tls); err != nil {
585-
panic(fmt.Sprintf("ptrace get tls failed: %v", err))
585+
return false, fmt.Errorf("ptrace get tls failed: %w", err)
586586
}
587587
if !ac.SetTLS(uintptr(tls)) {
588-
panic(fmt.Sprintf("tls value %v is invalid", tls))
588+
return false, fmt.Errorf("tls value %v is invalid", tls)
589589
}
590590

591591
// Is it a system call?
@@ -594,13 +594,12 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
594594

595595
// Ensure registers are sane.
596596
updateSyscallRegs(regs)
597-
return true
597+
return true, nil
598598
}
599599

600600
// Grab signal information.
601601
if err := t.getSignalInfo(&c.signalInfo); err != nil {
602-
// Should never happen.
603-
panic(fmt.Sprintf("ptrace get signal info failed: %v", err))
602+
return false, fmt.Errorf("ptrace get signal info failed: %w", err)
604603
}
605604

606605
// We have a signal. We verify however, that the signal was
@@ -611,13 +610,13 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) bool {
611610
// the signal information, and may patch it in order to
612611
// facilitate vsyscall emulation. See patchSignalInfo.
613612
patchSignalInfo(regs, &c.signalInfo)
614-
return false
613+
return false, nil
615614
} else if c.signalInfo.Code <= 0 && c.signalInfo.PID() == int32(os.Getpid()) {
616615
// The signal was generated by this process. That means
617616
// that it was an interrupt or something else that we
618617
// should bail for. Note that we ignore signals
619618
// generated by other processes.
620-
return false
619+
return false, nil
621620
}
622621
}
623622
}

0 commit comments

Comments
 (0)