From patchwork Thu May 26 21:08:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862793 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 AC6B4C433EF for ; Thu, 26 May 2022 21:24:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348633AbiEZVYV (ORCPT ); Thu, 26 May 2022 17:24:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348476AbiEZVYT (ORCPT ); Thu, 26 May 2022 17:24:19 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4142960069 for ; Thu, 26 May 2022 14:24:19 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id g69-20020a625248000000b00519150d186bso1476940pfb.18 for ; Thu, 26 May 2022 14:24:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=qcb34r8lBkv1bGkFkoJYhaFMYHoFB0Pd8gzL2lqLpkQ=; b=T2zruDflY/r2OIUodskEq7SMCOGDU5zIxLD6CKLlpC+X1tooGQxFlorAGyJySJiLcT BcnQsYeLkficbXY1grZaMSOthPCBy2G7UlNRMgaw3Fki/sHXjUDSydOFdzfhioLz6vax 4gHW6WF6P1CeKQeh8tEypLoVOrZhs4imn/tnXHLtiJtPtiOHluXDiIrjkY2f4TIIprjj YZQ+SkB3IFIn1h4C/asUwTVq0bKcWzu/4OEdoRTcStiO25m1gWa5ZjOfxfEhXAeSDusp IKml40YTsbiAdMUFSg2RxerihFBAvv7pjgmFfk+SnKpam8IBWV1VQ9BNzawlaSa5Rw7p SnbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=qcb34r8lBkv1bGkFkoJYhaFMYHoFB0Pd8gzL2lqLpkQ=; b=YqcGoYkJF+M1Enf0rolaIODvJNkU4qbSpNtUso4E9RaGss5+IG1upGJCpFmxbhKwMR 7sJDYc61UmLyshfCfyP8lXsT46HLuM00H9TWJN+cbAy9ri3CjttfRtnNiHbjczLu87d5 8tgL/MDmELUbSj2Y/aMZNvkMAT8Jqzuax0hObXd2Z2V580FHVioWjKlHO0r3fnYySxjy maQQqDKvNRGOH3jE9SC9osesTDh4Znn3INcJa6Z0X6t+uEVt+8PFrsHsm5IbH8HG2VFY tvLY166EbbesC7BbmSvWD88/RnqxCPqSn6WTtx2JYdsl/GFmlXiU2xMeJJTs/wSwd+jB xH8g== X-Gm-Message-State: AOAM532Xw2FQRpiY4iO6rUe2GSWFBfefMaF/XLe/+nFdreHpqpHHfopv EOMaZUjdsuuzKpw0QzKZwzYG3OCu1gY= X-Google-Smtp-Source: ABdhPJxAeFvGXx51xtaRc6ldC7mkeitVeSpk0Q3pavUjwHjAZWr2uqsYLQND033oUCn3RqxKULma6C2BFAg= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a62:6dc3:0:b0:505:895a:d38b with SMTP id i186-20020a626dc3000000b00505895ad38bmr40875071pfc.7.1653600258711; Thu, 26 May 2022 14:24:18 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:10 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-2-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 1/8] KVM: x86: Grab regs_dirty in local 'unsigned long' From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Capture ctxt->regs_dirty in a local 'unsigned long' instead of casting it to an 'unsigned long *' for use in for_each_set_bit(). The bitops helpers really do read the entire 'unsigned long', even though the walking of the read value is capped at the specified size. I.e. 64-bit KVM is reading memory beyond ctxt->regs_dirty, which is a u32 and thus 4 bytes, whereas an unsigned long is 8 bytes. Functionally it's not an issue because regs_dirty is in the middle of x86_emulate_ctxt, i.e. KVM is just reading its own memory, but relying on that coincidence is gross and unsafe. Reviewed-by: Vitaly Kuznetsov Reviewed-by: Kees Cook Signed-off-by: Sean Christopherson --- arch/x86/kvm/emulate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 89b11e7dca8a..7226a127ccb4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -269,9 +269,10 @@ static ulong *reg_rmw(struct x86_emulate_ctxt *ctxt, unsigned nr) static void writeback_registers(struct x86_emulate_ctxt *ctxt) { + unsigned long dirty = ctxt->regs_dirty; unsigned reg; - for_each_set_bit(reg, (ulong *)&ctxt->regs_dirty, 16) + for_each_set_bit(reg, &dirty, 16) ctxt->ops->write_gpr(ctxt, reg, ctxt->_regs[reg]); } From patchwork Thu May 26 21:08:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862795 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 B0575C433F5 for ; Thu, 26 May 2022 21:24:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349090AbiEZVYZ (ORCPT ); Thu, 26 May 2022 17:24:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229835AbiEZVYV (ORCPT ); Thu, 26 May 2022 17:24:21 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 028974C7AA for ; Thu, 26 May 2022 14:24:21 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id b20-20020a62a114000000b0050a6280e374so1484521pff.13 for ; Thu, 26 May 2022 14:24:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=Nj11sMCgQgDAP7C4SyDQj5semkrlbFX/aMEmua6TrWo=; b=K72D1I+pKpn91nJKzkfGAnssAW78lSoqkoj7q0Fsy0PcP782i5+XHpwQ+31nJDR/F5 T2ZQrkYnsoBofCYqYLMmMnYXnzYYVAEb5GSsjU+RSn6T+yYyL5K5PGhP15hyJvwlxtuK w3llFQUFkG5IomCwYNqArB0n3jnBFjQAsSzXClsbEumISzv2WFFx4zMofHOp8XqebpbP sbTmErvnivyyYdMEsHKht9i8830EY5MELCPHvwaaEp2G952pkNy796Ct4leLH56qcQhJ rBdNlJp6c/UI0ykSoDOUe4IdQBZkUQQhh8pRrSc2iBCwh40cRzGcB5O5BCQ0Jc0XMu52 tlBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=Nj11sMCgQgDAP7C4SyDQj5semkrlbFX/aMEmua6TrWo=; b=gf53jdzKZf598vwC343H/0z19s6P4k9oaoBCqPKb5uww8nAOfLjtQNfAB6pPSluw03 BiC/NLS3mpsthgmt35CZBDfidDGODyG+iNe2xl41sNl4I9i+paqnE3WJWA6wF01G2Xeo vY834d/8VwdfXYPJi3K762T/kn2eZcMJjXOpQVpNEDuAMe5TGDkgZTLNWSHdKG+DbdGM v2m6ewDNFPkcz1rGNg6a2RIW8kilLnK+ztL16OZsDMzdx1H6uRyVFTwpCHevPRRHSNL4 vaYI+V4Jj2z8Zk0MVFw6XQhihvp1c8m4i8V/DJy9JmYiiqVL+6Nr1OSA0fE8sRwSAPYe ZxIA== X-Gm-Message-State: AOAM5337FWOdtvFrzwnB51+COvA8qGBEOej1Y5W+a3rIKluxg2/6oBNR UYFutqz/JC3YouYATDOGhQfwQBP1L+M= X-Google-Smtp-Source: ABdhPJxE9wmASbPgNq1RmxvCK1+awZBzuRGIk5dOXG8m86UEZH9YhpSnNSvR3YNCfYA8r7EWuS14TcECFl4= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:c612:b0:161:e095:8ff6 with SMTP id r18-20020a170902c61200b00161e0958ff6mr37012728plr.145.1653600260466; Thu, 26 May 2022 14:24:20 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:11 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-3-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 2/8] KVM: x86: Harden _regs accesses to guard against buggy input From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org WARN and truncate the incoming GPR number/index when reading/writing GPRs in the emulator to guard against KVM bugs, e.g. to avoid out-of-bounds accesses to ctxt->_regs[] if KVM generates a bogus index. Truncate the index instead of returning e.g. zero, as reg_write() returns a pointer to the register, i.e. returning zero would result in a NULL pointer dereference. KVM could also force the index to any arbitrary GPR, but that's no better or worse, just different. Open code the restriction to 16 registers; RIP is handled via _eip and should never be accessed through reg_read() or reg_write(). See the comments above the declarations of reg_read() and reg_write(), and the behavior of writeback_registers(). The horrific open coded mess will be cleaned up in a future commit. There are no such bugs known to exist in the emulator, but determining that KVM is bug-free is not at all simple and requires a deep dive into the emulator. The code is so convoluted that GCC-12 with the recently enable -Warray-bounds spits out a false-positive due to a GCC bug: arch/x86/kvm/emulate.c:254:27: warning: array subscript 32 is above array bounds of 'long unsigned int[17]' [-Warray-bounds] 254 | return ctxt->_regs[nr]; | ~~~~~~~~~~~^~~~ In file included from arch/x86/kvm/emulate.c:23: arch/x86/kvm/kvm_emulate.h: In function 'reg_rmw': arch/x86/kvm/kvm_emulate.h:366:23: note: while referencing '_regs' 366 | unsigned long _regs[NR_VCPU_REGS]; | ^~~~~ Link: https://lore.kernel.org/all/YofQlBrlx18J7h9Y@google.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=216026 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105679 Reported-and-tested-by: Robert Dinse Reported-by: Kees Cook Reviewed-by: Kees Cook Signed-off-by: Sean Christopherson --- arch/x86/kvm/emulate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7226a127ccb4..c58366ae4da2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -247,6 +247,9 @@ enum x86_transfer_type { static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { + if (WARN_ON_ONCE(nr >= 16)) + nr &= 16 - 1; + if (!(ctxt->regs_valid & (1 << nr))) { ctxt->regs_valid |= 1 << nr; ctxt->_regs[nr] = ctxt->ops->read_gpr(ctxt, nr); @@ -256,6 +259,9 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { + if (WARN_ON_ONCE(nr >= 16)) + nr &= 16 - 1; + ctxt->regs_valid |= 1 << nr; ctxt->regs_dirty |= 1 << nr; return &ctxt->_regs[nr]; From patchwork Thu May 26 21:08:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862797 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 AEF25C433EF for ; Thu, 26 May 2022 21:24:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349139AbiEZVY3 (ORCPT ); Thu, 26 May 2022 17:24:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348989AbiEZVYY (ORCPT ); Thu, 26 May 2022 17:24:24 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F7E669494 for ; Thu, 26 May 2022 14:24:22 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id gn21-20020a17090ac79500b001dc8a800410so3841466pjb.0 for ; Thu, 26 May 2022 14:24:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=PHlgII++2wIvs6hDrvRGyxpTlkYLyG2XZsv/tF8ktec=; b=EjR3CvFdD4qmlvt2dipOIuLCgt9cB3TxZLX5sW8gDxj1N8MgeukB2KSfi/Wd5x2+3V ltKUp9vKh5QUHtlVZ4NMPI7aQyK2f51a/p7hIlK/d7diGjA53aQbgMavD+zhUrHOO0C1 Pt9YMGdQFMlHSSwSNmsczu0nbjX2665XijE+VPVJC7Vt2xvRxPs3wGR3Kw0a3t2mxYNV lL2QIM1nxqtarHU6Ruu98837OKk+1fSmEaVbICbmvZM6u5uVP8jpu8iMqnnx4Z4Y+Lx8 HLSvHmSilB4NSH9tWVJDVmWMJoNQUF1qT7JYLFzMHc7ANM2c5oR7ZSB2U9NsuXPbjG2j KszQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=PHlgII++2wIvs6hDrvRGyxpTlkYLyG2XZsv/tF8ktec=; b=ejk6Qr6SnyplSFYtT9Q3epQLYmlPYPJIO39pxoLaj+Ikg5zu2K10VMAgFvt7p4nQ6l EPN0agSDlfMhgbEV7+eNqPBQCsLdGS0Ry/4raqicbeeS407DGAdrf14RzJu/BZIrYh02 IDMLt6zu/nR7UcJVqDEvKLVhwG0Q0GH4ursbfMN8xVkrltmp1LsZ4u6k9wJknb4/mT0e HBOEuoVFQ7VZxmTCptrA+MYgoJc2SpgTc/SvZF8m4EuP4KgwKgVPlF0L7Opu0z6Tuf+b 9b5rIpHn/2FfEGw2lgUKGPez9FjrjisfD7gjlIxN13hs2RLVj+xWpTMHspL/vekwZoTp oW5g== X-Gm-Message-State: AOAM531kWtwE+QyYw63TK17oQGYPJ9mQ4y9VjRZ094xsvjZyFfO24tCt 60jdFyc56BrrsqdxmkAinatAaGO5eX8= X-Google-Smtp-Source: ABdhPJw/ccwDmeY7jf7RVD+CTb+pd3p8Uic7RhBWSbMGkZIbC9D4edge/H18CR7gVRPN4L8jAPWVcX7Knck= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a63:86c7:0:b0:3fb:a6ea:b73a with SMTP id x190-20020a6386c7000000b003fba6eab73amr367971pgd.510.1653600262128; Thu, 26 May 2022 14:24:22 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:12 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-4-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 3/8] KVM: x86: Omit VCPU_REGS_RIP from emulator's _regs array From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Omit RIP from the emulator's _regs array, which is used only for GPRs, i.e. registers that can be referenced via ModRM and/or SIB bytes. The emulator uses the dedicated _eip field for RIP, and manually reads from _eip to handle RIP-relative addressing. To avoid an even bigger, slightly more dangerous change, hardcode the number of GPRs to 16 for the time being even though 32-bit KVM's emulator technically should only have 8 GPRs. Add a TODO to address that in a future commit. See also the comments above the read_gpr() and write_gpr() declarations, and obviously the handling in writeback_registers(). No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook --- arch/x86/kvm/emulate.c | 10 +++++----- arch/x86/kvm/kvm_emulate.h | 13 ++++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c58366ae4da2..c74c0fd3b860 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -247,8 +247,8 @@ enum x86_transfer_type { static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >= 16)) - nr &= 16 - 1; + if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS)) + nr &= NR_EMULATOR_GPRS - 1; if (!(ctxt->regs_valid & (1 << nr))) { ctxt->regs_valid |= 1 << nr; @@ -259,8 +259,8 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >= 16)) - nr &= 16 - 1; + if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS)) + nr &= NR_EMULATOR_GPRS - 1; ctxt->regs_valid |= 1 << nr; ctxt->regs_dirty |= 1 << nr; @@ -278,7 +278,7 @@ static void writeback_registers(struct x86_emulate_ctxt *ctxt) unsigned long dirty = ctxt->regs_dirty; unsigned reg; - for_each_set_bit(reg, &dirty, 16) + for_each_set_bit(reg, &dirty, NR_EMULATOR_GPRS) ctxt->ops->write_gpr(ctxt, reg, ctxt->_regs[reg]); } diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 8dff25d267b7..bc3f8295c8c8 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -301,6 +301,17 @@ struct fastop; typedef void (*fastop_t)(struct fastop *); +/* + * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP. RIP is + * tracked/accessed via _eip, and except for RIP relative addressing, which + * also uses _eip, RIP cannot be a register operand nor can it be an operand in + * a ModRM or SIB byte. + * + * TODO: this is technically wrong for 32-bit KVM, which only supports 8 GPRs; + * R8-R15 don't exist. + */ +#define NR_EMULATOR_GPRS 16 + struct x86_emulate_ctxt { void *vcpu; const struct x86_emulate_ops *ops; @@ -363,7 +374,7 @@ struct x86_emulate_ctxt { struct operand src2; struct operand dst; struct operand memop; - unsigned long _regs[NR_VCPU_REGS]; + unsigned long _regs[NR_EMULATOR_GPRS]; struct operand *memopp; struct fetch_cache fetch; struct read_cache io_read; From patchwork Thu May 26 21:08:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862796 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 6FE39C433FE for ; Thu, 26 May 2022 21:24:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345240AbiEZVY2 (ORCPT ); Thu, 26 May 2022 17:24:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349062AbiEZVYZ (ORCPT ); Thu, 26 May 2022 17:24:25 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8AE2C5F27A for ; Thu, 26 May 2022 14:24:24 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id j13-20020a170902da8d00b00161d78a9e3eso1678820plx.17 for ; Thu, 26 May 2022 14:24:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=+ARLUoQErvE10R5Z3P5YbADKHrFc+h+h9fYwAe9gqkQ=; b=P1O1m4A5QB3PkqYRhvWgKI3trzoLpiD17Kap9u1Ntf7VXNNt1LmTVq0xans+HuPbwP mrMXwad+SEnBrc5v+SdXuwL7TfEDMDuy3jr82opB5JprY8fpDve5pmyhw/qPJ5KCyALt rFJ5C02+GK3Um1cpjhCZFsMdja3ACtm7xaEK2uFGIcSrATj61okbfsKEv/q9Q2V0qgcE 8XbzvEcswTakOhChRP0G2ohPJDooOxl1wJ3oRkV0+YniNUu3+5oXZwertnhEL7elo276 CFUTe0QOajucWkgSzuSbC60D7gFaNKbeIkXJgjThxp8libH4wQFoylreajXaLkiXjahY loeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=+ARLUoQErvE10R5Z3P5YbADKHrFc+h+h9fYwAe9gqkQ=; b=gL19QHvaxtvJDILZ3CxJESv/thKdvEokbQxHbA1DpBji6H0Fdx+QO+6VqMjyEOQoXw FDdk8peDVAIgYt4G6wsvNq0JsPbuf2AfAWeKpUOKD7RWlnrgJsfmFsLO7EUKkGOy98Yg jWZivlAcnG36qXWovGZdEg5J4UuBlctIFtB5zGGzRq7gk2vq/OcO+Xkz4aDEz9xf0FeD 4LllqLoPS0YsZDiKmexwpPaBeDha/FWDydOOqcnd/GTMnCkPNQEI0b0GRMQgw/Vraauy dq5Kq/w8dV6KpWpI4bL5la1SUq2+fQYKL0M/ML3UlymIzoHSCUN4Wb8yBx4cIfw7u6NV smsg== X-Gm-Message-State: AOAM530xKngCd2bV3Tf+HuYh59RDv5eqJObDG20Wl6VpKqGd8ls5eyFY 0lJkI/2GNTFmyajtjFDnt0yOvovdQXo= X-Google-Smtp-Source: ABdhPJw0nK+wAhiONzhiRIha9jnwWLcnJmVTgMO2zOQF0Ko9glHAJQlpshUO38CIPt2CWi406/F7XXICRcc= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a62:e819:0:b0:518:6a98:b02 with SMTP id c25-20020a62e819000000b005186a980b02mr34100356pfi.74.1653600263944; Thu, 26 May 2022 14:24:23 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:13 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-5-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 4/8] KVM: x86: Use 16-bit fields to track dirty/valid emulator GPRs From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Use a u16 instead of a u32 to track the dirty/valid status of GPRs in the emulator. Unlike struct kvm_vcpu_arch, x86_emulate_ctxt tracks only the "true" GPRs, i.e. doesn't include RIP in its array, and so only needs to track 16 registers. Note, maxing out at 16 GPRs is a fundamental property of x86-64 and will not change barring a massive architecture update. Legacy x86 ModRM and SIB encodings use 3 bits for GPRs, i.e. support 8 registers. x86-64 uses a single bit in the REX prefix for each possible reference type to double the number of supported GPRs to 16 registers (4 bits). Reviewed-by: Kees Cook Signed-off-by: Sean Christopherson --- arch/x86/kvm/emulate.c | 3 +++ arch/x86/kvm/kvm_emulate.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c74c0fd3b860..5aaf1d1200af 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -262,6 +262,9 @@ static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS)) nr &= NR_EMULATOR_GPRS - 1; + BUILD_BUG_ON(sizeof(ctxt->regs_dirty) * BITS_PER_BYTE < NR_EMULATOR_GPRS); + BUILD_BUG_ON(sizeof(ctxt->regs_valid) * BITS_PER_BYTE < NR_EMULATOR_GPRS); + ctxt->regs_valid |= 1 << nr; ctxt->regs_dirty |= 1 << nr; return &ctxt->_regs[nr]; diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index bc3f8295c8c8..3a65d6ea7fe6 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -356,9 +356,9 @@ struct x86_emulate_ctxt { u8 lock_prefix; u8 rep_prefix; /* bitmaps of registers in _regs[] that can be read */ - u32 regs_valid; + u16 regs_valid; /* bitmaps of registers in _regs[] that have been written */ - u32 regs_dirty; + u16 regs_dirty; /* modrm */ u8 modrm; u8 modrm_mod; From patchwork Thu May 26 21:08:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862798 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 74617C433EF for ; Thu, 26 May 2022 21:24:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235823AbiEZVYf (ORCPT ); Thu, 26 May 2022 17:24:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239874AbiEZVY1 (ORCPT ); Thu, 26 May 2022 17:24:27 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 180F99D06C for ; Thu, 26 May 2022 14:24:26 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id on14-20020a17090b1d0e00b001c7a548e4f7so3903584pjb.2 for ; Thu, 26 May 2022 14:24:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=vRAWGApnZo9PQoKSv+ZEImJz7U3HwflIO0rVPe9gUZU=; b=AuzYwvO+aFV3coHvl7K8KwGsYi6DGC0TkiEteCchpLesVODaU452xnHzHBJREb8Jbr 2aGV5xDy4pWsobXF7xO2yRHmoYLNtJKJHnYJ0V8UmMwip981d7pD4jNF5vhqtUmPkWr4 eANCrVZAUXZ7ZVOwzKTVdyHTRsMc12HjplmVvqUV46xFfqIlLNQ36TqSDqNAOBC9PlfQ QAsOKQQYg6EuAwHZMGFY5tJ7OmiP18H5E5XVSklljJ8wBLIv1H3mddfjE5lAbGyBwIdA lsJ2mXx4v/foETyFGjPDoN034bzZSwe+07TXR+9mvhmv0gVRQ6+3Pn9X5QkAeXGAFF5S pelA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=vRAWGApnZo9PQoKSv+ZEImJz7U3HwflIO0rVPe9gUZU=; b=xqk9/QYCjmX6Tfa8D4atIi25Nu2Z83ap5D2GKl2dlrdE5PcejRMbAPLEA65+4uuIH+ DEYol3VpLDpQZern+17WyDYqBM3agnExZGPL0umOHp5qHjIKWqbuq2rNnQhcNbkXUENr d/mYo17eBmAN9j7iv8GGQg6j+XIdwo/pylWw78FgRwDbMrZTtyIPfNQDG07Lqoh5Pmyv GbIX14BV5MNuGsaihL7LLnigXO0KXUrakPosoeY6+9oRqTMQMjObyLS/5czdF0BqHnbB oa+X5edyuoo64BpSJAAIuE0dTr2c080n7hJGajTx/8RK9IaiQEMZogVyViU+0tBe4R+a iPOg== X-Gm-Message-State: AOAM5305rk/vefZb6wGqEpuS+8kWs6oxpl8u4Se9sBPRH1/mZRvHZZbI JYHkJ0ehWK15YzpJV/aelnUssJsHxVI= X-Google-Smtp-Source: ABdhPJyvAr6xUQFYgm5WV3rKJQ4tk4S5ntWPyBHIlSXKk1BBeLTAu2f6WznnIhnvLiAHU4OPrsZPctfEhSM= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a65:6bce:0:b0:3f2:5f88:6f7d with SMTP id e14-20020a656bce000000b003f25f886f7dmr34957881pgw.253.1653600265524; Thu, 26 May 2022 14:24:25 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:14 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-6-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 5/8] KVM: x86: Reduce the number of emulator GPRs to '8' for 32-bit KVM From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Reduce the number of GPRs emulated by 32-bit KVM from 16 to 8. KVM does not support emulating 64-bit mode on 32-bit host kernels, and so should never generate accesses to R8-15. Opportunistically use NR_EMULATOR_GPRS in rsm_load_state_{32,64}() now that it is precise and accurate for both flavors. Wrap the definition with full #ifdef ugliness; sadly, IS_ENABLED() doesn't guarantee a compile-time constant as far as BUILD_BUG_ON() is concerned. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook --- arch/x86/kvm/emulate.c | 4 ++-- arch/x86/kvm/kvm_emulate.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5aaf1d1200af..77161f57c8d3 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2441,7 +2441,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED; ctxt->_eip = GET_SMSTATE(u32, smstate, 0x7ff0); - for (i = 0; i < 8; i++) + for (i = 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); val = GET_SMSTATE(u32, smstate, 0x7fcc); @@ -2498,7 +2498,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u16 selector; int i, r; - for (i = 0; i < 16; i++) + for (i = 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8); ctxt->_eip = GET_SMSTATE(u64, smstate, 0x7f78); diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 3a65d6ea7fe6..034c845b3c63 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -306,11 +306,12 @@ typedef void (*fastop_t)(struct fastop *); * tracked/accessed via _eip, and except for RIP relative addressing, which * also uses _eip, RIP cannot be a register operand nor can it be an operand in * a ModRM or SIB byte. - * - * TODO: this is technically wrong for 32-bit KVM, which only supports 8 GPRs; - * R8-R15 don't exist. */ +#ifdef CONFIG_X86_64 #define NR_EMULATOR_GPRS 16 +#else +#define NR_EMULATOR_GPRS 8 +#endif struct x86_emulate_ctxt { void *vcpu; From patchwork Thu May 26 21:08:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862799 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 EA4ACC433FE for ; Thu, 26 May 2022 21:24:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349195AbiEZVYn (ORCPT ); Thu, 26 May 2022 17:24:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349174AbiEZVYd (ORCPT ); Thu, 26 May 2022 17:24:33 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80F79E731B for ; Thu, 26 May 2022 14:24:28 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2f7dbceab08so23185267b3.10 for ; Thu, 26 May 2022 14:24:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=v3CqCwLu207sw0GXSofBe8WSdEvT1VmqfkxogyjcNu0=; b=CROY8wgPYt/QN4wVpxCf+acAp5/1J2MFvYsgfk2a8xMRi00okIaGJrHRap54YmorIy zIc4GGHJS9bzqlz98B5dUqDfN/aKPwesQgmWIDu/vKJfMoL8EQlZYsc/NSSVA+Hehi4r 9RVAi4eAeJiWr6p+EiC0AtRvSEG/Piqsb2bkYKULUJHdXE05q2O5qJ3U+QSJbXNJHZDW YVh0GHIz35VhiOjP+aLn1t+6k2v594qyu3RPj2g9SjcRIRcvkzm9GmpBgLHOGtXViplO X33SiVo/xTm753U5GmtpWqJmQndVyCxTNmHX1s6AcZOHsBrbQ65zhTGqHsQB2NfPxQod dhPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=v3CqCwLu207sw0GXSofBe8WSdEvT1VmqfkxogyjcNu0=; b=I5muT66qRiQl7gDxHJcmwCHbeHWUHzznnTjqog7xMn7uNFqE36l8/y1L5z02H5Szfy n67fSilLVTAaxIk0xAmhNzii/lhqu1F0bOjHmGUz+LhNKTPlghyMdoCwtIbF9VWfBhkt Nn4INyEDPfmWMsqWhFrrkqJ+hV5Ri1HmwVP2GaDZn3d9NJb9NLt17nuTK8maeuelIz1o vdXxYCQK42BqZ0LK2rsiXt8ncw0oXgWDjdLVpBYRGhDVvFFKW16t9jD68PFwZSVs0Tob 2ScxIl5OrSjOkYE44alEcNlo3ygt0BxRhpFejiOzIrcoTFrOf2i9XnuNd8jXvCNT33OG k+GA== X-Gm-Message-State: AOAM531sonmpO2vEbdHJX52UN+D09rxmDZI8EESnE8biMxqhu92zdMb9 gm1e9qBG8haF5ynClc+ISRQn9hEuT2g= X-Google-Smtp-Source: ABdhPJzyOrxr5ivAn4As2fM0HXaXv+5iCh+M5Mi7bj9R/MWAkeKBLhyvHaMvSLhc2V0BxcDiao0TbwBrj+A= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a25:4546:0:b0:655:845b:f3df with SMTP id s67-20020a254546000000b00655845bf3dfmr11137880yba.624.1653600267235; Thu, 26 May 2022 14:24:27 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:15 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-7-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 6/8] KVM: x86: Bug the VM if the emulator accesses a non-existent GPR From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Bug the VM, i.e. kill it, if the emulator accesses a non-existent GPR, i.e. generates an out-of-bounds GPR index. Continuing on all but gaurantees some form of data corruption in the guest, e.g. even if KVM were to redirect to a dummy register, KVM would be incorrectly read zeros and drop writes. Note, bugging the VM doesn't completely prevent data corruption, e.g. the current round of emulation will complete before the vCPU bails out to userspace. But, the very act of killing the guest can also cause data corruption, e.g. due to lack of file writeback before termination, so taking on additional complexity to cleanly bail out of the emulator isn't justified, the goal is purely to stem the bleeding and alert userspace that something has gone horribly wrong, i.e. to avoid _silent_ data corruption. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook Reviewed-by: Vitaly Kuznetsov --- arch/x86/kvm/emulate.c | 4 ++-- arch/x86/kvm/kvm_emulate.h | 10 ++++++++++ arch/x86/kvm/x86.c | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 77161f57c8d3..70a8e0cd9fdc 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -247,7 +247,7 @@ enum x86_transfer_type { static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS)) + if (KVM_EMULATOR_BUG_ON(nr >= NR_EMULATOR_GPRS, ctxt)) nr &= NR_EMULATOR_GPRS - 1; if (!(ctxt->regs_valid & (1 << nr))) { @@ -259,7 +259,7 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS)) + if (KVM_EMULATOR_BUG_ON(nr >= NR_EMULATOR_GPRS, ctxt)) nr &= NR_EMULATOR_GPRS - 1; BUILD_BUG_ON(sizeof(ctxt->regs_dirty) * BITS_PER_BYTE < NR_EMULATOR_GPRS); diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 034c845b3c63..89246446d6aa 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -89,6 +89,7 @@ struct x86_instruction_info { #define X86EMUL_INTERCEPTED 6 /* Intercepted by nested VMCB/VMCS */ struct x86_emulate_ops { + void (*vm_bugged)(struct x86_emulate_ctxt *ctxt); /* * read_gpr: read a general purpose register (rax - r15) * @@ -383,6 +384,15 @@ struct x86_emulate_ctxt { bool is_branch; }; +#define KVM_EMULATOR_BUG_ON(cond, ctxt) \ +({ \ + int __ret = (cond); \ + \ + if (WARN_ON_ONCE(__ret)) \ + ctxt->ops->vm_bugged(ctxt); \ + unlikely(__ret); \ +}) + /* Repeat String Operation Prefix */ #define REPE_PREFIX 0xf3 #define REPNE_PREFIX 0xf2 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7460b9a77d9a..e60badfbbc42 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7887,7 +7887,16 @@ static int emulator_set_xcr(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr) return __kvm_set_xcr(emul_to_vcpu(ctxt), index, xcr); } +static void emulator_vm_bugged(struct x86_emulate_ctxt *ctxt) +{ + struct kvm *kvm = emul_to_vcpu(ctxt)->kvm; + + if (!kvm->vm_bugged) + kvm_vm_bugged(kvm); +} + static const struct x86_emulate_ops emulate_ops = { + .vm_bugged = emulator_vm_bugged, .read_gpr = emulator_read_gpr, .write_gpr = emulator_write_gpr, .read_std = emulator_read_std, From patchwork Thu May 26 21:08:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862800 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 0C70CC433EF for ; Thu, 26 May 2022 21:24:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348392AbiEZVYq (ORCPT ); Thu, 26 May 2022 17:24:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349184AbiEZVYd (ORCPT ); Thu, 26 May 2022 17:24:33 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9611AE8B82 for ; Thu, 26 May 2022 14:24:29 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id b20-20020a62a114000000b0050a6280e374so1484521pff.13 for ; Thu, 26 May 2022 14:24:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=yRrqKfhB5+m3QmsLeXBaT/5o9hpC8Ubit1ecnTTsekU=; b=lsgx9HK0wPTF3d3oLuZSwn2QvIXYw7zGXYU/qK+/MCKvUxHdMKonxc+4ZAI5gXX3At hZWh6YSpu2kFwSJxMiWyYxW4o2lMk3zH93qR+BQh+a6cvq5p+JEeeCoZYrbDZ0XKVHhi bRp8VGk2WbRyqeil3jdolhmHL2V683AYIECZMDKNIasbtmly1txRKFRxKHs//c6+cU9O CuMayZC96EUsuLCAwjB+Vl8L3+afQkUS91zpda9vYKJ5nvFquoyE0UXKw6UZG05k0Xw8 juausBaUpbBHS6kE8sNFO8pwRDpKO0Jxqr/o/DbiyDtJlVQJbgQ12W+k4dHjM+/lXhCi 56jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=yRrqKfhB5+m3QmsLeXBaT/5o9hpC8Ubit1ecnTTsekU=; b=Vvq8hFG15aCkt00WyslTjq8+usn5cSgZ3LWZekaoqsIiyJvlflxlFMpg/6dGaX7Thv NMmMcnW9ImfquKZPx4HRJ40ts7x2aqmXlYrEu9UGWrRIKgMngQvfe51zhJ26rrm+NPPp R5/WyTCFQJC4rYR1IIqfcGXpNBdf3bFsAm0vSe2NzzP+XOgAOWTzqLMcezjthYTSAvtB lWAE5ba7iwJ+3rcDWf9/XIolz5xJ06hrTPIJsORqH1hrSWUAC4THfbMBC8wIxrF5000o 5Jc+2jegU3spGy57XX2ZWfwbi4Zea+6JxYEQ16ZmoGw/rL9f5aoOdJbQ+JpeTFgI90Xt jLHQ== X-Gm-Message-State: AOAM5314zPora9h8g6X1qXOjdEK4A3SaClArAJGIdoRPI1x5Sc724d3q RQ1dbymRgyxdoyX7xqN0PWC/Z+5NV6w= X-Google-Smtp-Source: ABdhPJyQ9jXsajtTuovYsAdXjyK+leKO3tYRFooS2NToE+scEfyRfA0JXUwXmnW1/Sh99NOkWmbBlpuKCuQ= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a65:5188:0:b0:3fa:6081:7393 with SMTP id h8-20020a655188000000b003fa60817393mr17689624pgq.72.1653600269102; Thu, 26 May 2022 14:24:29 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:16 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-8-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 7/8] KVM: x86: Bug the VM if the emulator generates a bogus exception vector From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Bug the VM if KVM's emulator attempts to inject a bogus exception vector. The guest is likely doomed even if KVM continues on, and propagating a bad vector to the rest of KVM runs the risk of breaking other assumptions in KVM and thus triggering a more egregious bug. All existing users of emulate_exception() have hardcoded vector numbers (__load_segment_descriptor() uses a few different vectors, but they're all hardcoded), and future users are likely to follow suit, i.e. the change to emulate_exception() is a glorified nop. As for the ctxt->exception.vector check in x86_emulate_insn(), the few known times the WARN has been triggered in the past is when the field was not set when synthesizing a fault, i.e. for all intents and purposes the check protects against consumption of uninitialized data. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook Reviewed-by: Vitaly Kuznetsov --- arch/x86/kvm/emulate.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 70a8e0cd9fdc..2aa17462a9ac 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -624,7 +624,9 @@ static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg) static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec, u32 error, bool valid) { - WARN_ON(vec > 0x1f); + if (KVM_EMULATOR_BUG_ON(vec > 0x1f, ctxt)) + return X86EMUL_UNHANDLEABLE; + ctxt->exception.vector = vec; ctxt->exception.error_code = error; ctxt->exception.error_code_valid = valid; @@ -5728,7 +5730,8 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) done: if (rc == X86EMUL_PROPAGATE_FAULT) { - WARN_ON(ctxt->exception.vector > 0x1f); + if (KVM_EMULATOR_BUG_ON(ctxt->exception.vector > 0x1f, ctxt)) + return EMULATION_FAILED; ctxt->have_exception = true; } if (rc == X86EMUL_INTERCEPTED) From patchwork Thu May 26 21:08:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12862801 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 3A431C433EF for ; Thu, 26 May 2022 21:25:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235256AbiEZVY6 (ORCPT ); Thu, 26 May 2022 17:24:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349149AbiEZVYe (ORCPT ); Thu, 26 May 2022 17:24:34 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24D2F644D9 for ; Thu, 26 May 2022 14:24:31 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id i19-20020aa79093000000b0050d44b83506so1472179pfa.22 for ; Thu, 26 May 2022 14:24:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=sjrWadd+U6s3AE9OlHKd1vSx1dK7nsNaDjQLzkoUXcg=; b=TQVt0Vq76cHTUEa2X6kDVHu+UhrNE6fY2WluDwgnGkC5IRYf796KPXGLhfr04Uy3YZ 6kBFEBE021obJjvVQEwo/PWkRY+xLg5Z1XpTssEYByESOvro3h2/ts3s+hfAVhsAxFqn 70IeBknD328cT/+s0eWCstTi2PBxxkLVBD6skaLODHTTWc58vzrIeMni8h4pEEr6iTFW fYzf6XTbKN6Lm9Kpw+ZG4tbsdEOKBd9GJnzIMzKjvgGXsggp+y8oQBokLA70b8+BylEg 52jqDFIsfdKJVhJIl/iRCeWIcuUWUmsp1vtPsMFHjg7HQGHRRO/QCD7qildWl4DVyUWm M7OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=sjrWadd+U6s3AE9OlHKd1vSx1dK7nsNaDjQLzkoUXcg=; b=Z75OuJkvzp7VA9DqowgOfCOq2dsYC4RgUIQEczL0xxFlIKjeOxamnL3UGLdBQosZSN dDpN4BjWHAmbEMdJj+EX73TysEGZpqPn+XADUNxZRgw0CSejRquaeG9zZ0ssqKA/eC2W D4qMIGSEDHARCy9HGZEFu6c6+OL65yuq38J02rF06IDlfA4QE0NccK/vj23+HDiQDiOL 215qzZdrPitka2poIwm0VXRVq5qzKnBPHchPe4aI+RgXxiFHdPrglDuprLAVAOI9M7MB t5ouiqalzYpM/17iSm9stX3jKnETcIwoUKCQFS3tBdPdtj5AnaTqxhdg0lsdcj0TTBPO BOiQ== X-Gm-Message-State: AOAM531Ih4d+FULBTZNxIO6tCcInIFr8PeuSlu+x9ILoN7AsObViaiJW nCdKqTR5FOPEMtX8Xu5cMBHYQ3QTnOo= X-Google-Smtp-Source: ABdhPJx8M0VoHr57nLlA/sX8zTDrVXkgT1bsVM9bmwFgKG11EQvIc6zvT1j59UbsqyEBKS3z3uAnVG+SZ80= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a62:e819:0:b0:518:6a98:b02 with SMTP id c25-20020a62e819000000b005186a980b02mr34100732pfi.74.1653600270603; Thu, 26 May 2022 14:24:30 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 26 May 2022 21:08:17 +0000 In-Reply-To: <20220526210817.3428868-1-seanjc@google.com> Message-Id: <20220526210817.3428868-9-seanjc@google.com> Mime-Version: 1.0 References: <20220526210817.3428868-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.255.ge46751e96f-goog Subject: [PATCH v2 8/8] KVM: x86: Bug the VM on an out-of-bounds data read From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kees Cook , Robert Dinse Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Bug the VM and terminate emulation if an out-of-bounds read into the emulator's data cache occurs. Knowingly contuining on all but guarantees that KVM will overwrite random kernel data, which is far, far worse than killing the VM. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook Reviewed-by: Vitaly Kuznetsov --- arch/x86/kvm/emulate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2aa17462a9ac..39ea9138224c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1373,7 +1373,8 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt, if (mc->pos < mc->end) goto read_cached; - WARN_ON((mc->end + size) >= sizeof(mc->data)); + if (KVM_EMULATOR_BUG_ON((mc->end + size) >= sizeof(mc->data), ctxt)) + return X86EMUL_UNHANDLEABLE; rc = ctxt->ops->read_emulated(ctxt, addr, mc->data + mc->end, size, &ctxt->exception);