]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.xen/870-i386-critical-section.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.xen / 870-i386-critical-section.patch
diff --git a/src/patches/suse-2.6.27.31/patches.xen/870-i386-critical-section.patch b/src/patches/suse-2.6.27.31/patches.xen/870-i386-critical-section.patch
new file mode 100644 (file)
index 0000000..2d7b7f8
--- /dev/null
@@ -0,0 +1,129 @@
+From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/9b9454800544
+# HG changeset 870 patch
+# User Keir Fraser <keir.fraser@citrix.com>
+# Date 1242292120 -3600
+# Node ID 9b945480054430882b60bb5e5f660822a1c07b70
+# Parent  271d9b9bee40657b1714b2bb62531e989c7b5813
+Subject: i386: hypervisor_callback adjustments
+References: bnc#503457 CVE-2009-1758
+Patch-mainline: obsolete
+
+The missing check of the interrupted code's code selector in
+hypervisor_callback() allowed a user mode application to oops (and
+perhaps crash) the kernel.
+
+Further adjustments:
+- the 'main' critical region does not include the jmp following the
+  disabling of interrupts
+- the sysexit_[se]crit range checks got broken at some point - the
+  sysexit ciritcal region is always at higher addresses than the
+  'main'
+  one, yielding the check pointless (but consuming execution time);
+  since the supervisor mode kernel isn't actively used afaict, I moved
+  that code into an #ifdef using a hypothetical config option
+- the use of a numeric label across more than 300 lines of code always
+  seemed pretty fragile to me, so the patch replaces this with a local
+  named label
+- streamlined the critical_region_fixup code to eliminate a branch
+
+Signed-off-by: Jan Beulich <jbeulich@novell.com>
+
+--- sle11-2009-05-14.orig/arch/x86/kernel/entry_32-xen.S       2009-05-15 08:44:13.000000000 +0200
++++ sle11-2009-05-14/arch/x86/kernel/entry_32-xen.S    2009-05-15 08:45:36.000000000 +0200
+@@ -529,8 +529,8 @@ scrit:     /**** START OF CRITICAL REGION **
+ .previous
+ 14:   __DISABLE_INTERRUPTS
+       TRACE_IRQS_OFF
+-      jmp  11f
+ ecrit:  /**** END OF CRITICAL REGION ****/
++      jmp  .Ldo_upcall
+       CFI_RESTORE_STATE
+ hypervisor_iret:
+@@ -788,17 +788,23 @@ ENTRY(hypervisor_callback)
+       pushl %eax
+       CFI_ADJUST_CFA_OFFSET 4
+       SAVE_ALL
++      testb $2,CS(%esp)
+       movl EIP(%esp),%eax
++      jnz  .Ldo_upcall
+       cmpl $scrit,%eax
+-      jb   11f
++      jb   0f
+       cmpl $ecrit,%eax
+       jb   critical_region_fixup
++0:
++#ifdef CONFIG_XEN_SUPERVISOR_MODE_KERNEL
+       cmpl $sysexit_scrit,%eax
+-      jb   11f
++      jb   .Ldo_upcall
+       cmpl $sysexit_ecrit,%eax
+-      ja   11f
++      ja   .Ldo_upcall
+       addl $OLDESP,%esp               # Remove eflags...ebx from stack frame.
+-11:   push %esp
++#endif
++.Ldo_upcall:
++      push %esp
+       CFI_ADJUST_CFA_OFFSET 4
+       call evtchn_do_upcall
+       add  $4,%esp
+@@ -814,39 +820,35 @@ ENTRY(hypervisor_callback)
+ # provides the number of bytes which have already been popped from the
+ # interrupted stack frame.
+ critical_region_fixup:
+-      movzbl critical_fixup_table-scrit(%eax),%ecx # %eax contains num bytes popped
+-      cmpb $0xff,%cl                  # 0xff => vcpu_info critical region
+-      jne  15f
+-      xorl %ecx,%ecx
+-15:   leal (%esp,%ecx),%esi           # %esi points at end of src region
++      movsbl critical_fixup_table-scrit(%eax),%ecx # %ecx contains num slots popped
++      testl %ecx,%ecx
++      leal (%esp,%ecx,4),%esi         # %esi points at end of src region
+       leal OLDESP(%esp),%edi          # %edi points at end of dst region
+-      shrl $2,%ecx                    # convert words to bytes
+-      je   17f                        # skip loop if nothing to copy
++      jle   17f                       # skip loop if nothing to copy
+ 16:   subl $4,%esi                    # pre-decrementing copy loop
+       subl $4,%edi
+       movl (%esi),%eax
+       movl %eax,(%edi)
+       loop 16b
+ 17:   movl %edi,%esp                  # final %edi is top of merged stack
+-      jmp  11b
++      jmp  .Ldo_upcall
+ .section .rodata,"a"
+ critical_fixup_table:
+-      .byte 0xff,0xff,0xff            # testb $0xff,(%esi) = __TEST_PENDING
+-      .byte 0xff,0xff                 # jnz  14f
+-      .byte 0x00                      # pop  %ebx
+-      .byte 0x04                      # pop  %ecx
+-      .byte 0x08                      # pop  %edx
+-      .byte 0x0c                      # pop  %esi
+-      .byte 0x10                      # pop  %edi
+-      .byte 0x14                      # pop  %ebp
+-      .byte 0x18                      # pop  %eax
+-      .byte 0x1c                      # pop  %ds
+-      .byte 0x20                      # pop  %es
+-      .byte 0x24,0x24,0x24            # add  $4,%esp
+-      .byte 0x28                      # iret
+-      .byte 0xff,0xff,0xff,0xff       # movb $1,1(%esi)
+-      .byte 0x00,0x00                 # jmp  11b
++      .byte -1,-1,-1                  # testb $0xff,(%esi) = __TEST_PENDING
++      .byte -1,-1                     # jnz  14f
++      .byte 0                         # pop  %ebx
++      .byte 1                         # pop  %ecx
++      .byte 2                         # pop  %edx
++      .byte 3                         # pop  %esi
++      .byte 4                         # pop  %edi
++      .byte 5                         # pop  %ebp
++      .byte 6                         # pop  %eax
++      .byte 7                         # pop  %ds
++      .byte 8                         # pop  %es
++      .byte 9,9,9                     # add  $4,%esp
++      .byte 10                        # iret
++      .byte -1,-1,-1,-1               # movb $1,1(%esi) = __DISABLE_INTERRUPTS
+ .previous
+ # Hypervisor uses this for application faults while it executes.