Re: [PATCH v8 00/26] Enable CET Virtualization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 1/4/2024 2:50 AM, Edgecombe, Rick P wrote:
On Thu, 2023-12-21 at 09:02 -0500, Yang Weijiang wrote:
Control-flow Enforcement Technology (CET) is a kind of CPU feature
used
to prevent Return/CALL/Jump-Oriented Programming (ROP/COP/JOP)
attacks.
It provides two sub-features(SHSTK,IBT) to defend against ROP/COP/JOP
style control-flow subversion attacks.

Shadow Stack (SHSTK):
   A shadow stack is a second stack used exclusively for control
transfer
   operations. The shadow stack is separate from the data/normal stack
and
   can be enabled individually in user and kernel mode. When shadow
stack
   is enabled, CALL pushes the return address on both the data and
shadow
   stack. RET pops the return address from both stacks and compares
them.
   If the return addresses from the two stacks do not match, the
processor
   generates a #CP.

Indirect Branch Tracking (IBT):
   IBT introduces new instruction(ENDBRANCH)to mark valid target
addresses of
   indirect branches (CALL, JMP etc...). If an indirect branch is
executed
   and the next instruction is _not_ an ENDBRANCH, the processor
generates a
   #CP. These instruction behaves as a NOP on platforms that doesn't
support
   CET.
What is the design around CET and the KVM emulator?

KVM doesn't emulate CET HW behavior for guest CET, instead it leaves CET related
checks and handling in guest kernel. E.g., if emulated JMP/CALL in emulator triggers
mismatch of data stack and shadow stack contents, #CP is generated in non-root
mode instead of being injected by KVM.  KVM only emulates basic x86 HW behaviors,
e.g., call/jmp/ret/in/out etc.

My understanding is that the KVM emulator kind of does what it has to
keep things running, and isn't expected to emulate every possible
instruction. With CET though, it is changing the behavior of existing
supported instructions. I could imagine a guest could skip over CET
enforcement by causing an MMIO exit and racing to overwrite the exit-
causing instruction from a different vcpu to be an indirect CALL/RET,
etc.

Can you elaborate the case? I cannot figure out how it works.

With reasonable assumptions around the threat model in use by the
guest this is probably not a huge problem. And I guess also reasonable
assumptions about functional expectations, as a misshandled CALL or RET
by the emulator would corrupt the shadow stack.

KVM emulates general x86 HW behaviors, if something wrong happens after emulation
then it can happen even on bare metal, i.e., guest SW most likely gets wrong somewhere
and it's expected to trigger CET exceptions in guest kernel.

But, another thing to do could be to just return X86EMUL_UNHANDLEABLE
or X86EMUL_RETRY_INSTR when CET is active and RET or CALL are emulated.

IMHO, translating the CET induced exceptions into X86EMUL_UNHANDLEABLE or X86EMUL_RETRY_INSTR would confuse guest kernel or even VMM, I prefer letting guest kernel handle #CP directly.
And I guess also for all instructions if the TRACKER bit is set. It
might tie up that loose end without too much trouble.

Anyway, was there a conscious decision to just punt on CET enforcement
in the emulator?

I don't remember we ever discussed it in community, but since KVM maintainers reviewed
the CET virtualization series for a long time, I assume we're moving on the right way :-)






[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux