[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <f297a1e42ed17a86ba92350e46c1e36db05bdc56.1438061139.git.luto@kernel.org>
Date: Mon, 27 Jul 2015 22:29:38 -0700
From: Andy Lutomirski <luto@...nel.org>
To: Peter Zijlstra <peterz@...radead.org>,
Steven Rostedt <rostedt@...dmis.org>
Cc: "security@...nel.org" <security@...nel.org>,
X86 ML <x86@...nel.org>, Borislav Petkov <bp@...en8.de>,
Sasha Levin <sasha.levin@...cle.com>,
linux-kernel@...r.kernel.org,
Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>,
Boris Ostrovsky <boris.ostrovsky@...cle.com>,
Andrew Cooper <andrew.cooper3@...rix.com>,
Jan Beulich <jbeulich@...e.com>,
xen-devel <xen-devel@...ts.xen.org>,
Andy Lutomirski <luto@...nel.org>, stable@...r.kernel.org
Subject: [PATCH v5 1/4] x86/xen: Unmap aliases in xen_alloc_ldt and xen_free_ldt
I've been able to get an unmodified Xen guest to OOPS once after a
lot of test iterations without this patch. I think this patch fixes
the problem. I'm a bit surprised that we don't see much more severe
LDT problems on Xen without this fix.
Once the synchronous modify_ldt code causes modify_ldt to more
aggressively reallocate the LDT, the OOPSes become much more common
without this fix.
Cc: stable@...r.kernel.org
Signed-off-by: Andy Lutomirski <luto@...nel.org>
---
arch/x86/xen/enlighten.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 0b95c9b8283f..e417d08c56c4 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -32,6 +32,7 @@
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/edd.h>
+#include <linux/vmalloc.h>
#include <xen/xen.h>
#include <xen/events.h>
@@ -512,6 +513,10 @@ static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
for(i = 0; i < entries; i += entries_per_page)
set_aliased_prot(ldt + i, PAGE_KERNEL_RO);
+
+ /* If there are stray aliases, the LDT won't work. */
+ if (is_vmalloc_addr(ldt))
+ vm_unmap_aliases();
}
static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)
@@ -519,6 +524,13 @@ static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)
const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
int i;
+ /*
+ * The set_aliased_prot call may OOPS due to a hypercall failure
+ * if there are any lazy vmap aliases of the page. We don't
+ * need to call vm_unmap_aliases() here, though, because we
+ * already eliminated any aliases in xen_alloc_ldt.
+ */
+
for(i = 0; i < entries; i += entries_per_page)
set_aliased_prot(ldt + i, PAGE_KERNEL);
}
--
2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists