Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp904616ybt; Fri, 10 Jul 2020 15:46:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwZt/canPMtYfANFsQ7ZSyGOhMMGcUhlFVHuCATkoZgyEbOQdIDT5ZXptsmFM+UNhr/7S7c X-Received: by 2002:a17:906:e213:: with SMTP id gf19mr13776506ejb.433.1594421215714; Fri, 10 Jul 2020 15:46:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594421215; cv=none; d=google.com; s=arc-20160816; b=bJBrJqhPLTSbK0GyVIkVm10PidJcbDWeqC7QQZZvxhmekS8hZIon2Ht2lVguSRpBMg 9yV7XG+gRhyJsbpGIgRoN45/gLn6z1+BFiCtVcnXABWkAIL2N+yOs4L3Z3jli2O5MpHP 5XwBuqV2Ct5WiFdVfyjlVZ6bPReChEVlBK+cYFPezXPXAW3H9rHr/fhtM7EJH7nBRY0k wVgOMy95cBhhryk7psMGo0PEUid3z9NyNL2vhDbdaFZ34EdfpSZzW+9FRqBUDfB6oYy1 XrGlCaK4KIIxpHfJCFz0Ptvo9L5KlsjtyYXgHL7NhAdagpNsw+qKCIAdDnvBNXhAE2U+ rv/Q== 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=yfpklkI0Uly04vToX/pHdtTu+UTS4eaBLrvZbAHOPmk=; b=QiZqYGTKzITSz2Terdtcq8ujOwhXcUA1kDxAN5dx+sIfKofWAekVp4Oqzf4aw6fm+d 4f3NiYYFfRs3B6yWz5l8NUuA2tFj1T/yYtJANFZONqcLKzVeMHcLnMfrUKKMCPO2QDEc M9EqSrCiW08r0t94SA7Gk2TZbGOrL8FSVD0GvPbkjvczziSQrd+1tViqFSE5MvZ2jV1s xVUUcKYwHUIIhmatNbzj04OBI4p3bSzvy8DvEOkh7ooZ4q1DOLeYY6+AXJgMD0nBi5Q3 0ncTJ2iyVXUrEr7PfKPY8xXKIton/uSUpjPw/fNU2OWzYERtcVxxvV+u43KBSCQrdNBk ERow== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail (test mode) header.i=@codeweavers.com header.s=6377696661 header.b=TmqySOYT; 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 d23si4785824edz.176.2020.07.10.15.46.32; Fri, 10 Jul 2020 15:46:55 -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=TmqySOYT; 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 S1726609AbgGJWpo (ORCPT + 99 others); Fri, 10 Jul 2020 18:45:44 -0400 Received: from mail.codeweavers.com ([50.203.203.244]:48538 "EHLO mail.codeweavers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726465AbgGJWpo (ORCPT ); Fri, 10 Jul 2020 18:45:44 -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=yfpklkI0Uly04vToX/pHdtTu+UTS4eaBLrvZbAHOPmk=; b=TmqySOYTTQGIPLD1sUww08Ijk5 C0NMmGEIhicVx2C+JFTUHWV4O0e/kmG5QqKp+MlWcF/ZLZI5l0meDwr6eZC07Co4v9iuB8EvPeGdL Gg48OyeARxA8TBk5wW08ARVUddvtqCbUmx11Uy21PoosR2n2g1QWOXgliGEhWTk17+0Y=; 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 1ju1lx-0006qf-7t; Fri, 10 Jul 2020 17:45:40 -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 v5] x86/umip: Add emulation/spoofing for SLDT and STR instructions Date: Fri, 10 Jul 2020 15:45:25 -0700 Message-Id: <20200710224525.21966-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 --- v5: Capitalize instruction names in comments. arch/x86/kernel/umip.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index 8d5cbe1bbb3b..2c304fd0bb1a 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c @@ -45,11 +45,12 @@ * value that, lies close to the top of the kernel memory. The limit for the GDT * and the IDT are set to zero. * - * Given that SLDT and STR are not commonly used in programs that run on WineHQ - * or DOSEMU2, they are not emulated. - * - * The instruction smsw is emulated to return the value that the register CR0 + * The instruction SMSW is emulated to return the value that the register CR0 * has at boot time as set in the head_32. + * SLDT and STR are emulated to return the values that the kernel programmatically + * assigns: + * - SLDT returns (GDT_ENTRY_LDT * 8) if an LDT has been set, 0 if not. + * - STR returns (GDT_ENTRY_TSS * 8). * * Emulation is provided for both 32-bit and 64-bit processes. * @@ -244,16 +245,34 @@ 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 = GDT_ENTRY_TSS * 8; + } 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 +280,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 +401,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