From patchwork Tue Feb 8 09:34:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hou Wenlong X-Patchwork-Id: 12738405 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 48FBFC433EF for ; Tue, 8 Feb 2022 09:34:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355208AbiBHJeL (ORCPT ); Tue, 8 Feb 2022 04:34:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355203AbiBHJeJ (ORCPT ); Tue, 8 Feb 2022 04:34:09 -0500 Received: from out0-152.mail.aliyun.com (out0-152.mail.aliyun.com [140.205.0.152]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB1E1C03FEC5 for ; Tue, 8 Feb 2022 01:34:08 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R151e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047213;MF=houwenlong.hwl@antgroup.com;NM=1;PH=DS;RN=1;SR=0;TI=SMTPD_---.Mn.uQJG_1644312846; Received: from localhost(mailfrom:houwenlong.hwl@antgroup.com fp:SMTPD_---.Mn.uQJG_1644312846) by smtp.aliyun-inc.com(127.0.0.1); Tue, 08 Feb 2022 17:34:06 +0800 From: "Hou Wenlong" To: kvm@vger.kernel.org Subject: [PATCH v2 0/3] KVM: x86/emulator: Fix wrong checks when loading code segment in emulator Date: Tue, 08 Feb 2022 17:34:02 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Per Intel's SDM on "Instruction Set Reference", code segment can be loaded by far jmp/call/ret, iret and int. For all those instructions, not-present segment check should be after type and privilege checks. But the emulator checks it first, so #NP is triggered instead of #GP if privilege check fails and the segment is not present. When loading code segment above realmode, RPL/CPL/DPL should be checked, but the privilege checks are different between those instructions. Since iret and int are only implemented for realmode in emulator, no checks ared needed. The current implement only checks if DPL > CPL for conforming code or (RPL > CPL or DPL != CPL) for non-conforming code. Since far call/jump to call gate, task gate and task state segment are not implemented for in emulator, the current checks are enough. As for far return, outer level return is not implemented above virtual-8086 mode in emulator, so RPL <= CPL. Per Intel's SDM, if RPL < CPL, it should trigger #GP, but it is missing in emulator. Other checks are satisfied in current implementation. When vmexit for task switch, code segment would also be loaded from tss. Since segment selector is loaded before segment descriptor when load state from tss, it implies that RPL = CPL, the checks are satisfied too. I add some tests in kvm-unit-tests[*] for the wrong checks in emulator. Enable kvm.force_enable_emulation to test them on emulator. [*] https://lore.kernel.org/kvm/cover.1644311445.git.houwenlong.hwl@antgroup.com Changed from v1: - Add a comment about RPL < CPL check for far return in patch 2. - Fix a mistake when judge transfer type in patch 2. - As Sean suggested, add a new patch to move the unhandled outer privilege level logic of far return into __load_segment_descriptor(). Hou Wenlong (3): KVM: x86/emulator: Defer not-present segment check in __load_segment_descriptor() KVM: x86/emulator: Fix wrong privilege check for code segment in __load_segment_descriptor() KVM: x86/emulator: Move the unhandled outer privilege level logic of far return into __load_segment_descriptor() arch/x86/kvm/emulate.c | 51 +++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) --- 2.31.1