mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
kvm: check CPL to find out if the Sentry is in VM
RFLAGS cannot be used because the IF flag (interrupt flag) is cleared when
a goroutine suspended on the host side is resumed in the VM. This means it
can start switching into the vm when it is already in the VM. It only works
because the rt_sigprocmask syscall is triggered before constructing a signal
frame, returning execution back to the host side, and then it switches into
the VM again.
Fixes: 374a11a7cd ("platform/kvm: rewriting bluepill()...")
PiperOrigin-RevId: 673621750
This commit is contained in:
@@ -59,10 +59,9 @@ fallback:
|
||||
MOVQ ·savedSigsysHandler(SB), AX
|
||||
JMP AX
|
||||
|
||||
TEXT ·rflags(SB), $8-8
|
||||
PUSHFQ
|
||||
POPQ AX
|
||||
MOVQ AX, ret+0(FP)
|
||||
TEXT ·getcs(SB), $0-2
|
||||
MOVW CS, AX
|
||||
MOVW AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT ·addrOfBluepillUserHandler(SB), $0-8
|
||||
|
||||
@@ -148,9 +148,8 @@ func bluepillArchHandleExit(c *vCPU, context unsafe.Pointer) {
|
||||
}
|
||||
|
||||
func addrOfBluepillUserHandler() uintptr
|
||||
func rflags() uint64
|
||||
|
||||
const _RFLAGS_IF = 1 << 9
|
||||
func getcs() uint16
|
||||
|
||||
func currentCPU() *vCPU
|
||||
|
||||
@@ -158,8 +157,8 @@ func currentCPU() *vCPU
|
||||
//
|
||||
//go:nosplit
|
||||
func bluepill(c *vCPU) {
|
||||
// Interrupts are always disabled in the VM.
|
||||
if rflags()&_RFLAGS_IF == 0 {
|
||||
// The sentry is running in the VM ring 0.
|
||||
if getcs()&3 == 0 {
|
||||
if currentCPU() == c {
|
||||
// Already in the vm.
|
||||
return
|
||||
|
||||
@@ -29,6 +29,13 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform/kvm/testutil"
|
||||
)
|
||||
|
||||
func TestGetCS(t *testing.T) {
|
||||
cs := getcs()
|
||||
if cs != 0x33 {
|
||||
t.Fatalf("cs = 0x%x", cs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegments(t *testing.T) {
|
||||
applicationTest(t, true, testutil.AddrOfTwiddleSegments(), func(c *vCPU, regs *arch.Registers, pt *pagetables.PageTables) bool {
|
||||
testutil.SetTestSegments(regs)
|
||||
|
||||
Reference in New Issue
Block a user