[x86] iopl/64: properly context-switch IOPL on Xen PV (CVE-2016-3157)

This commit is contained in:
Salvatore Bonaccorso 2016-03-17 18:20:19 +01:00
parent 5b884b50ae
commit 962c3c4a6f
3 changed files with 91 additions and 0 deletions

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
linux (4.4.6-2) UNRELEASED; urgency=medium
[ Salvatore Bonaccorso ]
* [x86] iopl/64: properly context-switch IOPL on Xen PV (CVE-2016-3157)
-- Salvatore Bonaccorso <carnil@debian.org> Thu, 17 Mar 2016 18:19:26 +0100
linux (4.4.6-1) unstable; urgency=medium
[ Salvatore Bonaccorso ]

View File

@ -0,0 +1,83 @@
From 91b210501e1bc7518a44d24526f223375bf3d039 Mon Sep 17 00:00:00 2001
From: Andy Lutomirski <luto@kernel.org>
Date: Thu, 17 Mar 2016 17:55:31 +0100
Origin: http://xenbits.xen.org/xsa/xsa171.patch
Subject: x86/iopl/64: properly context-switch IOPL on Xen PV
On Xen PV, regs->flags doesn't reliably reflect IOPL and the
exit-to-userspace code doesn't change IOPL. We need to context
switch it manually.
I'm doing this without going through paravirt because this is
specific to Xen PV. After the dust settles, we can merge this with
the 32-bit code, tidy up the iopl syscall implementation, and remove
the set_iopl pvop entirely.
This is XSA-171.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: stable@vger.kernel.org
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
arch/x86/include/asm/xen/hypervisor.h | 2 ++
arch/x86/kernel/process_64.c | 12 ++++++++++++
arch/x86/xen/enlighten.c | 2 +-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index 8b2d4be..7b87b3c 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num);
void xen_arch_unregister_cpu(int num);
#endif
+void xen_set_iopl_mask(unsigned mask);
+
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e835d26..4cbb60f 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -48,6 +48,7 @@
#include <asm/syscalls.h>
#include <asm/debugreg.h>
#include <asm/switch_to.h>
+#include <asm/xen/hypervisor.h>
asmlinkage extern void ret_from_fork(void);
@@ -411,6 +412,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
__switch_to_xtra(prev_p, next_p, tss);
+#ifdef CONFIG_XEN
+ /*
+ * On Xen PV, IOPL bits in pt_regs->flags have no effect, and
+ * current_pt_regs()->flags may not match the current task's
+ * intended IOPL. We need to switch it manually.
+ */
+ if (unlikely(static_cpu_has(X86_FEATURE_XENPV) &&
+ prev->iopl != next->iopl))
+ xen_set_iopl_mask(next->iopl);
+#endif
+
if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
/*
* AMD CPUs have a misfeature: SYSRET sets the SS selector but
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b7de78b..beab8c7 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -961,7 +961,7 @@ static void xen_load_sp0(struct tss_struct *tss,
tss->x86_tss.sp0 = thread->sp0;
}
-static void xen_set_iopl_mask(unsigned mask)
+void xen_set_iopl_mask(unsigned mask)
{
struct physdev_set_iopl set_iopl;
--
2.8.0.rc3

View File

@ -138,3 +138,4 @@ debian/module-fix-abi-change-in-4.4.5.patch
bugfix/x86/x86-efi-fix-boot-crash-by-always-mapping-boot-servic.patch
bugfix/x86/x86-mm-pat-fix-boot-crash-when-1gb-pages-are-not-supported.patch
bugfix/all/netfilter-x_tables-check-for-size-overflow.patch
bugfix/x86/x86-iopl-64-properly-context-switch-IOPL-on-Xen-PV.patch