Hi All,
I am working on implementing support for a new feature in the Linux kernel named User-Mode Instruction Prevention that will be present in upcoming Intel processors. In a nutshell, if this feature is present and enabled, a general protection fault will happen if any of the following instructions is executed with CPL > 0.
* SGDT - Store Global Descriptor Table * SIDT - Store Interrupt Descriptor Table * SLDT - Store Local Descriptor Table * SMSW - Store Machine Status Word * STR - Store Task Register
The goal of this feature is to prevent user space applications to read the resources mentioned above. For instance, a user-space application could easily read the descriptor tables and use that to instrument an attack.
I am aware that maybe wine (or applications using wine) might want to use some of these instructions. For instance, wine might want to use the sgdt instruction to emulate the VxD driver model.
Currently the proposed implementation is as follows:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
Your feedback will be greatly appreciated. You can see the original patch post here [1].
http://www.spinics.net/lists/kernel/msg2377725.html
Thanks and BR, Ricardo
Hi All,
On Wed, 2016-11-16 at 04:09 +0000, Neri, Ricardo wrote:
Hi All,
I am working on implementing support for a new feature in the Linux kernel named User-Mode Instruction Prevention that will be present in upcoming Intel processors. In a nutshell, if this feature is present and enabled, a general protection fault will happen if any of the following instructions is executed with CPL > 0.
- SGDT - Store Global Descriptor Table
- SIDT - Store Interrupt Descriptor Table
- SLDT - Store Local Descriptor Table
- SMSW - Store Machine Status Word
- STR - Store Task Register
The goal of this feature is to prevent user space applications to read the resources mentioned above. For instance, a user-space application could easily read the descriptor tables and use that to instrument an attack.
I am aware that maybe wine (or applications using wine) might want to use some of these instructions. For instance, wine might want to use the sgdt instruction to emulate the VxD driver model.
Currently the proposed implementation is as follows:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
Your feedback will be greatly appreciated. You can see the original patch post here [1].
Checking again if any of you have comments on this. I am planning on a new submissions to Linux based on the approach given above.
Thanks and BR, Ricardo
http://www.spinics.net/lists/kernel/msg2377725.html
Thanks and BR, Ricardo
"Neri, Ricardo" ricardo.neri@intel.com writes:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
There are apps that use these instructions, so we'll need to catch and emulate them in the segfault handler. We have the infrastructure in place for that sort of thing so it shouldn't be hard. It does mean that these apps would get broken until users upgrade Wine though.
On Fri, 2016-11-18 at 10:56 -0600, Alexandre Julliard wrote:
"Neri, Ricardo" ricardo.neri@intel.com writes:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
There are apps that use these instructions, so we'll need to catch and emulate them in the segfault handler. We have the infrastructure in place for that sort of thing so it shouldn't be hard. It does mean that these apps would get broken until users upgrade Wine though.
Thanks for the feedback. The consensus in the kernel mailing list is to catch the gp fault within the kernel and give the userspace fake values for the GDT, LDT, IDT and the MSW (I don't think there are vm86 apps that use the task register, are they?). This is because the goal of the feature is to hide these tables from the user space. Would this be a problem?
"Neri, Ricardo" ricardo.neri@intel.com writes:
On Fri, 2016-11-18 at 10:56 -0600, Alexandre Julliard wrote:
"Neri, Ricardo" ricardo.neri@intel.com writes:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
There are apps that use these instructions, so we'll need to catch and emulate them in the segfault handler. We have the infrastructure in place for that sort of thing so it shouldn't be hard. It does mean that these apps would get broken until users upgrade Wine though.
Thanks for the feedback. The consensus in the kernel mailing list is to catch the gp fault within the kernel and give the userspace fake values for the GDT, LDT, IDT and the MSW (I don't think there are vm86 apps that use the task register, are they?). This is because the goal of the feature is to hide these tables from the user space. Would this be a problem?
That sort of depends on what fake values you are returning. Currently we rely on SIDT returning a non-accessible address, in order to catch the resulting memory accesses and fake the IDT contents.
Note that the apps I'm talking about are not DOS apps running in vm86 mode, but Windows binaries running in protected mode, so if the emulation is only for vm86 mode they would still get broken.
There may also be issues with DOS apps in vm86 mode of course, but we normally forward these to DOSBox now, so it's no longer much of a concern for Wine.
On Fri, 2016-11-18 at 14:16 -0600, Alexandre Julliard wrote:
"Neri, Ricardo" ricardo.neri@intel.com writes:
On Fri, 2016-11-18 at 10:56 -0600, Alexandre Julliard wrote:
"Neri, Ricardo" ricardo.neri@intel.com writes:
If running in protected mode, always propagate the GP fault to the user space via a sigsegv. If running in vm86 mode, trap the GP fault within the kernel and give the userspace fake values for the aforementioned resources (most likely zeros).
Also, UMIP will be able to be disabled via a kernel command-line parameter at boot.
I would like to inquire about the current use of these instructions and whether it would be catastrophic for wine to lose access to them.
There are apps that use these instructions, so we'll need to catch and emulate them in the segfault handler. We have the infrastructure in place for that sort of thing so it shouldn't be hard. It does mean that these apps would get broken until users upgrade Wine though.
Thanks for the feedback. The consensus in the kernel mailing list is to catch the gp fault within the kernel and give the userspace fake values for the GDT, LDT, IDT and the MSW (I don't think there are vm86 apps that use the task register, are they?). This is because the goal of the feature is to hide these tables from the user space. Would this be a problem?
That sort of depends on what fake values you are returning. Currently we rely on SIDT returning a non-accessible address, in order to catch the resulting memory accesses and fake the IDT contents.
I see. Would a null address suffice? That would be non-accessible.
Note that the apps I'm talking about are not DOS apps running in vm86 mode, but Windows binaries running in protected mode, so if the emulation is only for vm86 mode they would still get broken.
This is good to know. I will look into emulating these instructions for protected mode as well.
There may also be issues with DOS apps in vm86 mode of course, but we normally forward these to DOSBox now, so it's no longer much of a concern for Wine.
Uh I see. Maybe I can look into trapping the fault for both vm86 and protected mode. I will also check with the DOSBox team.
"Neri, Ricardo" ricardo.neri@intel.com writes:
On Fri, 2016-11-18 at 14:16 -0600, Alexandre Julliard wrote:
"Neri, Ricardo" ricardo.neri@intel.com writes:
Thanks for the feedback. The consensus in the kernel mailing list is to catch the gp fault within the kernel and give the userspace fake values for the GDT, LDT, IDT and the MSW (I don't think there are vm86 apps that use the task register, are they?). This is because the goal of the feature is to hide these tables from the user space. Would this be a problem?
That sort of depends on what fake values you are returning. Currently we rely on SIDT returning a non-accessible address, in order to catch the resulting memory accesses and fake the IDT contents.
I see. Would a null address suffice? That would be non-accessible.
That wouldn't work, because we'd have no way of knowing that this was an attempted IDT access and not a normal null pointer. We rely on SIDT returning a unique address that we can recognize once we get an access violation fault for it.
It seems to me that in general, forwarding the fault to user-mode would be a more useful behavior than emulating it. Maybe it could be made opt-in somehow to avoid breaking existing apps.