Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp2499778ybg; Fri, 5 Jun 2020 15:45:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwHx0WfAoLbcEDVJ0jtad8+T4uFQjPE6q7lD0G7wmgScsF35Vr1qFzWZ6FUJQ+vtWY71fsL X-Received: by 2002:a17:906:851:: with SMTP id f17mr10356106ejd.396.1591397118028; Fri, 05 Jun 2020 15:45:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591397118; cv=none; d=google.com; s=arc-20160816; b=XdFOi5NM5YSOdobMs7tEqkb+a9NKCGIK+JjtYAz0QXPf5waY1ydSjfSvUeLESP0MaD 0c9Rfp/n6mtBrQkQehMdaaI7bJ4/y3mzUr86eNnqLdpv/kbMc9ZcHCICN+vT9M9LxWAk bgT269LBajY5MaqelId7JMmqfpNQIzYJIvxSPkxaGCvcFI7LKmUpk22ApKBPtWGdY7zU 2pJyDcuzel0NyobD+5M+zcaxebOb5rZx6w04yPZJiWYILeuHaU20U4GYe2PSb7YN4wYm 54qHlEaOkdPY82jOtI4qSsIXK8W0pxTSFOoU1X7vnmT6TP7izXgf688gmhVyvbazfFdN OIlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:ironport-sdr :ironport-sdr; bh=Bxd645uwHngQecXh9kdYT+3jOsxhtWMZy0k0ZZxuEdI=; b=lkQHSbVPH47wK2rGrtaNA2vp5WmotGxEqkX3jtWaIGXc70MscM1uBFPSr11FJXW/4Z exP6iMoA88/dwS8ILk30PJhvMPsDnivrBOWn3shcykk0Vfzq0FsNmiWi67wXyCtE+e9r zdtUzmsoKW9j8D9PTjugkLYmUd3yeGrqNvmnCmzXUYFJ1o1el2KE9soKdUPdJITKGsff /5yCYI2oX29BhZi/Nzgurr+em30+DNaBig1QbVXr5eWHo3U1DJl+lXN/fr83xPo3l3+C +ctX8sX0IiAfBTHe1hjsg38yBHHBoEynxKmumQIyTiEMMiBTsGj35x7PyKwN/ZQNa/pW cYdA== ARC-Authentication-Results: i=1; mx.google.com; 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=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bz17si4074608ejc.605.2020.06.05.15.44.55; Fri, 05 Jun 2020 15:45:18 -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; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728368AbgFEWmP (ORCPT + 99 others); Fri, 5 Jun 2020 18:42:15 -0400 Received: from mga18.intel.com ([134.134.136.126]:51110 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725878AbgFEWmP (ORCPT ); Fri, 5 Jun 2020 18:42:15 -0400 IronPort-SDR: 5ZzKNYisRwCwv9n47htYf3j5QcYJrCAkjEFjd1z+x5/0BIujuP8TlCenqZK5qpaN556STjKTwy h4U4mmKMcVrA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jun 2020 15:42:14 -0700 IronPort-SDR: 1awNLVZn28bzCXE18oeaLM73kW8zuL4Uorek+FgidFZ+2iNhIEoAuk9JpLxxAtbXjoH546OvzD BXdtwhGP+m9w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,478,1583222400"; d="scan'208";a="348580264" Received: from ranerica-svr.sc.intel.com ([172.25.110.23]) by orsmga001.jf.intel.com with ESMTP; 05 Jun 2020 15:42:14 -0700 Date: Fri, 5 Jun 2020 15:42:31 -0700 From: Ricardo Neri To: Brendan Shanks Cc: Andy Lutomirski , LKML , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , X86 ML , "Eric W. Biederman" , Andreas Rammhold , "Moger, Babu" Subject: Re: [PATCH] x86/umip: Add emulation/spoofing for SLDT and STR instructions Message-ID: <20200605224231.GA7466@ranerica-svr.sc.intel.com> References: <20200602184212.10813-1-bshanks@codeweavers.com> <20200604001243.GA24742@ranerica-svr.sc.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jun 05, 2020 at 11:58:13AM -0700, Brendan Shanks wrote: > > > On Jun 3, 2020, at 9:39 PM, Andy Lutomirski wrote: > > > > On Wed, Jun 3, 2020 at 5:12 PM Ricardo Neri > > > wrote: > >> > >> On Tue, Jun 02, 2020 at 11:42:12AM -0700, Brendan Shanks wrote: > >>> 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 > >>> --- > >>> arch/x86/kernel/umip.c | 23 ++++++++++++++--------- > >>> 1 file changed, 14 insertions(+), 9 deletions(-) > >>> > >>> diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c > >>> index 8d5cbe1bbb3b..59dfceac5cc0 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,24 @@ 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 > >>> + dummy_value = 0; > >> > >> Perhaps you can return a non-zero value for SLDT if it has an LDT, as > >> Andy had suggested. Maybe this can be implemented by looking at > >> current->mm->context.ldt > >> > >> I guess the non-zero value can be (GDT_ENTRY_LDT*8). > > > > You could probably even get away with always returning a nonzero > > value. After all, an empty LDT is quite similar to no LDT. > > > Is something like this what you both had in mind? > I don’t have any software handy to test the LDT-present case though. Perhaps you can insert a test in the kernel selftest. Something like this (based on Andreas' test program): --- a/tools/testing/selftests/x86/ldt_gdt.c +++ b/tools/testing/selftests/x86/ldt_gdt.c @@ -220,12 +220,23 @@ static void install_invalid(const struct user_desc *desc, bool oldmode) } } +unsigned long test(void) +{ + unsigned char ldtr[5] = "\xef\xbe\xad\xde"; + unsigned long ldt = 0; + asm("sldt %0\n" : "=m" (ldtr)); + ldt = *((unsigned long *)&ldtr[0]); + printf ("LDT base: 0x%lx\n", ldt); + return (ldt); +} + static int safe_modify_ldt(int func, struct user_desc *ptr, unsigned long bytecount) { int ret = syscall(SYS_modify_ldt, 0x11, ptr, bytecount); if (ret < -1) errno = -ret; + test(); return ret; } Thanks and BR, Ricardo > > > 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 > It looks fine to me. Perhaps Andy prefers a simpler, always-non-zero implementation? Thanks and BR, Ricardo