Re: [PATCH v7 00/26] x86: Enable User-Mode Instruction Prevention

2017-05-26 Thread Neri, Ricardo
Hi again Ingo, Thomas,
On Wed, 2017-05-17 at 11:42 -0700, Ricardo Neri wrote:
> Hi Ingo, Thomas,
> 
> On Fri, 2017-05-05 at 11:16 -0700, Ricardo Neri wrote:
> > This is v7 of this series. The six previous submissions can be found
> > here [1], here [2], here[3], here[4], here[5] and here[6]. This
> > version
> > addresses the comments received in v6 plus improvements of the
> > handling
> > of exceptions unrelated to UMIP as well as corner cases in
> > virtual-8086
> > mode. Please see details in the change log.
> 
> Since there have been no more comments in the version and if this series
> look good to you, could this be considered to be merged into the tip
> tree?
> 
> The only remaining item is a cleanup patch that Borislav Petkov
> suggested [1]. I could work on it incrementally on top of this series.

More items have accumulated from the latest review from Borislav Petkov.
These items are preparatory changes and are mostly minimal and would
impact functionality. There have been no comments on other parts of the
implementation. If I spin a v8 of the series, would it be considered
sufficiently mature to be included in v4.13?

Thanks and BR,
Ricardo


> 
> Thanks and BR,
> Ricardo
> 
> [1]. https://lkml.org/lkml/2017/5/4/244
> 
> 
> 
> 
> 
> 



Re: [PATCH v7 00/26] x86: Enable User-Mode Instruction Prevention

2017-05-17 Thread Ricardo Neri
Hi Ingo, Thomas,

On Fri, 2017-05-05 at 11:16 -0700, Ricardo Neri wrote:
> This is v7 of this series. The six previous submissions can be found
> here [1], here [2], here[3], here[4], here[5] and here[6]. This
> version
> addresses the comments received in v6 plus improvements of the
> handling
> of exceptions unrelated to UMIP as well as corner cases in
> virtual-8086
> mode. Please see details in the change log.

Since there have been no more comments in the version and if this series
look good to you, could this be considered to be merged into the tip
tree?

The only remaining item is a cleanup patch that Borislav Petkov
suggested [1]. I could work on it incrementally on top of this series.

Thanks and BR,
Ricardo

[1]. https://lkml.org/lkml/2017/5/4/244




--
To unsubscribe from this list: send the line "unsubscribe linux-msdos" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 00/26] x86: Enable User-Mode Instruction Prevention

2017-05-05 Thread Ricardo Neri
This is v7 of this series. The six previous submissions can be found
here [1], here [2], here[3], here[4], here[5] and here[6]. This version
addresses the comments received in v6 plus improvements of the handling
of exceptions unrelated to UMIP as well as corner cases in virtual-8086
mode. Please see details in the change log.

=== What is UMIP?

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. Hiding these system resources reduces the tools
available to craft privilege escalation attacks such as [7].

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.

=== How does it impact applications?

We want to have UMIP enabled by default. However, UMIP will change the
behavior that certain applications expect from the operating system.
For instance, programs running on WineHQ and DOSEMU2 rely on some of these
instructions to function. Stas Sergeev found that Microsoft Windows 3.1
and dos4gw use the instruction SMSW when running in virtual-8086 mode[8].
SGDT and SIDT can also run on virtual-8086 mode.

In order to not change the behavior of the system. This patchset emulates
the SGDT, SIDT and SMSW. This should be sufficient to not break the
applications mentioned above. Regarding the two remaining instructions, STR
and SLDT, the WineHQ team has shown interest catching the general protection
fault and use it as a vehicle to fix broken applications[9]. Furthermore,
STR and SLDT can only run in protected and long modes.

DOSEMU2 emulates virtual-8086 mode via KVM. No applications will be broken
unless DOSEMU2 decides to enable the CR4.UMIP bit in platforms that support
it. Also, this should not pose a security risk as no system resouces would
be revealed. Instead, code running inside the KVM would only see the KVM's
GDT, IDT and MSW.

Please note that UMIP is always enabled for both 64-bit and 32-bit Linux
builds. However, emulation of the UMIP-protected instructions is not done
for 64-bit processes. 64-bit user space applications will receive the
SIGSEGV signal when UMIP instructions causes a general protection fault.

=== How are UMIP-protected instructions emulated?

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 hard-coded dummy values as the base of the global
   descriptor and interrupt descriptor tables. These hard-coded values
   correspond to memory addresses that are near the end of the kernel
   memory map. This is also the case for virtual-8086 mode tasks. In all
   my experiments in x86_32, the base of GDT and IDT was always a 4-byte
   address, even for 16-bit operands. Thus, my emulation code does the
   same. In all cases, the limit of the table is set to 0.
 * SMSW returns the value with which the CR0 register is programmed in
   head_32/64.S at boot time. This is, the following bits are enabled:
   CR0.0 for Protection Enable, CR.1 for Monitor Coprocessor, CR.4 for
   Extension Type, which will always be 1 in recent processors with UMIP;
   CR.5 for Numeric Error, CR0.16 for Write Protect, CR0.18 for Alignment
   Mask. As per the Intel 64 and IA-32 Architectures Software Developer's
   Manual, SMSW returns a 16-bit results for memory operands. However, when
   the operand is a register, the results can be up to CR0[63:0]. Since
   the emulation code only kicks-in in x86_32, we return up to CR[31:0].
 * The proposed emulation code is handles faults that happens in both
   protected and virtual-8086 mode.
 * Again, STR and SLDT are not emulated.

=== How is this series laid out?

++ Preparatory work
As per suggestions from Andy Lutormirsky and Borislav Petkov, I moved
the x86 page fault error codes to a header. Also, I made user_64bit_mode
available to x86_32 builds. This helps to reuse code and reduce the number
of #ifdef's in these patches.

++ Fix bugs in MPX address evaluator
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 library file that both MPX and UMIP can access and avoid code
duplication. Before creating the new library, I fixed a