From 29e00c943a61dfcfd4ac8d3f6f526eab641c44a6 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Mon, 16 Jul 2018 22:02:03 -0700 Subject: Add CPUID faulting for ptrace and KVM. PiperOrigin-RevId: 204858314 Change-Id: I8252bf8de3232a7a27af51076139b585e73276d4 --- pkg/sentry/kernel/task_run.go | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'pkg/sentry/kernel') diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 94ce5582b..a03fa6ac0 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -221,6 +221,24 @@ func (*runApp) execute(t *Task) taskRunState { // loop to figure out why. return (*runApp)(nil) + case platform.ErrContextSignalCPUID: + // Is this a CPUID instruction? + expected := arch.CPUIDInstruction[:] + found := make([]byte, len(expected)) + _, err := t.CopyIn(usermem.Addr(t.Arch().IP()), &found) + if err == nil && bytes.Equal(expected, found) { + // Skip the cpuid instruction. + t.Arch().CPUIDEmulate(t) + t.Arch().SetIP(t.Arch().IP() + uintptr(len(expected))) + + // Resume execution. + return (*runApp)(nil) + } + + // The instruction at the given RIP was not a CPUID, and we + // fallthrough to the default signal deliver behavior below. + fallthrough + case platform.ErrContextSignal: // Looks like a signal has been delivered to us. If it's a synchronous // signal (SEGV, SIGBUS, etc.), it should be sent to the application @@ -266,28 +284,7 @@ func (*runApp) execute(t *Task) taskRunState { } switch sig { - case linux.SIGILL: - // N.B. The debug stuff here is arguably - // expensive. Don't fret. This gets called - // about 5 times for a typical application, if - // that. - t.Debugf("SIGILL @ %x", t.Arch().IP()) - - // Is this a CPUID instruction? - expected := arch.CPUIDInstruction[:] - found := make([]byte, len(expected)) - _, err := t.CopyIn(usermem.Addr(t.Arch().IP()), &found) - if err == nil && bytes.Equal(expected, found) { - // Skip the cpuid instruction. - t.Arch().CPUIDEmulate(t) - t.Arch().SetIP(t.Arch().IP() + uintptr(len(expected))) - break - } - - // Treat it like any other synchronous signal. - fallthrough - - case linux.SIGSEGV, linux.SIGBUS, linux.SIGFPE, linux.SIGTRAP: + case linux.SIGILL, linux.SIGSEGV, linux.SIGBUS, linux.SIGFPE, linux.SIGTRAP: // Synchronous signal. Send it to ourselves. Assume the signal is // legitimate and force it (work around the signal being ignored or // blocked) like Linux does. Conveniently, this is even the correct -- cgit v1.2.3