From c0ab059e7b904197f52ade879711d7fb02ffa8c0 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Fri, 8 Jun 2018 17:50:55 -0700 Subject: Fix kernel flags handling and add missing vectors. PiperOrigin-RevId: 199877174 Change-Id: I9d19ea301608c2b989df0a6123abb1e779427853 --- pkg/sentry/platform/kvm/machine_amd64.go | 52 ++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-) (limited to 'pkg/sentry/platform/kvm') diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index 7fcb7451f..7ac289756 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -150,13 +150,20 @@ func (c *vCPU) fault(signal int32) (*arch.SignalInfo, usermem.AccessType, error) // the code provided here. We need to re-execute. return nil, usermem.NoAccess, platform.ErrContextInterrupt } - info := &arch.SignalInfo{Signo: signal} + info := &arch.SignalInfo{ + Signo: signal, + } info.SetAddr(uint64(faultAddr)) accessType := usermem.AccessType{ Read: code&(1<<1) == 0, Write: code&(1<<1) != 0, Execute: code&(1<<4) != 0, } + if !accessType.Write && !accessType.Execute { + info.Code = 1 // SEGV_MAPERR. + } else { + info.Code = 2 // SEGV_ACCERR. + } return info, accessType, platform.ErrContextSignal } @@ -191,30 +198,55 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts) (*arch.SignalInfo, user return c.fault(int32(syscall.SIGSEGV)) case ring0.Debug, ring0.Breakpoint: - info := &arch.SignalInfo{Signo: int32(syscall.SIGTRAP)} + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGTRAP), + Code: 1, // TRAP_BRKPT (breakpoint). + } + info.SetAddr(switchOpts.Registers.Rip) // Include address. return info, usermem.AccessType{}, platform.ErrContextSignal case ring0.GeneralProtectionFault: - if !ring0.IsCanonical(switchOpts.Registers.Rip) { - // If the RIP is non-canonical, it's a SEGV. - info := &arch.SignalInfo{Signo: int32(syscall.SIGSEGV)} - return info, usermem.AccessType{}, platform.ErrContextSignal + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGSEGV), + Code: arch.SignalInfoKernel, } - // Otherwise, we deliver a SIGBUS. - info := &arch.SignalInfo{Signo: int32(syscall.SIGBUS)} + info.SetAddr(switchOpts.Registers.Rip) // Include address. return info, usermem.AccessType{}, platform.ErrContextSignal case ring0.InvalidOpcode: - info := &arch.SignalInfo{Signo: int32(syscall.SIGILL)} + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGILL), + Code: 1, // ILL_ILLOPC (illegal opcode). + } + info.SetAddr(switchOpts.Registers.Rip) // Include address. + return info, usermem.AccessType{}, platform.ErrContextSignal + + case ring0.DivideByZero: + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGFPE), + Code: 1, // FPE_INTDIV (divide by zero). + } + info.SetAddr(switchOpts.Registers.Rip) // Include address. return info, usermem.AccessType{}, platform.ErrContextSignal case ring0.X87FloatingPointException: - info := &arch.SignalInfo{Signo: int32(syscall.SIGFPE)} + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGFPE), + Code: 7, // FPE_FLTINV (invalid operation). + } + info.SetAddr(switchOpts.Registers.Rip) // Include address. return info, usermem.AccessType{}, platform.ErrContextSignal case ring0.Vector(bounce): return nil, usermem.NoAccess, platform.ErrContextInterrupt + case ring0.AlignmentCheck: + info := &arch.SignalInfo{ + Signo: int32(syscall.SIGBUS), + Code: 2, // BUS_ADRERR (physical address does not exist). + } + return info, usermem.NoAccess, platform.ErrContextSignal + case ring0.NMI: // An NMI is generated only when a fault is not servicable by // KVM itself, so we think some mapping is writeable but it's -- cgit v1.2.3