Received: by 2002:a5d:9c59:0:0:0:0:0 with SMTP id 25csp85529iof; Sun, 5 Jun 2022 21:55:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzlodd8YSuxGKj5I6FBX0qo1R+hvGP+gowwv5Zys7zLhPZTNRyzY5qN3O+o7XsYGYk33nXK X-Received: by 2002:a17:903:40c9:b0:167:5fce:a5e with SMTP id t9-20020a17090340c900b001675fce0a5emr11276387pld.6.1654491317613; Sun, 05 Jun 2022 21:55:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654491317; cv=none; d=google.com; s=arc-20160816; b=JPb7l/b6lIJu8Tc4VIwkRjAFS0Cwu2exYMimEgVRHQ1vtR+GHONfKdPmCQJmQJhYPa /eabQHc1jxDSIFyVr/uZ+JKOXs8RAukoS0xs2s5N+/+82qvGFpsyvJ1m8fz3S9hAWS/I 9FLUBpfYS7RMXmZI0if371TuV21E0py+I5Wm/KvdDbWZNB9lJj61vlKSZN7XGUTGBHPd fqz+6HQisoYVSZUQMqp+qGx1IVJ/rfxlkqp8zLI4BUZ5JIXET8wSxTIWvxc3FxtHfovk iItN9DSez7Fq26pvJUyJpXklMXimTVS7+TKSrV2gz6H3lCOAj4WE4m+Jr36DpF66d1ru Lq/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=9GaB0H3olBMG51bTd1VIYeCdTKTpavGOLBIss3aN45Y=; b=gqv+oC3iF5GjgNDIKSFKEDBtHIo5ltfRbo6b2+XWHQaAfB9BUS5LFHnLfT5QqPLfzh 5u+XminpdoA6BzaC3VKi3kB+LJo7d8abNpCmESFkW1DqHLhkwIpc34WlVJinTUwK6FpH osmE1HKFwaKtA64NoxTXYsvYPvwp8DEY9wteTkp6mDiOs7w0jZWm/vkI0x4/r1bqGdTv ElU4QiNtS019rgZ9Iy/YUmAzb/U0APp4BRGuPNFoKcEXBgWJm2ep4RtpNClY0uhPlV/7 5mj9vGpIkRVXG/w7FVZTwHhlfcezPYyQK1zA/ahN3lRzV6IxePF7or/OdCi5bX+kJXlV 3a+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=hcxZdG4+; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id f9-20020a056a0022c900b005183434ec7csi20299442pfj.363.2022.06.05.21.55.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Jun 2022 21:55:17 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=hcxZdG4+; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id F40DFB0D39; Sun, 5 Jun 2022 21:09:13 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346696AbiFCSAa (ORCPT + 99 others); Fri, 3 Jun 2022 14:00:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347102AbiFCRv5 (ORCPT ); Fri, 3 Jun 2022 13:51:57 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6CCB457B16; Fri, 3 Jun 2022 10:50:04 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8F7D760A0F; Fri, 3 Jun 2022 17:50:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7FF17C385A9; Fri, 3 Jun 2022 17:50:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654278603; bh=8KN7L+80h1MHPhss4GQUQaL93QCH/hlkREk2DlXPkyI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hcxZdG4+d/uqaXZqdAndOTdpD9oYhDmzdkvCvlGE2cIoT3xh2TYOtJC5+Z+c3xD/P 1Yy2cgacGX4dMKPhp3npZlt3Q3m/QUQaKsKLqmHK7ReRrSOb6hn67ygWfCMkZgU5EJ l3jKOh+8+zsnRUmlxq1pOREo05Gj/QpY+Vt5cgGA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Qiuhao Li , Gaoning Pan , Yongkang Jia , Sean Christopherson , Paolo Bonzini Subject: [PATCH 5.15 31/66] KVM: x86: avoid calling x86 emulator without a decoded instruction Date: Fri, 3 Jun 2022 19:43:11 +0200 Message-Id: <20220603173821.553626389@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220603173820.663747061@linuxfoundation.org> References: <20220603173820.663747061@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sean Christopherson commit fee060cd52d69c114b62d1a2948ea9648b5131f9 upstream. Whenever x86_decode_emulated_instruction() detects a breakpoint, it returns the value that kvm_vcpu_check_breakpoint() writes into its pass-by-reference second argument. Unfortunately this is completely bogus because the expected outcome of x86_decode_emulated_instruction is an EMULATION_* value. Then, if kvm_vcpu_check_breakpoint() does "*r = 0" (corresponding to a KVM_EXIT_DEBUG userspace exit), it is misunderstood as EMULATION_OK and x86_emulate_instruction() is called without having decoded the instruction. This causes various havoc from running with a stale emulation context. The fix is to move the call to kvm_vcpu_check_breakpoint() where it was before commit 4aa2691dcbd3 ("KVM: x86: Factor out x86 instruction emulation with decoding") introduced x86_decode_emulated_instruction(). The other caller of the function does not need breakpoint checks, because it is invoked as part of a vmexit and the processor has already checked those before executing the instruction that #GP'd. This fixes CVE-2022-1852. Reported-by: Qiuhao Li Reported-by: Gaoning Pan Reported-by: Yongkang Jia Fixes: 4aa2691dcbd3 ("KVM: x86: Factor out x86 instruction emulation with decoding") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Message-Id: <20220311032801.3467418-2-seanjc@google.com> [Rewrote commit message according to Qiuhao's report, since a patch already existed to fix the bug. - Paolo] Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/x86.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7846,7 +7846,7 @@ int kvm_skip_emulated_instruction(struct } EXPORT_SYMBOL_GPL(kvm_skip_emulated_instruction); -static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) +static bool kvm_vcpu_check_code_breakpoint(struct kvm_vcpu *vcpu, int *r) { if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) && (vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) { @@ -7915,25 +7915,23 @@ static bool is_vmware_backdoor_opcode(st } /* - * Decode to be emulated instruction. Return EMULATION_OK if success. + * Decode an instruction for emulation. The caller is responsible for handling + * code breakpoints. Note, manually detecting code breakpoints is unnecessary + * (and wrong) when emulating on an intercepted fault-like exception[*], as + * code breakpoints have higher priority and thus have already been done by + * hardware. + * + * [*] Except #MC, which is higher priority, but KVM should never emulate in + * response to a machine check. */ int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type, void *insn, int insn_len) { - int r = EMULATION_OK; struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt; + int r; init_emulate_ctxt(vcpu); - /* - * We will reenter on the same instruction since we do not set - * complete_userspace_io. This does not handle watchpoints yet, - * those would be handled in the emulate_ops. - */ - if (!(emulation_type & EMULTYPE_SKIP) && - kvm_vcpu_check_breakpoint(vcpu, &r)) - return r; - r = x86_decode_insn(ctxt, insn, insn_len, emulation_type); trace_kvm_emulate_insn_start(vcpu); @@ -7966,6 +7964,15 @@ int x86_emulate_instruction(struct kvm_v if (!(emulation_type & EMULTYPE_NO_DECODE)) { kvm_clear_exception_queue(vcpu); + /* + * Return immediately if RIP hits a code breakpoint, such #DBs + * are fault-like and are higher priority than any faults on + * the code fetch itself. + */ + if (!(emulation_type & EMULTYPE_SKIP) && + kvm_vcpu_check_code_breakpoint(vcpu, &r)) + return r; + r = x86_decode_emulated_instruction(vcpu, emulation_type, insn, insn_len); if (r != EMULATION_OK) {