From: Ian.Campbell@xensource.com Date: Fri, 13 Jan 2006 11:04:04 +0000 (+0000) Subject: Fix x86/32 do_iret implementation, fixes VM86 mode. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16541^2~48 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=dd38458519384dff33252ae76889e08d5dbe7a18;p=xen.git Fix x86/32 do_iret implementation, fixes VM86 mode. Do not clobber a freshly restored esp when performing an iret. Signed-off-by: Keir Fraser Signed-off-by: Ian Campbell --- diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index e9c98d8aa8..95b69a14bd 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -157,14 +157,6 @@ asmlinkage void do_double_fault(void) __asm__ __volatile__ ( "hlt" ); } -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)) ) - domain_crash_synchronous(); - regs->esp += bytes; -} - asmlinkage unsigned long do_iret(void) { struct cpu_user_regs *regs = guest_cpu_user_regs(); @@ -175,22 +167,29 @@ asmlinkage unsigned long do_iret(void) domain_crash_synchronous(); /* Pop and restore EAX (clobbered by hypercall). */ - pop_from_guest_stack(®s->eax, regs, 4); + if ( unlikely(__copy_from_user(®s->eax, (void __user *)regs->esp, 4)) ) + domain_crash_synchronous(); + regs->esp += 4; /* Pop and restore CS and EIP. */ - pop_from_guest_stack(®s->eip, regs, 8); + if ( unlikely(__copy_from_user(®s->eip, (void __user *)regs->esp, 8)) ) + domain_crash_synchronous(); + regs->esp += 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); + if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) ) + domain_crash_synchronous(); + regs->esp += 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); + if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 24) ) + domain_crash_synchronous(); } else if ( unlikely(RING_0(regs)) ) { @@ -199,7 +198,8 @@ asmlinkage unsigned long do_iret(void) else if ( !RING_1(regs) ) { /* Return to ring 2/3: pop and restore ESP and SS. */ - pop_from_guest_stack(®s->esp, regs, 8); + if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 8) ) + domain_crash_synchronous(); } /* No longer in NMI context. */