From nobody Tue Apr 28 23:19:20 2026 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 DF405C433EF for ; Thu, 26 May 2022 21:24:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349037AbiEZVYY (ORCPT ); Thu, 26 May 2022 17:24:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245759AbiEZVYT (ORCPT ); Thu, 26 May 2022 17:24:19 -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 378EE5F252 for ; Thu, 26 May 2022 14:24:19 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id i4-20020a17090a718400b001e09f0af976so1629961pjk.9 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=x3pruN6apF13Sh/8QKyT0oiSB71dQrjjtFhjFs5tsYuAo8qd+lZzwEnrPry6CU57uK 5jkSjG5S2zSAEtQxEbx0S4rv5TGyvTorrWHoyGiGyHBb18T3G0HO/nXAP5dk9dN45b8Y EoLzVWZAX3dDEZVXfnMonbXJlfh9AQoiTdyRN5T0Q6ERPv6c1XlTyEmiI7LEgAflynPn cpXkRxaaguvTVaFXec4wt++s6Ews/4kXyZ+loJb7ClLnL4hqPqbxTYH1y4vMWnYRkXIn Fcwltvm17Ainnr6xp3jHQuUt49N9SQMawPtURJdfn8gHiW563BldlCbrUoheaVNazmp8 /Vgw== X-Gm-Message-State: AOAM530dGgiXn9bOhjieID0PLwUOAMKH5rWa02/+JF6VnVNR2caACPKA zsTUR0K1vBsnwSy/pTwzGHpYgy/y8Jo= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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, u= nsigned nr) =20 static void writeback_registers(struct x86_emulate_ctxt *ctxt) { + unsigned long dirty =3D ctxt->regs_dirty; unsigned reg; =20 - 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]); } =20 --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 6F3BBC433FE for ; Thu, 26 May 2022 21:24:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349137AbiEZVY3 (ORCPT ); Thu, 26 May 2022 17:24:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348865AbiEZVYV (ORCPT ); Thu, 26 May 2022 17:24:21 -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 185785623E for ; Thu, 26 May 2022 14:24:21 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id nn14-20020a17090b38ce00b001e00df82de8so3909300pjb.1 for ; Thu, 26 May 2022 14:24:21 -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=Z5rN6YPBoBaDcShw+MJ1A7OzTCd2S/V2SEjqpA1SvMaS2Cg5mHAm3MQCmlrPqdYjyl 2V5sZtJY00RZigOfx89YGkO1vHDnruW7QDmeHRq9qFJicpcrsreQwO+/cgJ5ytlrzEdu yFzCKsVTkZ0atcdVrAdEwxTwLnmWqI0bYNYGfNOP7Gu7VqVeImHmcDuttrm3cU8zOR3K RqJQnnA3JA1155tjYNWzFM7S7PnJ5mBkl7xi2yMrMP8NV4/Wr8XDlUn4ORbGUXhmb5BB 6lNXQt3UOF3nGi0GHyptpYXRK4LJX6YQKvjQIBYR1bMNPW6riMVelxbjuCiUFhSt73Mr NQ+Q== X-Gm-Message-State: AOAM530Q0datGDJSzsdUHy0glM4AQsVGlx4DfvZ4pKSkrlFNnQFgJW41 Rg7gu2WIqD0gov5lDxmXnvjhVkHZAkQ= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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=3D216026 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105679 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 { =20 static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { + if (WARN_ON_ONCE(nr >=3D 16)) + nr &=3D 16 - 1; + if (!(ctxt->regs_valid & (1 << nr))) { ctxt->regs_valid |=3D 1 << nr; ctxt->_regs[nr] =3D ctxt->ops->read_gpr(ctxt, nr); @@ -256,6 +259,9 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, un= signed nr) =20 static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { + if (WARN_ON_ONCE(nr >=3D 16)) + nr &=3D 16 - 1; + ctxt->regs_valid |=3D 1 << nr; ctxt->regs_dirty |=3D 1 << nr; return &ctxt->_regs[nr]; --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 D377BC433EF for ; Thu, 26 May 2022 21:24:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349226AbiEZVYn (ORCPT ); Thu, 26 May 2022 17:24:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348998AbiEZVYY (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 A097587A25 for ; Thu, 26 May 2022 14:24:22 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id g9-20020a17090a3c8900b001e0b21c4d68so1664478pjc.9 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=Q+HDHvIUiaC86N1viD/BdrpT6D3VrrXAlBDZq07l5IGWJ806M4lMqc/TvWoUV/GKVA Pfu1WGhiZH5dtO8Y+faWpiFRoutQst5uXU2RXZ99SqVDUK6fQl8NiRU2xO2pk/LTOk92 b+QxmcCB/EPtZZyGcYDDsrdWoq1XKCgAJmmwt/Pk31oOUPTY7uvmwYBSF/QVnAfP9CbG FysmmJjCr5xGOCWANrctQd8+GH2CayoZgCOIPTaec8GZdJKJsjSXyvZeyScRWMQ5WmI/ rqXKtiRKc7/u9E6tDVW8KIVIoO8Q7MJ4TfOl6ZQZvufMBKrrMsZWnrYw93bhm4qXesiR InEg== X-Gm-Message-State: AOAM532xRBZncvF4XLTvanHP1jZe6pjp9liHDACaD8MWNANOXxM4TBMq eVXtHvCUzsY7+eGhWhVLtY2g531TY2M= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 { =20 static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >=3D 16)) - nr &=3D 16 - 1; + if (WARN_ON_ONCE(nr >=3D NR_EMULATOR_GPRS)) + nr &=3D NR_EMULATOR_GPRS - 1; =20 if (!(ctxt->regs_valid & (1 << nr))) { ctxt->regs_valid |=3D 1 << nr; @@ -259,8 +259,8 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, un= signed nr) =20 static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >=3D 16)) - nr &=3D 16 - 1; + if (WARN_ON_ONCE(nr >=3D NR_EMULATOR_GPRS)) + nr &=3D NR_EMULATOR_GPRS - 1; =20 ctxt->regs_valid |=3D 1 << nr; ctxt->regs_dirty |=3D 1 << nr; @@ -278,7 +278,7 @@ static void writeback_registers(struct x86_emulate_ctxt= *ctxt) unsigned long dirty =3D ctxt->regs_dirty; unsigned reg; =20 - 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]); } =20 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; =20 typedef void (*fastop_t)(struct fastop *); =20 +/* + * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP. RI= P 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 opera= nd in + * a ModRM or SIB byte. + * + * TODO: this is technically wrong for 32-bit KVM, which only supports 8 G= PRs; + * 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; --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 80F37C433F5 for ; Thu, 26 May 2022 21:24:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349204AbiEZVYe (ORCPT ); Thu, 26 May 2022 17:24:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349072AbiEZVYZ (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 8AEAA60069 for ; Thu, 26 May 2022 14:24:24 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id t14-20020a1709028c8e00b0015cf7e541feso1703861plo.1 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=vJKGYJz0ckPbia07V4O2JIOpkf6JWY2tUp6DJL2+cUzpw3UwZASjVe4fF/2lZq+TX0 vWTSmgkQzstV5fVrKoilMnej46n48aqdaz5Sxyjff9qqNech7kJkfrrXgBUS/JhO8BaR voohlP+/9PvEYDm/dDBrA4locwPMFQJ0swZRKvYADCve2SpOFyKOAOwTRL3nIjs0TWpX TYFfvMTjhGqEeF0xk7ZVPUERlk0ZyBlx/pXQXx71y0wmpKazGgzldZGqtdUCaH2pzqzL wmo8aCE1NGRlUysRKhDkl0NGToxGro5VFCJub54lishxg5KpbaLa6HJtUk4ARxnhrSmD t6HQ== X-Gm-Message-State: AOAM531H5qZfmTluYhx7ARJ13xnGMjJWWvveCMxgIiBKeATgZG1U2svw rdtRz+vsdMZT1U++5FDvOzaFJ4UsvXs= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 >=3D NR_EMULATOR_GPRS)) nr &=3D NR_EMULATOR_GPRS - 1; =20 + 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 |=3D 1 << nr; ctxt->regs_dirty |=3D 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; --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 49F07C433F5 for ; Thu, 26 May 2022 21:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345544AbiEZVYs (ORCPT ); Thu, 26 May 2022 17:24:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349152AbiEZVYc (ORCPT ); Thu, 26 May 2022 17:24:32 -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 690C2C03AA for ; Thu, 26 May 2022 14:24:26 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id z186-20020a6233c3000000b00510a6bc2864so1486487pfz.10 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=m8K3OnP+IcVmBwCvveLyh9fOqgpwdkIpYNLMRJhZ2mUeZ8IBxW3dDuXYtzhjhTR9Yd s4w6FhaelFbFSk3kULyTKG+jadJt4O5lXrH7i6lPnmW+pTYUrhAmSpACzYo041qxrW0Y C9pJ09eQtjQQI3ivK88JA0BqbADH3vIPME9ysYejX34NsFkj7E6958SS00Mr9vsb/rzZ Yo0OjlD4cuQixvsOzYQqOHUHD4UNwVYnkvynjIUAzkRfg9+WJfcSNm0Zn97MgdGUGhFU RHnZmlXd1C4KTOO2EXxnHKOoVGoZTijE+xEN/HcXk0yNlAclwX5I5Flc+NTusR1UDgnE PDUw== X-Gm-Message-State: AOAM5320rre/8RRJev4vinc+mZgZcR3WycT7YVu3fxiGqH2rPHvynean /aoSaSEHQV3Sd6Vz/MXTec/shBuQckE= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =3D GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLA= GS_FIXED; ctxt->_eip =3D GET_SMSTATE(u32, smstate, 0x7ff0); =20 - for (i =3D 0; i < 8; i++) + for (i =3D 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) =3D GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); =20 val =3D 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; =20 - for (i =3D 0; i < 16; i++) + for (i =3D 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) =3D GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8); =20 ctxt->_eip =3D 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 opera= nd in * a ModRM or SIB byte. - * - * TODO: this is technically wrong for 32-bit KVM, which only supports 8 G= PRs; - * R8-R15 don't exist. */ +#ifdef CONFIG_X86_64 #define NR_EMULATOR_GPRS 16 +#else +#define NR_EMULATOR_GPRS 8 +#endif =20 struct x86_emulate_ctxt { void *vcpu; --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 4C68DC433EF for ; Thu, 26 May 2022 21:25:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233809AbiEZVZB (ORCPT ); Thu, 26 May 2022 17:25:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349178AbiEZVYd (ORCPT ); Thu, 26 May 2022 17:24:33 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80FE3E7320 for ; Thu, 26 May 2022 14:24:28 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id n191-20020a2540c8000000b0064f89b186f5so2634871yba.1 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=dPKNLFSW/HI6gQN54yURtM3vTC5coJJ4Teo8uiqw/OdR/+kLY/jOpCDrADgFLSGXlX 5yEVQHHxzn6eQAlLZ13jWiA8vK5b7zLXCif1umXg5bIdwl/z1Vti2MujyjPiiKI23th9 mrLgH9KLgfl+8WBEagmv4ZbjvqqDzLKBID8W7ume0NrhLl4XlHXUTnXNsvAAwN+OY1nZ Wqp8ypgC+bYEBbsoGc3TXEtGoGVRWoiDMzAG+5+7+L04F2CucSgf6mWpJZDCIKrqqOfU c0pm1wrCHok38yQsvrK35VDVB2K1ArnWIjm3w5hzWKKTxe+WzyldudgvxafsC1YjoAiU 3OQQ== X-Gm-Message-State: AOAM533bhkJrcb4U5t2PA5rfdWWq6D6fbZue7B0cZwnHenM0t6sqepQu xZoIviBtBrACK+AeLpJbLorDHf7gjC8= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 { =20 static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >=3D NR_EMULATOR_GPRS)) + if (KVM_EMULATOR_BUG_ON(nr >=3D NR_EMULATOR_GPRS, ctxt)) nr &=3D NR_EMULATOR_GPRS - 1; =20 if (!(ctxt->regs_valid & (1 << nr))) { @@ -259,7 +259,7 @@ static ulong reg_read(struct x86_emulate_ctxt *ctxt, un= signed nr) =20 static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr) { - if (WARN_ON_ONCE(nr >=3D NR_EMULATOR_GPRS)) + if (KVM_EMULATOR_BUG_ON(nr >=3D NR_EMULATOR_GPRS, ctxt)) nr &=3D NR_EMULATOR_GPRS - 1; =20 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 */ =20 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; }; =20 +#define KVM_EMULATOR_BUG_ON(cond, ctxt) \ +({ \ + int __ret =3D (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); } =20 +static void emulator_vm_bugged(struct x86_emulate_ctxt *ctxt) +{ + struct kvm *kvm =3D emul_to_vcpu(ctxt)->kvm; + + if (!kvm->vm_bugged) + kvm_vm_bugged(kvm); +} + static const struct x86_emulate_ops emulate_ops =3D { + .vm_bugged =3D emulator_vm_bugged, .read_gpr =3D emulator_read_gpr, .write_gpr =3D emulator_write_gpr, .read_std =3D emulator_read_std, --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 9CAF5C433EF for ; Thu, 26 May 2022 21:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349234AbiEZVYz (ORCPT ); Thu, 26 May 2022 17:24:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44884 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349194AbiEZVYe (ORCPT ); Thu, 26 May 2022 17:24:34 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CFF0E8B89 for ; Thu, 26 May 2022 14:24:29 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id l14-20020a170902f68e00b001633979d821so1694821plg.9 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=7kKXXSNlt6aQZkBFg+vzBfTkFNPSTO5Gms/jC5zGcCsf0Z6Q257GdrbsY+1vLudNk5 61JC2vySvuadPRGBRwGa0iRPNvChSNJI1LjO9pHOPD7ktyqLt7/ObLzgNvDCmPZbQ/Rs FvQ1Mf4Uy9CJHfGOWfTJrd6RA2f+6S09RyufZGNVCBmLzndpcXn5Zu7RDiYSrWurqYxz NMqN472SlbeSsjxIcqMclCxw8rOGWhU6HPboIG1+EVq2pzLKuGZ22Ga54L+ZFIWirdyZ IeCHOuhwlnoUiohRM9VR6gOXn4sGOUZE7bNEG+7Clp6rqr+r6O41Rj2V1PJgumdrYpgA k0PQ== X-Gm-Message-State: AOAM530jwf9kKOFDrvcPFEViFmpghHjl4ptGALthVgCiWDUvwVkjbowI kDwKTW/FzDxBWDuoH5oM3hF/0AkG4UI= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =3D vec; ctxt->exception.error_code =3D error; ctxt->exception.error_code_valid =3D valid; @@ -5728,7 +5730,8 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) =20 done: if (rc =3D=3D 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 =3D true; } if (rc =3D=3D X86EMUL_INTERCEPTED) --=20 2.36.1.255.ge46751e96f-goog From nobody Tue Apr 28 23:19:20 2026 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 E2D18C433F5 for ; Thu, 26 May 2022 21:25:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348841AbiEZVZG (ORCPT ); Thu, 26 May 2022 17:25:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349208AbiEZVYe (ORCPT ); Thu, 26 May 2022 17:24:34 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D8E3E8B97 for ; Thu, 26 May 2022 14:24:31 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id x16-20020a63f710000000b003f6082673afso1292267pgh.15 for ; Thu, 26 May 2022 14:24:31 -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=ogPb11GGAKqwULekX++bw8mBzTcDzebDpvNNjDo4l4AiL7gOX7qSvEcGkc+ZZDG7p1 I4mjKz+l8o1NEArv9JxpUWqtlcJ3gDJm5meGBM8IDkyExXr9J+9E73b9IhvgYP+gvnr0 hkdy/drOF5S5z3CRREheNWAfx+KXBjutpSNDQpSrVgiF67FWGELUb6lnvUQ3emnvu6Pp 4u9SWNQ8YgJIapSyskoVoXwV6m0xx2nqTyo1fZezvRgs3UBZ/0imAIoEgIkaAagl+pZC R7UMK3201tMdnOe5y/yBluRDxO9buaqYwRWGRWW6YcaAdQj6iwGLjef2IkxqVyFWFexG FTHQ== X-Gm-Message-State: AOAM533e0ZBqhv5K/DDGKfnvZ/2W2pRgc/DAtIUXovIor6+RTn6dlJvK vvQ0nOgBoDryLtYoXEtxh0gQraQDZHo= 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: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 *ctx= t, if (mc->pos < mc->end) goto read_cached; =20 - WARN_ON((mc->end + size) >=3D sizeof(mc->data)); + if (KVM_EMULATOR_BUG_ON((mc->end + size) >=3D sizeof(mc->data), ctxt)) + return X86EMUL_UNHANDLEABLE; =20 rc =3D ctxt->ops->read_emulated(ctxt, addr, mc->data + mc->end, size, &ctxt->exception); --=20 2.36.1.255.ge46751e96f-goog