From patchwork Mon Apr 3 10:56:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Krause X-Patchwork-Id: 13198035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5636C761A6 for ; Mon, 3 Apr 2023 10:56:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231849AbjDCK4k (ORCPT ); Mon, 3 Apr 2023 06:56:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231658AbjDCK4h (ORCPT ); Mon, 3 Apr 2023 06:56:37 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0ECED61A3 for ; Mon, 3 Apr 2023 03:56:35 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id j24so28921391wrd.0 for ; Mon, 03 Apr 2023 03:56:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=grsecurity.net; s=grsec; t=1680519393; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Tvq2Ku7+r2hCsvAVWbqSUv9fohN3osKERwU7gfauayA=; b=DXg87Kr1aQLpt/NeklDhnizO8Fm/hhU1/lNnX3vxY8y3EHgHFXHvcnC43pjQNaGUDP CJ6ds0K0ijiSLy8T+5e29E0IKkKVhpsk1KIKOxmcMTUxVr5tBMt4xBA/0t1Fg7kEiKkM IfbwJbJVoFFuq9MolSk2uNDk6KGl0nN57w3YKLfLNM8B5jEdqFu8bKI4nTgeOQwXVbdP xe9jCTTDumO/6FV4Zcm5zUeQhff674yA1zXdngud7DRQycPScGGL9Tl8+tm0v9MTxKir EbNZKsPdoJ1/TNOaksw6iZy2o2R/hbb2GZBV5IFyyJ5Y29J3kBaUz6KsA+WUcRH5OVZ2 Iavg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680519393; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Tvq2Ku7+r2hCsvAVWbqSUv9fohN3osKERwU7gfauayA=; b=HoY2vMZjz5i8845PimgJJaG2kcQ6EA9BStT4GgE9QIvVl5l/Glz/anyzEIxXxyDLEm gOXCWFyjH9hIfk/KfZcz9tHvhJzXWweqcZcfd2LE74fVZolQGwPTvF8xx9R5+MT5ejdf i72BkRF3BXk+QjOMmLaIx7JZaP/acBRPcCHVS2JZXDPnp/iqOLWTQ/sC5m7yKdSwPZ5K z7Xfyf6+yaNvaL+RP8fgveOCxuq1l7yzILwGJiRZz37NPvwbj5TOm+NZfXryMSzNeJdj idZEa3we7oexp6t6F52usSuHVk48DwhTm99SR8LXp+KNaFfWu4iqPyBamJyIeDPlS6Ml kRRg== X-Gm-Message-State: AAQBX9daKRHlR9MgHiwwLvgPloEL/Y7k3XS9US2HVLBAwQFrS8PwRB0S aRzF3+viKNyJQiabNjPLhnDBkEOd0SR/mI5LurPoyA== X-Google-Smtp-Source: AKy350agVdPjU1Lm8smDa0L24zDRnl14626ymLKEG6qoTsTUhdeGSJBsG+/0WTFnJ1fEYxZX8CmCWQ== X-Received: by 2002:a05:6000:7:b0:2cf:f314:774d with SMTP id h7-20020a056000000700b002cff314774dmr26607311wrx.44.1680519393228; Mon, 03 Apr 2023 03:56:33 -0700 (PDT) Received: from nuc.fritz.box (p200300f6af22160069a3c79c8928b176.dip0.t-ipconnect.de. [2003:f6:af22:1600:69a3:c79c:8928:b176]) by smtp.gmail.com with ESMTPSA id x6-20020a5d60c6000000b002dfca33ba36sm9483671wrt.8.2023.04.03.03.56.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 03:56:32 -0700 (PDT) From: Mathias Krause To: kvm@vger.kernel.org Cc: Sean Christopherson , Mathias Krause Subject: [kvm-unit-tests PATCH v3 1/4] x86: Use existing CR0.WP / CR4.SMEP bit definitions Date: Mon, 3 Apr 2023 12:56:15 +0200 Message-Id: <20230403105618.41118-2-minipli@grsecurity.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230403105618.41118-1-minipli@grsecurity.net> References: <20230403105618.41118-1-minipli@grsecurity.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Use the existing bit definitions from x86/processor.h instead of defining one-off versions in individual tests. Signed-off-by: Mathias Krause --- x86/access.c | 11 ++++------- x86/pks.c | 5 ++--- x86/pku.c | 5 ++--- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/x86/access.c b/x86/access.c index 4dfec23073f7..203353a3f74f 100644 --- a/x86/access.c +++ b/x86/access.c @@ -20,9 +20,6 @@ static int invalid_mask; #define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 36) - 1) & PAGE_MASK)) #define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) -#define CR0_WP_MASK (1UL << 16) -#define CR4_SMEP_MASK (1UL << 20) - #define PFERR_PRESENT_MASK (1U << 0) #define PFERR_WRITE_MASK (1U << 1) #define PFERR_USER_MASK (1U << 2) @@ -239,9 +236,9 @@ static void set_cr0_wp(int wp) { unsigned long cr0 = shadow_cr0; - cr0 &= ~CR0_WP_MASK; + cr0 &= ~X86_CR0_WP; if (wp) - cr0 |= CR0_WP_MASK; + cr0 |= X86_CR0_WP; if (cr0 != shadow_cr0) { write_cr0(cr0); shadow_cr0 = cr0; @@ -272,9 +269,9 @@ static unsigned set_cr4_smep(ac_test_t *at, int smep) unsigned long cr4 = shadow_cr4; unsigned r; - cr4 &= ~CR4_SMEP_MASK; + cr4 &= ~X86_CR4_SMEP; if (smep) - cr4 |= CR4_SMEP_MASK; + cr4 |= X86_CR4_SMEP; if (cr4 == shadow_cr4) return 0; diff --git a/x86/pks.c b/x86/pks.c index ef95fb96c597..bda15efc546d 100644 --- a/x86/pks.c +++ b/x86/pks.c @@ -5,7 +5,6 @@ #include "x86/vm.h" #include "x86/msr.h" -#define CR0_WP_MASK (1UL << 16) #define PTE_PKEY_BIT 59 #define SUPER_BASE (1 << 23) #define SUPER_VAR(v) (*((__typeof__(&(v))) (((unsigned long)&v) + SUPER_BASE))) @@ -18,9 +17,9 @@ static void set_cr0_wp(int wp) { unsigned long cr0 = read_cr0(); - cr0 &= ~CR0_WP_MASK; + cr0 &= ~X86_CR0_WP; if (wp) - cr0 |= CR0_WP_MASK; + cr0 |= X86_CR0_WP; write_cr0(cr0); } diff --git a/x86/pku.c b/x86/pku.c index 51ff412cef82..6c0d72cc6f81 100644 --- a/x86/pku.c +++ b/x86/pku.c @@ -5,7 +5,6 @@ #include "x86/vm.h" #include "x86/msr.h" -#define CR0_WP_MASK (1UL << 16) #define PTE_PKEY_BIT 59 #define USER_BASE (1 << 23) #define USER_VAR(v) (*((__typeof__(&(v))) (((unsigned long)&v) + USER_BASE))) @@ -18,9 +17,9 @@ static void set_cr0_wp(int wp) { unsigned long cr0 = read_cr0(); - cr0 &= ~CR0_WP_MASK; + cr0 &= ~X86_CR0_WP; if (wp) - cr0 |= CR0_WP_MASK; + cr0 |= X86_CR0_WP; write_cr0(cr0); } From patchwork Mon Apr 3 10:56:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Krause X-Patchwork-Id: 13198036 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBD75C761A6 for ; Mon, 3 Apr 2023 10:56:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231985AbjDCK4o (ORCPT ); Mon, 3 Apr 2023 06:56:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231803AbjDCK4j (ORCPT ); Mon, 3 Apr 2023 06:56:39 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F260586B5 for ; Mon, 3 Apr 2023 03:56:35 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id h17so28865023wrt.8 for ; Mon, 03 Apr 2023 03:56:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=grsecurity.net; s=grsec; t=1680519394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=a6fwZqXE56drVA6/4ffLVKYgxl6E3+Ct3neznNmShJg=; b=i+UyFB8lT/cD+ytOt/bgqqW/kjNxd2rdgYAAd7P4052hxXfkyaAh6TkIerF6C8SE3Y mCrOtpjrqlSOkbgHYO23T7pm0Tx1WTTp4CW3YdoabsFLhw98qwUYMB6F1I+FC0jYYHdA ylkUj99TQmTKFxijlXEiXoSGnqViapkEdffez28eIFpwDqE32PPxCyDv+KUbWYdGeVtm ttePFDBRYzybD2l7jzpnX8wUPNsLlYKPrbZd91Z0vKvcKi1TJj9ptKMnxb9Nj7Mcwqfc mxBEMYS8vkcl6MocH58zdrc32gdRYjn1wYHPRgunx2/qeBehG52HIPJ/nt7HNEfje0nR HMwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680519394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a6fwZqXE56drVA6/4ffLVKYgxl6E3+Ct3neznNmShJg=; b=yLsyIwVl3gwicIj+QjisXIIQSlSz7gk/j62ANrY/to8Uj3dqIsQe/s1VBy6ZjU4FT1 RelfJDJ50vmLcUKEDvpkCpyolHH5Ui9xta8U8wwEG90Csx+VAQ7YLm7TOjRvNnE/iDL8 ilec5PNq5STd3nYo3nYQ+5GQWVCYTeSpKOsPVu5EkKUS9Rgm4liwg8UBTPutndQMCThN Bs8MPQpZ0Wusv6KKxT2bPrknJiVgqe+ryKnKmxzFD24vJJjwgfg5t1QAnR8EC7wC7fBH 81PHswDC+Ig18vJfeJneRQ0fGJM0Q/rCqhQRXPxOeGxr/vl+7gp7eqAAi28kC+SJlJ53 kGNQ== X-Gm-Message-State: AAQBX9f4hjdC9fRQGsyBA/jCXxY/xgVyvSqziARe0dhFHJVeIyWxT5r/ yIbYCPOdeP6f8fKHuKwzkfZ42Lx+NyzHGb1qSLKvaw== X-Google-Smtp-Source: AKy350Zr1H3Owf41ia6tPBdvJy13si0l1F0RAGms+pis2z1qjhkewU+Ag5eU2BO8HKg5kV0f7qD8xg== X-Received: by 2002:adf:e303:0:b0:2c5:4c9d:2dab with SMTP id b3-20020adfe303000000b002c54c9d2dabmr13036720wrj.10.1680519394093; Mon, 03 Apr 2023 03:56:34 -0700 (PDT) Received: from nuc.fritz.box (p200300f6af22160069a3c79c8928b176.dip0.t-ipconnect.de. [2003:f6:af22:1600:69a3:c79c:8928:b176]) by smtp.gmail.com with ESMTPSA id x6-20020a5d60c6000000b002dfca33ba36sm9483671wrt.8.2023.04.03.03.56.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 03:56:33 -0700 (PDT) From: Mathias Krause To: kvm@vger.kernel.org Cc: Sean Christopherson , Mathias Krause Subject: [kvm-unit-tests PATCH v3 2/4] x86/access: CR0.WP toggling write to r/o data test Date: Mon, 3 Apr 2023 12:56:16 +0200 Message-Id: <20230403105618.41118-3-minipli@grsecurity.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230403105618.41118-1-minipli@grsecurity.net> References: <20230403105618.41118-1-minipli@grsecurity.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org KUT has tests that verify a supervisor write access to an r/o page is successful when CR0.WP=0, but lacks a test that explicitly verifies that the same access faults after setting CR0.WP=1 without flushing any associated TLB entries, either explicitly (INVLPG) or implicitly (write to CR3). Add such a test. Signed-off-by: Mathias Krause --- For v3 I moved the guts to a helper but omitted the "as expected" part from the printf() as it not only keeps the generated output below 80 chars but also is kinda superfluous when it triggers. Here's an example failure run (with the full series applied): : run : .................................................................................................................................................................................................................................................................................................... : test pte.a pte.p pde.a pde.p write fep: FAIL: unexpected fault : Dump mapping: address: 0xffff923042007000 : ------L4 I292: 2100027 : ------L3 I193: 2101027 : ------L2 I16: 2102021 : ------L1 I7: 2000061 : do_cr0_wp_access: emulated supervisor write with CR0.WP=0 did not SUCCEED : : test pte.a pte.p pde.a pde.p write cr0.wp fep: FAIL: unexpected access : Dump mapping: address: 0xffff923042007000 : ------L4 I292: 2100027 : ------L3 I193: 2101027 : ------L2 I16: 2102021 : ------L1 I7: 2000061 : do_cr0_wp_access: emulated supervisor write with CR0.WP=1 did not FAULT : : 19169286 tests, 1 failures : FAIL access As can be seen, ac_test_check() already prints the failure reason, no need to mention it again. x86/access.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/x86/access.c b/x86/access.c index 203353a3f74f..a01278451b96 100644 --- a/x86/access.c +++ b/x86/access.c @@ -575,9 +575,10 @@ fault: at->expected_error &= ~PFERR_FETCH_MASK; } -static void ac_set_expected_status(ac_test_t *at) +static void __ac_set_expected_status(ac_test_t *at, bool flush) { - invlpg(at->virt); + if (flush) + invlpg(at->virt); if (at->ptep) at->expected_pte = *at->ptep; @@ -599,6 +600,11 @@ static void ac_set_expected_status(ac_test_t *at) ac_emulate_access(at, at->flags); } +static void ac_set_expected_status(ac_test_t *at) +{ + __ac_set_expected_status(at, true); +} + static pt_element_t ac_get_pt(ac_test_t *at, int i, pt_element_t *ptep) { pt_element_t pte; @@ -1061,6 +1067,56 @@ err: return 0; } +#define TOGGLE_CR0_WP_TEST_BASE_FLAGS \ + (AC_PDE_PRESENT_MASK | AC_PDE_ACCESSED_MASK | \ + AC_PTE_PRESENT_MASK | AC_PTE_ACCESSED_MASK | \ + AC_ACCESS_WRITE_MASK) + +static int do_cr0_wp_access(ac_test_t *at, int flags) +{ + const bool cr0_wp = !!(flags & AC_CPU_CR0_WP_MASK); + + at->flags = TOGGLE_CR0_WP_TEST_BASE_FLAGS | flags; + __ac_set_expected_status(at, false); + + /* + * Under VMX the guest might own the CR0.WP bit, requiring KVM to + * manually keep track of it where needed, e.g. in the guest page + * table walker. + * + * Load CR0.WP with the inverse value of what will be used during + * the access test and toggle EFER.NX to coerce KVM into rebuilding + * the current MMU context based on the soon-to-be-stale CR0.WP. + */ + set_cr0_wp(!cr0_wp); + set_efer_nx(1); + set_efer_nx(0); + + if (!ac_test_do_access(at)) { + printf("%s: supervisor write with CR0.WP=%d did not %s\n", + __FUNCTION__, cr0_wp, cr0_wp ? "FAULT" : "SUCCEED"); + + return 1; + } + + return 0; +} + +static int check_toggle_cr0_wp(ac_pt_env_t *pt_env) +{ + ac_test_t at; + int err = 0; + + ac_test_init(&at, 0xffff923042007000ul, pt_env); + at.flags = TOGGLE_CR0_WP_TEST_BASE_FLAGS; + ac_test_setup_ptes(&at); + + err += do_cr0_wp_access(&at, 0); + err += do_cr0_wp_access(&at, AC_CPU_CR0_WP_MASK); + + return err == 0; +} + static int check_effective_sp_permissions(ac_pt_env_t *pt_env) { unsigned long ptr1 = 0xffff923480000000; @@ -1150,6 +1206,7 @@ const ac_test_fn ac_test_cases[] = check_pfec_on_prefetch_pte, check_large_pte_dirty_for_nowp, check_smep_andnot_wp, + check_toggle_cr0_wp, check_effective_sp_permissions, }; From patchwork Mon Apr 3 10:56:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Krause X-Patchwork-Id: 13198037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7882C77B60 for ; Mon, 3 Apr 2023 10:56:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231891AbjDCK4r (ORCPT ); Mon, 3 Apr 2023 06:56:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231644AbjDCK4k (ORCPT ); Mon, 3 Apr 2023 06:56:40 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 030F47294 for ; Mon, 3 Apr 2023 03:56:37 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id l12so28857929wrm.10 for ; Mon, 03 Apr 2023 03:56:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=grsecurity.net; s=grsec; t=1680519394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sPexPN8ih5rH0+fxHo4fd3sBIHWUHnjnfW2LV8nEB4Q=; b=KtAh2nx6LK/+MAymSXgHcdjNAaCAIwX6eqa0J2sQXzj8fcAOqPC0z9dqtBtGRlCgfR H/mzGZ3/8jTZrba2h77N4n1un5gKV22uNyPN/JdQaI2+4okfBgloltXPfJfCztiS6pWa /tYvW/9Zg4jachJPqDASiIyz0pcKIFbFX9kRMYvqf+PFYHg3Q/efkSGpdm6agJPgcGGE ELFCX850dV9y8iwN8g16TQ1kyS5pgSpe8sDtuhp935Mq4gC57pGo06RSiZ86SfAFDhCt eLYoehBV2PvFd1NfuoCIyc7qXqy/9nblQ5A+4bvN0Q8vO2c0r+xX5ElCVopKXA380bk7 7+vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680519394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sPexPN8ih5rH0+fxHo4fd3sBIHWUHnjnfW2LV8nEB4Q=; b=7TA7+UDI4KnsiIOU/d7SooScFUrVkI1J1n6NDJEKldLYo/olH4o9msazbLQnq4oCGi Zu3a62s66TL4gaYNKMmH6ocz3K5PqtCqqO3lwKNIgR+EtAZb32Vu2DpQ96XXyop/XvPU c6KkFf4oSbsWDuS5mRfp9TbbTTCYSDVoSpoiVWClnSwtI6A+mDLmHECfd59J/ew+qIaR 6anm4P3XO0t2G12nNqopivfVP52OXCVprw3wTBze7m9g8szolacZGh5G96OI/ujXgZ99 RNR9KMpnUrf3phOddKpsnQr2pPJxfrI/keb1f9USvjneinsKIc9m6eJm6iFkY8+aPckW o3gA== X-Gm-Message-State: AAQBX9fIPfg7TTjRD4tjdkNFDKu1vcnJupqBIzjFxvcK9gW2OqagTRfg WvIIIq9sHryRn3EGH93/JR4Imk03iLVtQjiahJtmEA== X-Google-Smtp-Source: AKy350bJGuWN4pk2OaBg0oPLi65JLM+nlNx1oFErHwf84duizutiMtZKI6AdBIzfdC2dPFuR/EGciQ== X-Received: by 2002:a05:6000:118f:b0:2e7:29f:b4 with SMTP id g15-20020a056000118f00b002e7029f00b4mr4653008wrx.67.1680519394755; Mon, 03 Apr 2023 03:56:34 -0700 (PDT) Received: from nuc.fritz.box (p200300f6af22160069a3c79c8928b176.dip0.t-ipconnect.de. [2003:f6:af22:1600:69a3:c79c:8928:b176]) by smtp.gmail.com with ESMTPSA id x6-20020a5d60c6000000b002dfca33ba36sm9483671wrt.8.2023.04.03.03.56.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 03:56:34 -0700 (PDT) From: Mathias Krause To: kvm@vger.kernel.org Cc: Sean Christopherson , Mathias Krause Subject: [kvm-unit-tests PATCH v3 3/4] x86/access: Forced emulation support Date: Mon, 3 Apr 2023 12:56:17 +0200 Message-Id: <20230403105618.41118-4-minipli@grsecurity.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230403105618.41118-1-minipli@grsecurity.net> References: <20230403105618.41118-1-minipli@grsecurity.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add support to enforce access tests to be handled by the emulator, if supported by KVM. Exclude it from the ac_test_exec() test, though, to not slow it down too much. Signed-off-by: Mathias Krause --- x86/access.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/x86/access.c b/x86/access.c index a01278451b96..674077297978 100644 --- a/x86/access.c +++ b/x86/access.c @@ -82,6 +82,13 @@ enum { AC_CPU_CR4_SMEP_BIT, AC_CPU_CR4_PKE_BIT, + NR_AC_TEST_FLAGS, + + /* + * synthetic flags follow, won't be exercised by ac_test_exec(). + */ + AC_FEP_BIT, + NR_AC_FLAGS }; @@ -121,6 +128,8 @@ enum { #define AC_CPU_CR4_SMEP_MASK (1 << AC_CPU_CR4_SMEP_BIT) #define AC_CPU_CR4_PKE_MASK (1 << AC_CPU_CR4_PKE_BIT) +#define AC_FEP_MASK (1 << AC_FEP_BIT) + const char *ac_names[] = { [AC_PTE_PRESENT_BIT] = "pte.p", [AC_PTE_ACCESSED_BIT] = "pte.a", @@ -152,6 +161,7 @@ const char *ac_names[] = { [AC_CPU_CR0_WP_BIT] = "cr0.wp", [AC_CPU_CR4_SMEP_BIT] = "cr4.smep", [AC_CPU_CR4_PKE_BIT] = "cr4.pke", + [AC_FEP_BIT] = "fep", }; static inline void *va(pt_element_t phys) @@ -396,7 +406,7 @@ static void ac_test_init(ac_test_t *at, unsigned long virt, ac_pt_env_t *pt_env) static int ac_test_bump_one(ac_test_t *at) { at->flags = ((at->flags | invalid_mask) + 1) & ~invalid_mask; - return at->flags < (1 << NR_AC_FLAGS); + return at->flags < (1 << NR_AC_TEST_FLAGS); } #define F(x) ((flags & x##_MASK) != 0) @@ -799,10 +809,13 @@ static int ac_test_do_access(ac_test_t *at) if (F(AC_ACCESS_TWICE)) { asm volatile ("mov $fixed2, %%rsi \n\t" - "mov (%[addr]), %[reg] \n\t" + "cmp $0, %[fep] \n\t" + "jz 1f \n\t" + KVM_FEP + "1: mov (%[addr]), %[reg] \n\t" "fixed2:" : [reg]"=r"(r), [fault]"=a"(fault), "=b"(e) - : [addr]"r"(at->virt) + : [addr]"r"(at->virt), [fep]"r"(F(AC_FEP)) : "rsi"); fault = 0; } @@ -823,9 +836,15 @@ static int ac_test_do_access(ac_test_t *at) "jnz 2f \n\t" "cmp $0, %[write] \n\t" "jnz 1f \n\t" - "mov (%[addr]), %[reg] \n\t" + "cmp $0, %[fep] \n\t" + "jz 0f \n\t" + KVM_FEP + "0: mov (%[addr]), %[reg] \n\t" "jmp done \n\t" - "1: mov %[reg], (%[addr]) \n\t" + "1: cmp $0, %[fep] \n\t" + "jz 0f \n\t" + KVM_FEP + "0: mov %[reg], (%[addr]) \n\t" "jmp done \n\t" "2: call *%[addr] \n\t" "done: \n" @@ -843,6 +862,7 @@ static int ac_test_do_access(ac_test_t *at) [write]"r"(F(AC_ACCESS_WRITE)), [user]"r"(F(AC_ACCESS_USER)), [fetch]"r"(F(AC_ACCESS_FETCH)), + [fep]"r"(F(AC_FEP)), [user_ds]"i"(USER_DS), [user_cs]"i"(USER_CS), [user_stack_top]"r"(user_stack + sizeof user_stack), @@ -1233,6 +1253,11 @@ int ac_test_run(int pt_levels) invalid_mask |= AC_PTE_BIT36_MASK; } + if (!is_fep_available()) { + printf("FEP not available, skipping emulation tests\n"); + invalid_mask |= AC_FEP_MASK; + } + ac_env_int(&pt_env, pt_levels); ac_test_init(&at, 0xffff923400000000ul, &pt_env); From patchwork Mon Apr 3 10:56:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Krause X-Patchwork-Id: 13198038 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F42BC76196 for ; Mon, 3 Apr 2023 10:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231844AbjDCK4s (ORCPT ); Mon, 3 Apr 2023 06:56:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231867AbjDCK4k (ORCPT ); Mon, 3 Apr 2023 06:56:40 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4ACE7AD04 for ; Mon, 3 Apr 2023 03:56:37 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id l27so28881839wrb.2 for ; Mon, 03 Apr 2023 03:56:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=grsecurity.net; s=grsec; t=1680519395; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Qj5ObJFyEiD8lPGnjnuXNDQhtwMJ0SLMCqhL+zNAU/Q=; b=gFZspbMY/cllAOmYDY/1ObHg7ar+yDqBuRkSHavHTmk/ilbCrAyF+a7WKw1bp15wLf Q9IYFOnsTM2q5bLyLw+TcjoCJeNTzHiT6Sox8ZadeIQ290lIew/TU9oI6AF+qICRLgcb cMdaoy0I6IO4dZumLLc4noN0/BCey5hXke32s0eWJGVAgjumk0MpmKo/zIZfzcxp+ibb iL27inZBOyipq9GTWg0j/6+EGLhDieZxclYKN1Agn4kjRiaDTaCMiUDEoRE1vHpQkZhb VY9Ob7K1UyycHPSbXA1N3xki4jdR14SnidPkhuTv2JIaI+/zXWuLqaVDeTf0s0lGoxJy EdQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680519395; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Qj5ObJFyEiD8lPGnjnuXNDQhtwMJ0SLMCqhL+zNAU/Q=; b=hhnfBZleuPtyqHFvvJL+/FxampKmHMwuVBHsSHdR0v0QjjRIix/+26ip4PwlKyIrFa sZ/2Yxfr/Hu3DA3goLS6rLEPxNfo2qx80NNFto/mYj9MegJ435gIaTAScU+DVoWs2Mwf r8FfYEHZd1oSxlMBwQ9ldT8bTQ3VLXwFp5hPF5XOIgg+M2ttY3bul6TMuo1Zn9lKXZkR sLgoXPGAVfwxexmBCf6v/ItwjnqLUIG9P4WJ9jciAcEvFCOLyfbRJyUXsceSpmNFCnKL NQQz0eGD4Bbox40DPJzrbUXjeLFn8Rw7dqT+BpUpNpcMObCKUMchAhXGBiY6q+ijbBIp wUsw== X-Gm-Message-State: AAQBX9dR/avizVEtJfAgM5hei2Hm48trXLLr9D/bcNNxfpvbaqqDzHjy qp7zqEnBtIWzM7cR8UvpnU5VXeeWzHy0mxYHnPsj7Q== X-Google-Smtp-Source: AKy350bDo+rJBMg4rZGrT9w891XR1E4LgRGcymNnw5f7dpyRokXYo+N7eo3A2T+o42co5+sz/e3T4Q== X-Received: by 2002:a5d:67cd:0:b0:2d7:babe:104c with SMTP id n13-20020a5d67cd000000b002d7babe104cmr25833176wrw.15.1680519395572; Mon, 03 Apr 2023 03:56:35 -0700 (PDT) Received: from nuc.fritz.box (p200300f6af22160069a3c79c8928b176.dip0.t-ipconnect.de. [2003:f6:af22:1600:69a3:c79c:8928:b176]) by smtp.gmail.com with ESMTPSA id x6-20020a5d60c6000000b002dfca33ba36sm9483671wrt.8.2023.04.03.03.56.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 03:56:35 -0700 (PDT) From: Mathias Krause To: kvm@vger.kernel.org Cc: Sean Christopherson , Mathias Krause Subject: [kvm-unit-tests PATCH v3 4/4] x86/access: Try emulation for CR0.WP test as well Date: Mon, 3 Apr 2023 12:56:18 +0200 Message-Id: <20230403105618.41118-5-minipli@grsecurity.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230403105618.41118-1-minipli@grsecurity.net> References: <20230403105618.41118-1-minipli@grsecurity.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- Instead of testing 'invalid_mask', I simply added yet another call to is_fep_available(). It's cleaner, IMO, as it's easier to grasp than '!(invalid_mask & AC_FEP_MASK)'. The additional exception doesn't influence the tests, as all preparation is done in do_cr0_wp_access(). x86/access.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/x86/access.c b/x86/access.c index 674077297978..eab3959bc871 100644 --- a/x86/access.c +++ b/x86/access.c @@ -1107,14 +1107,17 @@ static int do_cr0_wp_access(ac_test_t *at, int flags) * Load CR0.WP with the inverse value of what will be used during * the access test and toggle EFER.NX to coerce KVM into rebuilding * the current MMU context based on the soon-to-be-stale CR0.WP. + * + * This used to trigger a bug in the emulator, testable via FEP. */ set_cr0_wp(!cr0_wp); set_efer_nx(1); set_efer_nx(0); if (!ac_test_do_access(at)) { - printf("%s: supervisor write with CR0.WP=%d did not %s\n", - __FUNCTION__, cr0_wp, cr0_wp ? "FAULT" : "SUCCEED"); + printf("%s: %ssupervisor write with CR0.WP=%d did not %s\n", + __FUNCTION__, (flags & AC_FEP_MASK) ? "emulated " : "", + cr0_wp, cr0_wp ? "FAULT" : "SUCCEED"); return 1; } @@ -1133,6 +1136,10 @@ static int check_toggle_cr0_wp(ac_pt_env_t *pt_env) err += do_cr0_wp_access(&at, 0); err += do_cr0_wp_access(&at, AC_CPU_CR0_WP_MASK); + if (is_fep_available()) { + err += do_cr0_wp_access(&at, AC_FEP_MASK); + err += do_cr0_wp_access(&at, AC_FEP_MASK | AC_CPU_CR0_WP_MASK); + } return err == 0; }