[kvm-unit-tests PATCH v2 4/4] x86/access: Try emulation for CR0.WP test as well

Mathias Krause
2023-03-31T13:57:36Z

Enhance the CR.WP toggling test to do additional tests via the emulator
as these used to trigger bugs when CR0.WP is guest owned.

Link: https://lore.kernel.org/kvm/ea3a8fbc-2bf8-7442-e498-3e5818384c83@grsecurity.net/
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
---
x86/access.c | 46 +++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/x86/access.c b/x86/access.c
index ae5e7d8e8892..21967434bc18 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -1107,27 +1107,43 @@ static int check_write_cr0wp(ac_pt_env_t *pt_env)
* We load CR0.WP with the inverse value of what would be used during
* the access test and toggle EFER.NX to flush and rebuild the current
* MMU context based on that value.
+ *
+ * This used to trigger a bug in the emulator we try to test via FEP.
*/
+ for (;;) {
+ const char *fep = (at.flags & AC_FEP_MASK) ? "FEP " : "";

- set_cr0_wp(1);
- set_efer_nx(1);
- set_efer_nx(0);
+ set_cr0_wp(1);
+ set_efer_nx(1);
+ set_efer_nx(0);

- if (!ac_test_do_access(&at)) {
- printf("%s: CR0.WP=0 r/o write fail\n", __FUNCTION__);
- err++;
- }
+ if (!ac_test_do_access(&at)) {
+ printf("%s: %sCR0.WP=0 r/o write fail\n", __FUNCTION__, fep);
+ err++;
+ }

- at.flags |= AC_CPU_CR0_WP_MASK;
- __ac_set_expected_status(&at, false);
+ at.flags |= AC_CPU_CR0_WP_MASK;
+ __ac_set_expected_status(&at, false);

- set_cr0_wp(0);
- set_efer_nx(1);
- set_efer_nx(0);
+ set_cr0_wp(0);
+ set_efer_nx(1);
+ set_efer_nx(0);

- if (!ac_test_do_access(&at)) {
- printf("%s: CR0.WP=1 r/o write deny fail\n", __FUNCTION__);
- err++;
+ if (!ac_test_do_access(&at)) {
+ printf("%s: %sCR0.WP=1 r/o write deny fail\n", __FUNCTION__, fep);
+ err++;
+ }
+
+ if (!fep_available)
+ break;
+
+ if (at.flags & AC_FEP_MASK)
+ break;
+
+ /* Re-test via the emulator */
+ at.flags |= AC_FEP_MASK;
+ at.flags ^= AC_CPU_CR0_WP_MASK;
+ __ac_set_expected_status(&at, false);
}

return err == 0;
--
2.39.2