Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp4576151ybg; Mon, 8 Jun 2020 11:17:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxO8t3auxccrcriZ62xmOnL6XygZDUVeG9mHUajNlq60rgTFRh4rrKykc03jvMcNIZ6yYS+ X-Received: by 2002:a05:6402:36d:: with SMTP id s13mr23416105edw.192.1591640251330; Mon, 08 Jun 2020 11:17:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591640251; cv=none; d=google.com; s=arc-20160816; b=YCA0BWe2VoE+M57sYm3vZLjI05edf3rKxyUnuc+tdSCSz7pt7zA5ihVRExXQptHyE7 aLqrI7O+ZEI9MROi4rkPwsAysOy0toAQgztDBna3nxj5tm8mjziFJ4TWbOM8LWpaP9ZJ TP+Z0CSN5vUJs9dfT57G79t5x3Ok0AZNmDmRKVpKaS/zNkJhVeAXaRCj6FBv9bmVi2Mv ax8t0e8p8WPQpEgxK22RmJRwpTftGQ+kwV9Qr83sCp75simZcrZyiZwi4qz+NDsAsxIk dpUfQFvyHepEXb1NivJoLay8KdB6RiIiHdpMOWn6lMIMChqAejBdxctSFwiqdMl20xji 0qQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=AtJTdkGcem0MKnYBuQj5wimwQb7HemSYIZc6Qs/sz9M=; b=uSEPruZ8NBjSuHJgBkvcJkT26mrQQtqLgLGkoaexNTd929EIYrlUWRKvmHvY1r0f4/ pA5VFACQ39J+wl0/Ix8UIAw4a+m0/YN4gz5pa+h1TYXhzIY8LmRQucRgFz64Pa6xrfdg 0WibUPEYmeHNVT5j5aGsulTsb3eQFA0frSTG/4iHGh9VSDzI4/N0LZeKQepUUk6eaUI1 rvwMKGju2mzpBM5bYFM/IGAR8VVEGOkyMnqlZw0Z+SPgAsg+uuGD6nrbWYrycKc9Zrxt 0ExWdRkJcixoVti7nZ3AOoIwfxZ1Dkt9XkF/vqJ1o6CulDTIf7YaJgER4ZB5V+DsHygC eHvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail (test mode) header.i=@codeweavers.com header.s=6377696661 header.b="PZ4/HvdN"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codeweavers.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z9si9102613ejm.47.2020.06.08.11.17.08; Mon, 08 Jun 2020 11:17:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail (test mode) header.i=@codeweavers.com header.s=6377696661 header.b="PZ4/HvdN"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codeweavers.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725924AbgFHSPL (ORCPT + 99 others); Mon, 8 Jun 2020 14:15:11 -0400 Received: from mail.codeweavers.com ([50.203.203.244]:36646 "EHLO mail.codeweavers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725283AbgFHSPL (ORCPT ); Mon, 8 Jun 2020 14:15:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=6377696661; h=Content-Transfer-Encoding:MIME-Version: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=AtJTdkGcem0MKnYBuQj5wimwQb7HemSYIZc6Qs/sz9M=; b=PZ4/HvdNcrXomQXlNjDnLLTMX2 HBjaJwIZQR+PnDcl0yzvjbLVA06OV6eVEsqQ1cPsP+eRpO6KwRDy2UoGq0wazcWt8dPLtFrc/AZE+ 3iDouVc0OXi71NheLG3CdywARXlAUBmMbI5rlogVlZtqoM13FmRl8bpIZkCCsvgV7/Zc=; Received: from cpe-107-184-2-226.socal.res.rr.com ([107.184.2.226] helo=zen.bslabs.net) by mail.codeweavers.com with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jiMId-0008GB-2z; Mon, 08 Jun 2020 13:15:09 -0500 From: Brendan Shanks To: linux-kernel@vger.kernel.org Cc: ricardo.neri-calderon@linux.intel.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, hpa@zytor.com, x86@kernel.org, ebiederm@xmission.com, andi@notmuch.email, Babu.Moger@amd.com, Brendan Shanks Subject: [PATCH v2] x86/umip: Add emulation/spoofing for SLDT and STR instructions Date: Mon, 8 Jun 2020 11:14:54 -0700 Message-Id: <20200608181454.14210-1-bshanks@codeweavers.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -25.8 X-Spam-Report: Spam detection software, running on the system "mail.codeweavers.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Add emulation/spoofing of SLDT and STR for both 32- and 64-bit processes. Wine users have found a small number of Windows apps using SLDT that were crashing when run on UMIP-enabled systems. Reported-by: Andreas Rammhold Originally-by: Ricardo Neri Signed-off-by: Brendan Shanks --- Content analysis details: (-25.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -20 USER_IN_WHITELIST From: address is in the user's white-list -6.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -0.5 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.7 AWL AWL: Adjusted score from AWL reputation of From: address Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add emulation/spoofing of SLDT and STR for both 32- and 64-bit processes. Wine users have found a small number of Windows apps using SLDT that were crashing when run on UMIP-enabled systems. Reported-by: Andreas Rammhold Originally-by: Ricardo Neri Signed-off-by: Brendan Shanks --- v2: Return (GDT_ENTRY_LDT * 8) for SLDT when an LDT is set. arch/x86/kernel/umip.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index 8d5cbe1bbb3b..a85f0b0ec2b9 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c @@ -64,6 +64,8 @@ #define UMIP_DUMMY_GDT_BASE 0xfffffffffffe0000ULL #define UMIP_DUMMY_IDT_BASE 0xffffffffffff0000ULL +#define UMIP_DUMMY_TASK_REGISTER_SELECTOR 0x40 + /* * The SGDT and SIDT instructions store the contents of the global descriptor * table and interrupt table registers, respectively. The destination is a @@ -244,16 +246,35 @@ static int emulate_umip_insn(struct insn *insn, int umip_inst, *data_size += UMIP_GDT_IDT_LIMIT_SIZE; memcpy(data, &dummy_limit, UMIP_GDT_IDT_LIMIT_SIZE); - } else if (umip_inst == UMIP_INST_SMSW) { - unsigned long dummy_value = CR0_STATE; + } else if (umip_inst == UMIP_INST_SMSW || umip_inst == UMIP_INST_SLDT || + umip_inst == UMIP_INST_STR) { + unsigned long dummy_value; + + if (umip_inst == UMIP_INST_SMSW) + dummy_value = CR0_STATE; + else if (umip_inst == UMIP_INST_STR) + dummy_value = UMIP_DUMMY_TASK_REGISTER_SELECTOR; + else if (umip_inst == UMIP_INST_SLDT) + { +#ifdef CONFIG_MODIFY_LDT_SYSCALL + down_read(¤t->mm->context.ldt_usr_sem); + if (current->mm->context.ldt) + dummy_value = GDT_ENTRY_LDT * 8; + else + dummy_value = 0; + up_read(¤t->mm->context.ldt_usr_sem); +#else + dummy_value = 0; +#endif + } /* - * Even though the CR0 register has 4 bytes, the number + * For these 3 instructions, the number * of bytes to be copied in the result buffer is determined * by whether the operand is a register or a memory location. * If operand is a register, return as many bytes as the operand * size. If operand is memory, return only the two least - * siginificant bytes of CR0. + * siginificant bytes. */ if (X86_MODRM_MOD(insn->modrm.value) == 3) *data_size = insn->opnd_bytes; @@ -261,7 +282,6 @@ static int emulate_umip_insn(struct insn *insn, int umip_inst, *data_size = 2; memcpy(data, &dummy_value, *data_size); - /* STR and SLDT are not emulated */ } else { return -EINVAL; } @@ -383,10 +403,6 @@ bool fixup_umip_exception(struct pt_regs *regs) umip_pr_warn(regs, "%s instruction cannot be used by applications.\n", umip_insns[umip_inst]); - /* Do not emulate (spoof) SLDT or STR. */ - if (umip_inst == UMIP_INST_STR || umip_inst == UMIP_INST_SLDT) - return false; - umip_pr_warn(regs, "For now, expensive software emulation returns the result.\n"); if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size, -- 2.26.2