# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1e1107e3d894f0d5b844639bfc5edc145b81df6b
# Parent 1c186b28289bc03060e971e863719cbda62ab481
More do_iret() fixes. We need to take care in restoring
EFLAGS that we do not pull in non-zero IOPL, then crash
the domain, and then bug out when dom0 gets vcpu context.
This could otherwise be triggered by a malicious guest.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 1c186b28289b -r 1e1107e3d894 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Wed Jan 11 19:03:53 2006
+++ b/xen/arch/x86/x86_32/traps.c Wed Jan 11 19:14:27 2006
@@ -160,7 +160,7 @@
static inline void pop_from_guest_stack(
void *dst, struct cpu_user_regs *regs, unsigned int bytes)
{
- if ( unlikely(copy_from_user(dst, (void __user *)regs->esp, bytes)) )
+ if ( unlikely(__copy_from_user(dst, (void __user *)regs->esp, bytes)) )
domain_crash_synchronous();
regs->esp += bytes;
}
@@ -168,19 +168,31 @@
asmlinkage unsigned long do_iret(void)
{
struct cpu_user_regs *regs = guest_cpu_user_regs();
+ u32 eflags;
+
+ /* Check worst-case stack frame for overlap with Xen protected area. */
+ if ( unlikely(!access_ok(regs->esp, 40)) )
+ domain_crash_synchronous();
/* Pop and restore EAX (clobbered by hypercall). */
pop_from_guest_stack(®s->eax, regs, 4);
- /* Pop and restore EFLAGS, CS and EIP. */
- pop_from_guest_stack(®s->eip, regs, 12);
+ /* Pop and restore CS and EIP. */
+ pop_from_guest_stack(®s->eip, regs, 8);
+
+ /*
+ * Pop, fix up and restore EFLAGS. We fix up in a local staging area
+ * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
+ */
+ pop_from_guest_stack(&eflags, regs, 4);
+ regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
if ( VM86_MODE(regs) )
{
/* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
pop_from_guest_stack(®s->esp, regs, 24);
}
- else if ( RING_0(regs) )
+ else if ( unlikely(RING_0(regs)) )
{
domain_crash_synchronous();
}
@@ -189,10 +201,6 @@
/* Return to ring 2/3: pop and restore ESP and SS. */
pop_from_guest_stack(®s->esp, regs, 8);
}
-
- /* Fixup EFLAGS. */
- regs->eflags &= ~X86_EFLAGS_IOPL;
- regs->eflags |= X86_EFLAGS_IF;
/* No longer in NMI context. */
clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|