Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756808AbcLXBiY (ORCPT ); Fri, 23 Dec 2016 20:38:24 -0500 Received: from mga01.intel.com ([192.55.52.88]:26759 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751671AbcLXBiX (ORCPT ); Fri, 23 Dec 2016 20:38:23 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,396,1477983600"; d="scan'208";a="45999312" From: Ricardo Neri To: Ingo Molnar , Thomas Gleixner , Borislav Petkov , Andy Lutomirski , Peter Zijlstra Cc: linux-kernel@vger.kernel.org, x86@kernel.org, , , Ricardo Neri , Andrew Morton , Brian Gerst , Chen Yucong , Chris Metcalf , Dave Hansen , Fenghua Yu , Huang Rui , Jiri Slaby , Jonathan Corbet , "Michael S . Tsirkin" , Paul Gortmaker , "Ravi V . Shankar" , Vlastimil Babka , Shuah Khan , Paolo Bonzini , Liang Z Li Subject: [v2 0/7] x86: enable User-Mode Instruction Prevention Date: Fri, 23 Dec 2016 17:37:38 -0800 Message-Id: <20161224013745.108716-1-ricardo.neri-calderon@linux.intel.com> X-Mailer: git-send-email 2.9.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6019 Lines: 133 This is v2 of my first submission done a while ago[1]. I apologize for the delay. User-Mode Instruction Prevention (UMIP) is a security feature present in new Intel Processors. If enabled, it prevents the execution of certain instructions if the Current Privilege Level (CPL) is greater than 0. If these instructions were executed while in CPL > 0, user space applications could have access to system-wide settings such as the global and local descriptor tables, the segment selectors to the current task state and the local descriptor table. These are the instructions covered by UMIP: * SGDT - Store Global Descriptor Table * SIDT - Store Interrupt Descriptor Table * SLDT - Store Local Descriptor Table * SMSW - Store Machine Status Word * STR - Store Task Register If any of these instructions is executed with CPL > 0, a general protection exception is issued when UMIP is enabled. There is a caveat, however. Certain applications rely on some of these instructions to function. An example of this are applications that use WineHQ[2]. For instance, these applications rely on sidt returning a non- accesible memory location[3]. During the discussions, it was proposed that the fault could be relied to the user-space and perform the emulation in user-mode. However, this would break existing applications until, for instance, they update to a new WineHQ version. However, this approach would require UMIP to be disabled by default. The concensus in this forum is to always enable it. This patchset initially treated tasks running in virtual-8086 mode as a special case. However, I received clarification that DOSEMU[4] does not support applications that use these instructions. It relies on WineHQ for this[4]. Furthermore, the applications for which the concern was raised run in protected mode [3]. This version keeps UMIP enabled at all times and by default. If a general protection fault caused by the instructions protected by UMIP is detected, such fault will be fixed-up by returning dummy values as follows: * SGDT and SIDT return a base address to a dummy location in kernel memory and a limit of 0. * STR, SLDT returns 0 as the segment selector. This seems OK since we are providing a dummy value as the base address of the global descriptor table. * SMSW returns 0. Lastly, I found very useful the code for Intel MPX (Memory Protection Extensions) used to parse opcodes and the memory locations contained in the general purpose registers when used as operands. I put some of this code in a separate file that both MPX and UMIP can access and avoid code duplication. While here, I fixed two small bugs that I found in the MPX implementation. The code that I used to test the emulated instructions can be found in [6]. [1]. https://lwn.net/Articles/705877/ [2]. https://www.winehq.org/ [3]. https://www.winehq.org/pipermail/wine-devel/2016-November/115320.html [4]. http://www.dosemu.org/ [5]. http://marc.info/?l=linux-kernel&m=147876798717927&w=2 [6]. https://github.com/01org/luv-yocto/tree/rneri/umip/meta-luv/recipes-core/umip/files Thanks and BR, Ricardo Cc: Andy Lutomirski Cc: Andrew Morton Cc: Borislav Petkov Cc: Brian Gerst Cc: Chen Yucong Cc: Chris Metcalf Cc: Dave Hansen Cc: Fenghua Yu Cc: Huang Rui Cc: Jiri Slaby Cc: Jonathan Corbet Cc: Michael S. Tsirkin Cc: Paul Gortmaker Cc: Peter Zijlstra Cc: Ravi V. Shankar Cc: Vlastimil Babka Cc: Shuah Khan Cc: Paolo Bonzini Cc: Liang Z Li Cc: x86@kernel.org Cc: linux-msdos@vger.kernel.org Changes since V1: * Virtual-8086 mode tasks are not treated in a special manner. All code for this purpose was removed. * Instead of attempting to disable UMIP during a context switch or when entering virtual-8086 mode, UMIP remains enabled all the time. General protection faults that occur are fixed-up by returning dummy values as detailed above. * Removed umip= kernel parameter in favor of using clearcpuid=514 to disable UMIP. * Removed selftests designed to detect the absence of SIGSEGV signals when running in virtual-8086 mode. * Reused code from MPX to decode instructions operands. For this purpose code was put in a common location. * Fixed two bugs in MPX code that decodes operands. Ricardo Neri (7): x86/mpx: Do not use SIB index if index points to R/ESP x86/mpx: Fail when implicit zero-displacement is used along with R/EBP x86/mpx, x86/insn: Relocate insn util functions to a new insn-utils x86/cpufeature: Add User-Mode Instruction Prevention definitions x86: Add emulation code for UMIP instructions x86/traps: Fixup general protection faults caused by UMIP x86: Enable User-Mode Instruction Prevention arch/x86/Kconfig | 10 ++ arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/disabled-features.h | 8 +- arch/x86/include/asm/insn.h | 6 + arch/x86/include/asm/umip.h | 16 +++ arch/x86/include/uapi/asm/processor-flags.h | 2 + arch/x86/kernel/Makefile | 1 + arch/x86/kernel/cpu/common.c | 16 ++- arch/x86/kernel/traps.c | 4 + arch/x86/kernel/umip.c | 170 ++++++++++++++++++++++++++++ arch/x86/lib/Makefile | 2 +- arch/x86/lib/insn-utils.c | 148 ++++++++++++++++++++++++ arch/x86/mm/mpx.c | 119 +------------------ 13 files changed, 382 insertions(+), 121 deletions(-) create mode 100644 arch/x86/include/asm/umip.h create mode 100644 arch/x86/kernel/umip.c create mode 100644 arch/x86/lib/insn-utils.c -- 2.9.3