summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Buchholz <rbu@gentoo.org>2007-10-10 09:49:41 +0000
committerRobert Buchholz <rbu@gentoo.org>2007-10-10 09:49:41 +0000
commite411b22225cc0a7467173cc72a772bbac007dccd (patch)
tree166c5b0e3d018b0ce2503d4e88452091ac685dae
parentDebian 2.6.18 1-13etch3 security patches (diff)
downloadxen-e411b22225cc0a7467173cc72a772bbac007dccd.tar.gz
xen-e411b22225cc0a7467173cc72a772bbac007dccd.tar.bz2
xen-e411b22225cc0a7467173cc72a772bbac007dccd.zip
Debian 2.6.18 1-13etch4 security patches
svn path=/patches/; revision=47
-rw-r--r--trunk/2.6.18/00000_README20
-rw-r--r--trunk/2.6.18/30037_amd64-zero-extend-32bit-ptrace-xen.patch50
-rw-r--r--trunk/2.6.18/30038_don-t-leak-nt-bit-into-next-task-xen.patch32
-rw-r--r--trunk/2.6.18/30039_hugetlb-prio_tree-unit-fix.patch85
-rw-r--r--trunk/2.6.18/30040_usb-pwc-disconnect-block.patch124
5 files changed, 311 insertions, 0 deletions
diff --git a/trunk/2.6.18/00000_README b/trunk/2.6.18/00000_README
index e49351c..27868b4 100644
--- a/trunk/2.6.18/00000_README
+++ b/trunk/2.6.18/00000_README
@@ -186,6 +186,26 @@ Patches
prevent incorrect permissions upon remount.
See CVE-2007-4849
+30037_amd64-zero-extend-32bit-ptrace-xen.patch
+ [SECURITY] Zero extend all registers after ptrace in 32-bit entry path
+ (Xen).
+ See CVE-2007-4573
+
+30038_don-t-leak-nt-bit-into-next-task-xen.patch
+ [SECURITY] Don't leak NT bit into next task (Xen).
+ See CVE-2006-5755
+
+30039_hugetlb-prio_tree-unit-fix.patch
+ [SECURITY] Fix misconversion of hugetlb_vmtruncate_list to prio_tree
+ which could be used to trigger a BUG_ON() call in exit_mmap.
+ See CVE-2007-4133
+
+30040_usb-pwc-disconnect-block.patch
+ [SECURITY] Fix issue with unplugging webcams that use the pwc driver.
+ If userspace still has the device open it can result, the driver would
+ wait for the device to close, blocking the USB subsystem.
+ See CVE-2007-5093
+
50001_make-install.patch
Handle make install in a semi-sane way that plays nice with
split domU/dom0 kernels.
diff --git a/trunk/2.6.18/30037_amd64-zero-extend-32bit-ptrace-xen.patch b/trunk/2.6.18/30037_amd64-zero-extend-32bit-ptrace-xen.patch
new file mode 100644
index 0000000..25e56d3
--- /dev/null
+++ b/trunk/2.6.18/30037_amd64-zero-extend-32bit-ptrace-xen.patch
@@ -0,0 +1,50 @@
+Adjusted to apply to Debian's 2.6.18 Xen
+
+--- linux-source-2.6.18.orig/arch/x86_64/ia32/ia32entry-xen.S 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/arch/x86_64/ia32/ia32entry-xen.S 2007-09-25 00:10:16.089100799 -0600
+@@ -38,6 +38,18 @@
+ #define __sti sti
+ #endif
+
++ .macro LOAD_ARGS32 offset
++ movl \offset(%rsp),%r11d
++ movl \offset+8(%rsp),%r10d
++ movl \offset+16(%rsp),%r9d
++ movl \offset+24(%rsp),%r8d
++ movl \offset+40(%rsp),%ecx
++ movl \offset+48(%rsp),%edx
++ movl \offset+56(%rsp),%esi
++ movl \offset+64(%rsp),%edi
++ movl \offset+72(%rsp),%eax
++ .endm
++
+ .macro CFI_STARTPROC32 simple
+ CFI_STARTPROC \simple
+ CFI_UNDEFINED r8
+@@ -151,7 +163,7 @@ sysenter_tracesys:
+ movq $-ENOSYS,RAX(%rsp) /* really needed? */
+ movq %rsp,%rdi /* &pt_regs -> arg1 */
+ call syscall_trace_enter
+- LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
++ LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+ movl %ebp, %ebp
+ /* no need to do an access_ok check here because rbp has been
+@@ -253,7 +265,7 @@ cstar_tracesys:
+ movq $-ENOSYS,RAX(%rsp) /* really needed? */
+ movq %rsp,%rdi /* &pt_regs -> arg1 */
+ call syscall_trace_enter
+- LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
++ LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+ movl RSP-ARGOFFSET(%rsp), %r8d
+ /* no need to do an access_ok check here because r8 has been
+@@ -330,7 +342,7 @@ ia32_tracesys:
+ movq $-ENOSYS,RAX(%rsp) /* really needed? */
+ movq %rsp,%rdi /* &pt_regs -> arg1 */
+ call syscall_trace_enter
+- LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
++ LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+ jmp ia32_do_syscall
+ END(ia32_syscall)
diff --git a/trunk/2.6.18/30038_don-t-leak-nt-bit-into-next-task-xen.patch b/trunk/2.6.18/30038_don-t-leak-nt-bit-into-next-task-xen.patch
new file mode 100644
index 0000000..8ee7bc0
--- /dev/null
+++ b/trunk/2.6.18/30038_don-t-leak-nt-bit-into-next-task-xen.patch
@@ -0,0 +1,32 @@
+
+--- linux-2.6.18.6.orig/arch/x86_64/kernel/entry-xen.S
++++ linux-2.6.18.6/arch/x86_64/kernel/entry-xen.S
+@@ -146,6 +146,10 @@
+ /* rdi: prev */
+ ENTRY(ret_from_fork)
+ CFI_DEFAULT_STACK
++ push kernel_eflags(%rip)
++ CFI_ADJUST_CFA_OFFSET 4
++ popf # reset kernel eflags
++ CFI_ADJUST_CFA_OFFSET -4
+ call schedule_tail
+ GET_THREAD_INFO(%rcx)
+ testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
+--- linux-2.6.18.6.orig/arch/x86_64/kernel/setup64-xen.c
++++ linux-2.6.18.6/arch/x86_64/kernel/setup64-xen.c
+@@ -178,6 +178,8 @@ void __cpuinit check_efer(void)
+ }
+ }
+
++unsigned long kernel_eflags;
++
+ /*
+ * cpu_init() initializes state that is per-CPU. Some data is already
+ * initialized (naturally) in the bootstrap process, such as the GDT
+@@ -290,4 +292,6 @@ void __cpuinit cpu_init (void)
+ set_debugreg(0UL, 7);
+
+ fpu_init();
++
++ raw_local_save_flags(kernel_eflags);
+ }
diff --git a/trunk/2.6.18/30039_hugetlb-prio_tree-unit-fix.patch b/trunk/2.6.18/30039_hugetlb-prio_tree-unit-fix.patch
new file mode 100644
index 0000000..2b92bf0
--- /dev/null
+++ b/trunk/2.6.18/30039_hugetlb-prio_tree-unit-fix.patch
@@ -0,0 +1,85 @@
+From: Hugh Dickins <hugh@veritas.com>
+Date: Sat, 28 Oct 2006 17:38:43 +0000 (-0700)
+Subject: [PATCH] hugetlb: fix prio_tree unit
+X-Git-Tag: v2.6.19-rc4~50
+X-Git-Url: http://git.kernel.org/gitweb.cgi?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=856fc29505556cf263f3dcda2533cf3766c14ab6
+
+[PATCH] hugetlb: fix prio_tree unit
+
+hugetlb_vmtruncate_list was misconverted to prio_tree: its prio_tree is in
+units of PAGE_SIZE (PAGE_CACHE_SIZE) like any other, not HPAGE_SIZE (whereas
+its radix_tree is kept in units of HPAGE_SIZE, otherwise slots would be
+absurdly sparse).
+
+At first I thought the error benign, just calling __unmap_hugepage_range on
+more vmas than necessary; but on 32-bit machines, when the prio_tree is
+searched correctly, it happens to ensure the v_offset calculation won't
+overflow. As it stood, when truncating at or beyond 4GB, it was liable to
+discard pages COWed from lower offsets; or even to clear pmd entries of
+preceding vmas, triggering exit_mmap's BUG_ON(nr_ptes).
+
+Signed-off-by: Hugh Dickins <hugh@veritas.com>
+Cc: Adam Litke <agl@us.ibm.com>
+Cc: David Gibson <david@gibson.dropbear.id.au>
+Cc: "Chen, Kenneth W" <kenneth.w.chen@intel.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+---
+
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index 0b23b96..0bea6a6 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -271,26 +271,24 @@ static void hugetlbfs_drop_inode(struct inode *inode)
+ hugetlbfs_forget_inode(inode);
+ }
+
+-/*
+- * h_pgoff is in HPAGE_SIZE units.
+- * vma->vm_pgoff is in PAGE_SIZE units.
+- */
+ static inline void
+-hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
++hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
+ {
+ struct vm_area_struct *vma;
+ struct prio_tree_iter iter;
+
+- vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
+- unsigned long h_vm_pgoff;
++ vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
+ unsigned long v_offset;
+
+- h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
+- v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT;
+ /*
+- * Is this VMA fully outside the truncation point?
++ * Can the expression below overflow on 32-bit arches?
++ * No, because the prio_tree returns us only those vmas
++ * which overlap the truncated area starting at pgoff,
++ * and no vma on a 32-bit arch can span beyond the 4GB.
+ */
+- if (h_vm_pgoff >= h_pgoff)
++ if (vma->vm_pgoff < pgoff)
++ v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT;
++ else
+ v_offset = 0;
+
+ __unmap_hugepage_range(vma,
+@@ -303,14 +301,14 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
+ */
+ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
+ {
+- unsigned long pgoff;
++ pgoff_t pgoff;
+ struct address_space *mapping = inode->i_mapping;
+
+ if (offset > inode->i_size)
+ return -EINVAL;
+
+ BUG_ON(offset & ~HPAGE_MASK);
+- pgoff = offset >> HPAGE_SHIFT;
++ pgoff = offset >> PAGE_SHIFT;
+
+ inode->i_size = offset;
+ spin_lock(&mapping->i_mmap_lock);
diff --git a/trunk/2.6.18/30040_usb-pwc-disconnect-block.patch b/trunk/2.6.18/30040_usb-pwc-disconnect-block.patch
new file mode 100644
index 0000000..679c7bc
--- /dev/null
+++ b/trunk/2.6.18/30040_usb-pwc-disconnect-block.patch
@@ -0,0 +1,124 @@
+From: Oliver Neukum <oneukum@suse.de>
+Date: Tue, 21 Aug 2007 05:10:42 +0000 (+0200)
+Subject: USB: fix DoS in pwc USB video driver
+X-Git-Tag: v2.6.23-rc4~29^2~8
+X-Git-Url: http://git.kernel.org/gitweb.cgi?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=85237f202d46d55c1bffe0c5b1aa3ddc0f1dce4d
+
+USB: fix DoS in pwc USB video driver
+
+the pwc driver has a disconnect method that waits for user space to
+close the device. This opens up an opportunity for a DoS attack,
+blocking the USB subsystem and making khubd's task busy wait in
+kernel space. This patch shifts freeing resources to close if an opened
+device is disconnected.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+CC: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/drivers/media/video/pwc/pwc-if.c linux-source-2.6.18/drivers/media/video/pwc/pwc-if.c
+--- linux-source-2.6.18.orig/drivers/media/video/pwc/pwc-if.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/media/video/pwc/pwc-if.c 2007-10-02 10:23:54.471131296 -0600
+@@ -1186,12 +1186,19 @@ static int pwc_video_open(struct inode *
+ return 0;
+ }
+
++
++static void pwc_cleanup(struct pwc_device *pdev)
++{
++ pwc_remove_sysfs_files(pdev->vdev);
++ video_unregister_device(pdev->vdev);
++}
++
+ /* Note that all cleanup is done in the reverse order as in _open */
+ static int pwc_video_close(struct inode *inode, struct file *file)
+ {
+ struct video_device *vdev = file->private_data;
+ struct pwc_device *pdev;
+- int i;
++ int i, hint;
+
+ PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
+
+@@ -1214,8 +1221,9 @@ static int pwc_video_close(struct inode
+ pwc_isoc_cleanup(pdev);
+ pwc_free_buffers(pdev);
+
++ lock_kernel();
+ /* Turn off LEDS and power down camera, but only when not unplugged */
+- if (pdev->error_status != EPIPE) {
++ if (!pdev->unplugged) {
+ /* Turn LEDs off */
+ if (pwc_set_leds(pdev, 0, 0) < 0)
+ PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
+@@ -1224,9 +1232,19 @@ static int pwc_video_close(struct inode
+ if (i < 0)
+ PWC_ERROR("Failed to power down camera (%d)\n", i);
+ }
++ pdev->vopen--;
++ PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
++ } else {
++ pwc_cleanup(pdev);
++ /* Free memory (don't set pdev to 0 just yet) */
++ kfree(pdev);
++ /* search device_hint[] table if we occupy a slot, by any chance */
++ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
++ if (device_hint[hint].pdev == pdev)
++ device_hint[hint].pdev = NULL;
+ }
+- pdev->vopen--;
+- PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
++ unlock_kernel();
++
+ return 0;
+ }
+
+@@ -1763,21 +1781,21 @@ static void usb_pwc_disconnect(struct us
+ /* Alert waiting processes */
+ wake_up_interruptible(&pdev->frameq);
+ /* Wait until device is closed */
+- while (pdev->vopen)
+- schedule();
+- /* Device is now closed, so we can safely unregister it */
+- PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
+- pwc_remove_sysfs_files(pdev->vdev);
+- video_unregister_device(pdev->vdev);
+-
+- /* Free memory (don't set pdev to 0 just yet) */
+- kfree(pdev);
++ if(pdev->vopen) {
++ pdev->unplugged = 1;
++ } else {
++ /* Device is closed, so we can safely unregister it */
++ PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
++ pwc_cleanup(pdev);
++ /* Free memory (don't set pdev to 0 just yet) */
++ kfree(pdev);
+
+ disconnect_out:
+- /* search device_hint[] table if we occupy a slot, by any chance */
+- for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+- if (device_hint[hint].pdev == pdev)
+- device_hint[hint].pdev = NULL;
++ /* search device_hint[] table if we occupy a slot, by any chance */
++ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
++ if (device_hint[hint].pdev == pdev)
++ device_hint[hint].pdev = NULL;
++ }
+
+ unlock_kernel();
+ }
+diff -urpN linux-source-2.6.18.orig/drivers/media/video/pwc/pwc.h linux-source-2.6.18/drivers/media/video/pwc/pwc.h
+--- linux-source-2.6.18.orig/drivers/media/video/pwc/pwc.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/media/video/pwc/pwc.h 2007-10-02 10:23:54.471131296 -0600
+@@ -198,6 +198,7 @@ struct pwc_device
+ char vsnapshot; /* snapshot mode */
+ char vsync; /* used by isoc handler */
+ char vmirror; /* for ToUCaM series */
++ char unplugged;
+
+ int cmd_len;
+ unsigned char cmd_buf[13];