Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4055

kernel-2.6.18-194.11.1.el5.src.rpm

From: Chris Lalancette <clalance@redhat.com>
Date: Wed, 20 May 2009 09:16:05 +0200
Subject: [x86] xen: fix local denial of service
Message-id: 4A13AE35.4070804@redhat.com
O-Subject: [RHEL5 PATCH]: Fix Xen local denial of service
Bugzilla: 500951
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Don Dutile <ddutile@redhat.com>
RH-Acked-by: Rik van Riel <riel@redhat.com>

All,
     With the current RHEL-5 kernel, it's possible for a rogue user application
to cause a kernel crash.  If a 32-bit application tried to access a memory
location between the scrit and ecrit symbols in the kernel, instead of a
receiving SEGV it could instead crash the kernel.

This happens because of insufficient checking in the hypervisor_callback path,
where it was forgetting to check the CS during entry.  In order to fix this,
I've backported linux-2.6.18-xen.hg c/s 870.  Note that the upstream changeset
does much more than just this bugfix; it also renames some jump points and
optimizes some of the code in critical_region_fixup.  Because we have quite
different code in the critical_region_fixup path, and because I don't think we
should necessarily optimize this at the same time, I elected to go with the
minimal fix, which is attached.

Tested by me on an i386 Xen guest.  Before the patch, running the reproducer in
the BZ would crash the guest 50% of the time.  After the patch, running the
reproducer in the BZ would always SEGV the application.

This should solve BZ 500949.  Please review and ACK.

--
Chris Lalancette

diff --git a/arch/i386/kernel/entry-xen.S b/arch/i386/kernel/entry-xen.S
index 3e7ebd7..ea89966 100644
--- a/arch/i386/kernel/entry-xen.S
+++ b/arch/i386/kernel/entry-xen.S
@@ -735,11 +735,15 @@ ENTRY(hypervisor_callback)
 	pushl %eax
 	CFI_ADJUST_CFA_OFFSET 4
 	SAVE_ALL
+	testb $2,CS(%esp)
 	movl EIP(%esp),%eax
+	jnz  11f
 	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
 	cmpl $sysexit_ecrit,%eax
@@ -748,6 +752,7 @@ ENTRY(hypervisor_callback)
 	addl $0x34,%esp			# Remove cs...ebx from stack frame.
 	# this popped off new frame to reuse the old one, therefore no 
 	# CFI_ADJUST_CFA_OFFSET here
+#endif
 11:	push %esp
 	CFI_ADJUST_CFA_OFFSET 4
 	call evtchn_do_upcall