From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
To: Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
"H. Peter Anvin" <hpa@zytor.com>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
linux-doc@vger.kernel.org,
Ricardo Neri <ricardo.neri-calderon@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Borislav Petkov <bp@suse.de>, Brian Gerst <brgerst@gmail.com>,
Chen Yucong <slaoub@gmail.com>,
Chris Metcalf <cmetcalf@mellanox.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Fenghua Yu <fenghua.yu@intel.com>, Huang Rui <ray.huang@amd.com>,
Jiri Slaby <jslaby@suse.cz>, Jonathan Corbet <corbet@lwn.net>,
"Michael S . Tsirkin" <mst@redhat.com>,
Paul Gortmaker <paul.gortmaker@windriver.com>,
Peter Zijlstra <peterz@infradead.org>,
"Ravi V . Shankar" <ravi.v.shankar@intel.com>,
Shuah Khan <shuah@kernel.org>, Vlastimil Babka <vbabka@suse.cz>
Subject: [PATCH 2/4] x86: Prepare vm86 tasks to handle User-Mode Instruction Prevention
Date: Mon, 7 Nov 2016 22:12:11 -0800 [thread overview]
Message-ID: <1478585533-19406-3-git-send-email-ricardo.neri-calderon@linux.intel.com> (raw)
In-Reply-To: <1478585533-19406-1-git-send-email-ricardo.neri-calderon@linux.intel.com>
User-Mode Instruction Prevention (UMIP) is a security feature in new Intel
processors that causes a general protection exception if certain
instructions are executed in user mode (CPL > 0).
Unfortunately, some of the instructions that are protected by UMIP (i.e.,
SGDT, SIDT and SMSW) are used by certain applications running in virtual-
8086 mode (e.g., DOSEMU and Wine). Thus, UMIP needs to be disabled in
virtual-8086 tasks for such applications to run correctly. However,
unconditionally disabling UMIP for virtual-8086 tasks could be abused by
malicious applcations. Hence, UMIP can only be disabled for this particular
kind of tasks if requested at boot time via vm86_disable_x86_umip.
If disabling UMIP is allowed, it is done in the following two code paths:
1) entering virtual-8086 mode via a system call, and 2) task switch. When
For task-switching a new member is added to struct vm86 to keep track of
the UMIP disabling selection; set in the vm86 system call as per the the
selection made at boot time.
If supported by the CPU, UMIP is re-enabled as soon as we exit virtual-8086
mode via interrupt/exception or task switch. To determine that we switch to
a virtual-8086 mode task, we rely in the fact that virtual-8086 mode tasks
keep a copy of the value of the supervisor mode stack pointer prior to
entering in virtual-8086 mode.
Since the X86_UMIP config option is not defined yet, this code remains
dormant until such option is enabled in a subsequent patch. Such patch will
also introduce code to disable UMIP for virtual-8086 tasks via a kernel
parameter.
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Chen Yucong <slaoub@gmail.com>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Huang Rui <ray.huang@amd.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi V. Shankar <ravi.v.shankar@intel.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
arch/x86/include/asm/vm86.h | 3 +++
arch/x86/kernel/process.c | 10 ++++++++++
arch/x86/kernel/vm86_32.c | 20 ++++++++++++++++++++
3 files changed, 33 insertions(+)
diff --git a/arch/x86/include/asm/vm86.h b/arch/x86/include/asm/vm86.h
index 1e491f3..bd14cbc 100644
--- a/arch/x86/include/asm/vm86.h
+++ b/arch/x86/include/asm/vm86.h
@@ -40,6 +40,7 @@ struct vm86 {
struct revectored_struct int_revectored;
struct revectored_struct int21_revectored;
struct vm86plus_info_struct vm86plus;
+ bool disable_x86_umip;
};
#ifdef CONFIG_VM86
@@ -47,6 +48,7 @@ struct vm86 {
void handle_vm86_fault(struct kernel_vm86_regs *, long);
int handle_vm86_trap(struct kernel_vm86_regs *, long, int);
void save_v86_state(struct kernel_vm86_regs *, int);
+void __init vm86_disable_x86_umip(void);
struct task_struct;
@@ -76,6 +78,7 @@ void release_vm86_irqs(struct task_struct *);
#define handle_vm86_fault(a, b)
#define release_vm86_irqs(a)
+#define vm86_disable_x86_umip()
static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c)
{
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 0888a87..32b7301 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -233,6 +233,16 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
*/
memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
}
+
+#if defined(CONFIG_VM86) && defined(CONFIG_X86_INTEL_UMIP)
+ if (next->vm86 && next->vm86->saved_sp0 && next->vm86->disable_x86_umip)
+ cr4_clear_bits(X86_CR4_UMIP);
+ else {
+ if (static_cpu_has(X86_FEATURE_UMIP))
+ cr4_set_bits(X86_CR4_UMIP);
+ }
+#endif
+
propagate_user_return_notify(prev_p, next_p);
}
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 01f30e5..7fd22e7 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -90,6 +90,14 @@
#define SAFE_MASK (0xDD5)
#define RETURN_MASK (0xDFF)
+static bool disable_x86_umip;
+
+void __init vm86_disable_x86_umip(void)
+{
+ if (cpu_feature_enabled(X86_FEATURE_UMIP))
+ disable_x86_umip = true;
+}
+
void save_v86_state(struct kernel_vm86_regs *regs, int retval)
{
struct tss_struct *tss;
@@ -156,6 +164,12 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)
lazy_load_gs(vm86->regs32.gs);
regs->pt.ax = retval;
+
+
+ /* Always enable UMIP if supported */
+ if (cpu_feature_enabled(X86_FEATURE_UMIP) &&
+ static_cpu_has(X86_FEATURE_UMIP))
+ cr4_set_bits(X86_CR4_UMIP);
}
static void mark_screen_rdonly(struct mm_struct *mm)
@@ -371,6 +385,12 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
if (vm86->flags & VM86_SCREEN_BITMAP)
mark_screen_rdonly(tsk->mm);
+ if (cpu_feature_enabled(X86_FEATURE_UMIP)) {
+ vm86->disable_x86_umip = disable_x86_umip;
+ if (disable_x86_umip)
+ cr4_clear_bits(X86_CR4_UMIP);
+ }
+
memcpy((struct kernel_vm86_regs *)regs, &vm86regs, sizeof(vm86regs));
force_iret();
return regs->ax;
--
2.7.4
next prev parent reply other threads:[~2016-11-08 6:13 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-08 6:12 [PATCH 0/4] x86: enable " Ricardo Neri
2016-11-08 6:12 ` [PATCH 1/4] x86/cpufeature: Add User-Mode Instruction Prevention definitions Ricardo Neri
2016-11-08 15:32 ` Andy Lutomirski
2016-11-09 4:25 ` Ricardo Neri
2016-11-09 11:02 ` Andy Lutomirski
2016-11-10 3:24 ` Ricardo Neri
2016-11-10 8:58 ` Borislav Petkov
2016-11-11 4:08 ` Ricardo Neri
2016-11-11 10:22 ` Borislav Petkov
2016-11-12 1:24 ` Ricardo Neri
2016-11-11 18:06 ` Dave Hansen
2016-11-10 17:09 ` Dave Hansen
2016-11-08 6:12 ` Ricardo Neri [this message]
2016-11-08 16:01 ` [PATCH 2/4] x86: Prepare vm86 tasks to handle User-Mode Instruction Prevention Andy Lutomirski
2016-11-08 17:00 ` Peter Zijlstra
2016-11-09 4:26 ` Ricardo Neri
2016-11-08 6:12 ` [PATCH 3/4] x86: Enable " Ricardo Neri
2016-11-08 6:12 ` [PATCH 4/4] selftests/x86: Add tests for " Ricardo Neri
2016-11-08 13:16 ` [PATCH 0/4] x86: enable " Peter Zijlstra
2016-11-08 15:34 ` Andy Lutomirski
2016-11-08 16:52 ` Thomas Gleixner
2016-11-09 4:26 ` Ricardo Neri
2016-11-09 4:31 ` Ricardo Neri
2016-11-09 11:05 ` Andy Lutomirski
2016-11-10 6:46 ` Ricardo Neri
2016-11-10 8:52 ` Stas Sergeev
2016-11-11 4:14 ` Ricardo Neri
2016-11-11 20:51 ` Stas Sergeev
2016-11-12 1:29 ` Ricardo Neri
2016-11-14 10:59 ` One Thousand Gnomes
2016-11-14 18:36 ` Harald Arnesen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1478585533-19406-3-git-send-email-ricardo.neri-calderon@linux.intel.com \
--to=ricardo.neri-calderon@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=bp@suse.de \
--cc=brgerst@gmail.com \
--cc=cmetcalf@mellanox.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=jslaby@suse.cz \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@kernel.org \
--cc=mst@redhat.com \
--cc=paul.gortmaker@windriver.com \
--cc=peterz@infradead.org \
--cc=ravi.v.shankar@intel.com \
--cc=ray.huang@amd.com \
--cc=shuah@kernel.org \
--cc=slaoub@gmail.com \
--cc=tglx@linutronix.de \
--cc=vbabka@suse.cz \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®