aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/lguest.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-08-09 06:57:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-09 11:14:56 -0400
commit0d027c01cd36b8cff727c78d2e40d334ba9895a8 (patch)
tree21dde51409ab83cbb3ce7200393b3a0acb76388d /drivers/lguest/lguest.c
parent37250097e1b730c30da1790e354c0da65e617043 (diff)
lguest: Fix Malicious Guest GDT Host Crash
If a Guest makes hypercall which sets a GDT entry to not present, we currently set any segment registers using that GDT entry to 0. Unfortunately, this is not sufficient: there are other ways of altering GDT entries which will cause a fault. The correct solution to do what Linux does: let them set any GDT value they want and handle the #GP when popping causes a fault. This has the added benefit of making our Switcher slightly more robust in the case of any other bugs which cause it to fault. We kill the Guest if it causes a fault in the Switcher: it's the Guest's responsibility to make sure it's not using segments when it changes them. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/lguest/lguest.c')
-rw-r--r--drivers/lguest/lguest.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c
index fb17d2757be9..524beea7fb19 100644
--- a/drivers/lguest/lguest.c
+++ b/drivers/lguest/lguest.c
@@ -323,9 +323,12 @@ static void lguest_write_gdt_entry(struct desc_struct *dt,
323 * __thread variables). So we have a hypercall specifically for this case. */ 323 * __thread variables). So we have a hypercall specifically for this case. */
324static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) 324static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
325{ 325{
326 /* There's one problem which normal hardware doesn't have: the Host
327 * can't handle us removing entries we're currently using. So we clear
328 * the GS register here: if it's needed it'll be reloaded anyway. */
329 loadsegment(gs, 0);
326 lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0); 330 lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
327} 331}
328/*:*/
329 332
330/*G:038 That's enough excitement for now, back to ploughing through each of 333/*G:038 That's enough excitement for now, back to ploughing through each of
331 * the paravirt_ops (we're about 1/3 of the way through). 334 * the paravirt_ops (we're about 1/3 of the way through).