Hi,

attached patch makes the read-only GDT handling CET compatible

Quoting the patch description:
"""
CET enabled systems need to disable CR4.CET prior to attempting to
toggle CR0.WP to avoid triggering a #GP(0). This is needed in VMMR0.r0
for PaX's r/o GDT handling.

Enhance the r/o GDT handling to toggle CR4.CET as well in case it's enabled.

This patch is provided under the MIT license.
"""

It would be nice to get it integrated not only in trunk, but all still
maintained release branches as well.

Thanks,
Mathias
CET enabled systems need to disable CR4.CET prior to attempting to toggle
CR0.WP to avoid triggering a #GP(0). This is needed in VMMR0.r0 for PaX's
r/o GDT handling.

Enhance the r/o GDT handling to toggle CR4.CET as well in case it's enabled.

This patch is provided under the MIT license.

Index: src/VBox/VMM/VMMR0/HMR0A.asm
===================================================================
--- src/VBox/VMM/VMMR0/HMR0A.asm	(revision 104448)
+++ src/VBox/VMM/VMMR0/HMR0A.asm	(working copy)
@@ -440,6 +440,8 @@
 .gdt_readonly_or_need_writable:
         test    edi, VMX_RESTORE_HOST_GDT_NEED_WRITABLE
         jnz     .gdt_readonly_need_writable
+        test    edi, VMX_RESTORE_HOST_CET_ENABLED
+        jnz     .gdt_readonly_cet
 .gdt_readonly:
         mov     rcx, cr0
         mov     r9, rcx
@@ -451,6 +453,26 @@
         mov     cr0, r9
         jmp     .restore_fs
 
+.gdt_readonly_cet:
+        ;
+        ; CR4.CET, when enabled, needs to be disabled around toggling CR0.WP to
+        ; not #GP(0).
+        ;
+        mov     rcx, cr4
+        mov     r8, rcx
+        and     rcx, ~X86_CR4_CET
+        mov     cr4, rcx
+        mov     rcx, cr0
+        mov     r9, rcx
+        add     rax, qword [rsi + VMXRESTOREHOST.HostGdtr + 2]  ; xAX <- descriptor offset + GDTR.pGdt.
+        and     rcx, ~X86_CR0_WP
+        mov     cr0, rcx
+        and     dword [rax + 4], ~RT_BIT(9)                     ; clear the busy flag in TSS desc (bits 0-7=base, bit 9=busy bit)
+        ltr     dx
+        mov     cr0, r9
+        mov     cr4, r8
+        jmp     .restore_fs
+
 ALIGNCODE(8)
 .gdt_readonly_need_writable:
         add     rax, qword [rsi + VMXRESTOREHOST.HostGdtrRw + 2]  ; xAX <- descriptor offset + GDTR.pGdtRw
Index: src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 104448)
+++ src/VBox/VMM/VMMR0/HMVMXR0.cpp	(working copy)
@@ -3547,7 +3547,12 @@
 
         /* If the host has made GDT read-only, we would need to temporarily toggle CR0.WP before writing the GDT. */
         if (g_fHmHostKernelFeatures & SUPKERNELFEATURES_GDT_READ_ONLY)
+        {
             fRestoreHostFlags |= VMX_RESTORE_HOST_GDT_READ_ONLY;
+            /* If CET is enabled, it needs to be disabled around toggling CR0.WP. */
+            if (uHostCr4 & X86_CR4_CET)
+                fRestoreHostFlags |= VMX_RESTORE_HOST_CET_ENABLED;
+        }
         if (g_fHmHostKernelFeatures & SUPKERNELFEATURES_GDT_NEED_WRITABLE)
         {
             /* The GDT is read-only but the writable GDT is available. */
Index: src/VBox/VMM/include/HMInternal.h
===================================================================
--- src/VBox/VMM/include/HMInternal.h	(revision 104448)
+++ src/VBox/VMM/include/HMInternal.h	(working copy)
@@ -677,6 +677,7 @@
 #define VMX_RESTORE_HOST_GDT_READ_ONLY                          RT_BIT(7)
 #define VMX_RESTORE_HOST_GDT_NEED_WRITABLE                      RT_BIT(8)
 #define VMX_RESTORE_HOST_CAN_USE_WRFSBASE_AND_WRGSBASE          RT_BIT(9)
+#define VMX_RESTORE_HOST_CET_ENABLED                            RT_BIT(10)
 /**
  * This _must_ be the top most bit, so that we can easily check that it and
  * something else is set w/o having to do two checks like this:
@@ -689,7 +690,7 @@
  *     if (pVCpu->hm.s.vmx.fRestoreHostFlags > VMX_RESTORE_HOST_REQUIRED)
  * @endcode
  */
-#define VMX_RESTORE_HOST_REQUIRED                               RT_BIT(10)
+#define VMX_RESTORE_HOST_REQUIRED                               RT_BIT(11)
 /** @} */
 
 /**
Index: src/VBox/VMM/include/HMInternal.mac
===================================================================
--- src/VBox/VMM/include/HMInternal.mac	(revision 104448)
+++ src/VBox/VMM/include/HMInternal.mac	(working copy)
@@ -111,7 +111,8 @@
 %define VMX_RESTORE_HOST_GDT_READ_ONLY                          0080h   ;RT_BIT(7)
 %define VMX_RESTORE_HOST_GDT_NEED_WRITABLE                      0100h   ;RT_BIT(8)
 %define VMX_RESTORE_HOST_CAN_USE_WRFSBASE_AND_WRGSBASE          0200h   ;RT_BIT(9)
-%define VMX_RESTORE_HOST_REQUIRED                               0400h   ;RT_BIT(10) - must be the highest bit!
+%define VMX_RESTORE_HOST_CET_ENABLED                            0400h   ;RT_BIT(10)
+%define VMX_RESTORE_HOST_REQUIRED                               0800h   ;RT_BIT(11) - must be the highest bit!
 struc VMXRESTOREHOST
     .uHostSelDS                     resw    1
     .uHostSelES                     resw    1
_______________________________________________
vbox-dev mailing list
vbox-dev@virtualbox.org
https://www.virtualbox.org/mailman/listinfo/vbox-dev

Reply via email to