[kernel] r8019 - in
dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian:
. patches patches/series
Dann Frazier
dannf at alioth.debian.org
Sat Dec 16 08:14:21 UTC 2006
Author: dannf
Date: Sat Dec 16 09:14:20 2006
New Revision: 8019
Added:
dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore-fixes.dpatch
dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore_hang.dpatch
dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge7
Modified:
dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
Log:
* mincore_hang.dpatch
[SECURITY] Fix a potential deadlock in mincore, thanks to Marcel
Holtmann for the patch.
See CVE-2006-4814
* mincore-fixes.dpatch
This patch includes a few fixes, necessary for mincore_hang.dpatch to
apply cleanly.
Modified: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
==============================================================================
--- dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog (original)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog Sat Dec 16 09:14:20 2006
@@ -1,3 +1,15 @@
+kernel-source-2.6.8 (2.6.8-16sarge7) UNRELEASED; urgency=high
+
+ * mincore_hang.dpatch
+ [SECURITY] Fix a potential deadlock in mincore, thanks to Marcel
+ Holtmann for the patch.
+ See CVE-2006-4814
+ * mincore-fixes.dpatch
+ This patch includes a few fixes, necessary for mincore_hang.dpatch to
+ apply cleanly.
+
+ -- dann frazier <dannf at debian.org> Sat, 16 Dec 2006 01:06:51 -0700
+
kernel-source-2.6.8 (2.6.8-16sarge6) stable-security; urgency=high
* perfmon-fd-refcnt.dpatch
Added: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore-fixes.dpatch
==============================================================================
--- (empty file)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore-fixes.dpatch Sat Dec 16 09:14:20 2006
@@ -0,0 +1,107 @@
+From: dhowells <dhowells>
+Date: Fri, 11 Feb 2005 19:01:29 +0000 (+0000)
+Subject: [PATCH] Fix the mincore() syscall
+X-Git-Tag: v2.6.11-rc4
+X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commitdiff;h=64b287cfdd0e37c48579f6ba95ab4fcc576914ee
+
+[PATCH] Fix the mincore() syscall
+
+This fixes the mincore syscall in three ways:
+
+ (1) It moves as much argument checking outside of the semaphore-holding
+ region as possible.
+
+ (2) It checks the region parameters against TASK_SIZE so that a 32-bit binary
+ on a 64-bit platform will get the right error when calling this syscall
+ on a region that overlaps the end of the 32-bit address space.
+
+ (3) It tidies up the VMA checking loop a little.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+Signed-Off-By: Linus Torvalds <torvalds at osdl.org>
+
+BKrev: 420d0109S65n5it9qSqkG144z7vKhg
+---
+
+--- a/mm/mincore.c
++++ b/mm/mincore.c
+@@ -109,39 +109,45 @@ asmlinkage long sys_mincore(unsigned lon
+ unsigned char __user * vec)
+ {
+ int index = 0;
+- unsigned long end;
++ unsigned long end, limit;
+ struct vm_area_struct * vma;
++ size_t max;
+ int unmapped_error = 0;
+- long error = -EINVAL;
++ long error;
+
+- down_read(¤t->mm->mmap_sem);
++ /* check the arguments */
++ if (start & ~PAGE_CACHE_MASK)
++ goto einval;
++
++ if (start < FIRST_USER_PGD_NR * PGDIR_SIZE)
++ goto enomem;
++
++ limit = TASK_SIZE;
++ if (start >= limit)
++ goto enomem;
++
++ max = limit - start;
++ len = PAGE_CACHE_ALIGN(len);
++ if (len > max)
++ goto einval;
+
+- if (start & ~PAGE_CACHE_MASK)
+- goto out;
+- len = (len + ~PAGE_CACHE_MASK) & PAGE_CACHE_MASK;
+ end = start + len;
+- if (end < start)
+- goto out;
+
++ /* check the output buffer whilst holding the lock */
+ error = -EFAULT;
+- if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
+- goto out;
++ down_read(¤t->mm->mmap_sem);
+
+- error = 0;
+- if (end == start)
++ if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
+ goto out;
+
+ /*
+ * If the interval [start,end) covers some unmapped address
+ * ranges, just ignore them, but return -ENOMEM at the end.
+ */
+- vma = find_vma(current->mm, start);
+- for (;;) {
+- /* Still start < end. */
+- error = -ENOMEM;
+- if (!vma)
+- goto out;
++ error = 0;
+
++ vma = find_vma(current->mm, start);
++ while (vma) {
+ /* Here start < vma->vm_end. */
+ if (start < vma->vm_start) {
+ unmapped_error = -ENOMEM;
+@@ -169,7 +175,15 @@ asmlinkage long sys_mincore(unsigned lon
+ vma = vma->vm_next;
+ }
+
++ /* we found a hole in the area queried if we arrive here */
++ error = -ENOMEM;
++
+ out:
+ up_read(¤t->mm->mmap_sem);
+ return error;
++
++einval:
++ return -EINVAL;
++enomem:
++ return -ENOMEM;
+ }
Added: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore_hang.dpatch
==============================================================================
--- (empty file)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/mincore_hang.dpatch Sat Dec 16 09:14:20 2006
@@ -0,0 +1,187 @@
+Updated patch. Dave's earlier comment made me realize there was a
+rather sinister overflow problem in my earlier patch. This one was
+tested in much more depth with a simple mincore test that called mincore
+for a very large address space (i.e. more than PAGE_SIZE pages long).
+
+--- linux-2.6.9/mm/mincore.c.orig 2006-09-19 15:04:01.000000000 -0400
++++ linux-2.6.9/mm/mincore.c 2006-09-20 11:44:35.000000000 -0400
+@@ -38,10 +38,9 @@
+ }
+
+ static long mincore_vma(struct vm_area_struct * vma,
+- unsigned long start, unsigned long end, unsigned char __user * vec)
++ unsigned long start, unsigned long end, char * vec)
+ {
+- long error, i, remaining;
+- unsigned char * tmp;
++ long error, j, pages;
+
+ error = -ENOMEM;
+ if (!vma->vm_file)
+@@ -52,30 +51,13 @@
+ end = vma->vm_end;
+ end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+
+- error = -EAGAIN;
+- tmp = (unsigned char *) __get_free_page(GFP_KERNEL);
+- if (!tmp)
+- return error;
+-
+- /* (end - start) is # of pages, and also # of bytes in "vec */
+- remaining = (end - start),
+-
+ error = 0;
+- for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) {
+- int j = 0;
+- long thispiece = (remaining < PAGE_SIZE) ?
+- remaining : PAGE_SIZE;
+-
+- while (j < thispiece)
+- tmp[j++] = mincore_page(vma, start++);
+-
+- if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) {
+- error = -EFAULT;
+- break;
+- }
+- }
++ pages = end-start;
++ BUG_ON(pages > PAGE_SIZE);
++
++ for (j=0; j < pages; j++)
++ vec[j] = mincore_page(vma, start++);
+
+- free_page((unsigned long) tmp);
+ return error;
+ }
+
+@@ -108,11 +90,11 @@
+ unsigned char __user * vec)
+ {
+ int index = 0;
+- unsigned long end, limit;
++ unsigned long end, real_end, limit;
+ struct vm_area_struct * vma;
+ size_t max;
+- int unmapped_error = 0;
+ long error;
++ unsigned char * tmp = NULL;
+
+ /* check the arguments */
+ if (start & ~PAGE_CACHE_MASK)
+@@ -130,54 +112,85 @@
+ if (len > max)
+ goto einval;
+
+- end = start + len;
+-
+- /* check the output buffer whilst holding the lock */
++ /*
++ * if any pages pointed to by *vec are not in core we
++ * will deadlock later at the copy_to_user due to mmap_sem
++ * being locked. So, we must only look at as many pages
++ * as fit into 1 page of vec at a time and and copy to a
++ * tmp page that we know is in core
++ */
++ real_end = start + len;
+ error = -EFAULT;
+- down_read(¤t->mm->mmap_sem);
+
+- if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
+- goto out;
++ end = start;
++ while (end < real_end)
++ {
++ end += PAGE_SIZE*PAGE_SIZE;
++ if (end > real_end)
++ end = real_end;
++
++ index = 0;
++ tmp = (unsigned char *) __get_free_page(GFP_KERNEL);
++ if (!tmp)
++ goto enomem;
+
+- /*
+- * If the interval [start,end) covers some unmapped address
+- * ranges, just ignore them, but return -ENOMEM at the end.
+- */
+- error = 0;
++ /* check the output buffer whilst holding the lock */
++ down_read(¤t->mm->mmap_sem);
++
++ if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT)){
++ error = -EFAULT;
++ goto error_unlock;
++ }
+
+- vma = find_vma(current->mm, start);
+- while (vma) {
++ error = 0;
++
++ vma = find_vma(current->mm, start);
++ while (vma) {
+ /* Here start < vma->vm_end. */
+- if (start < vma->vm_start) {
+- unmapped_error = -ENOMEM;
+- start = vma->vm_start;
++ if (start < vma->vm_start){
++ error = -ENOMEM;
++ goto error_unlock;
+ }
+
+ /* Here vma->vm_start <= start < vma->vm_end. */
+ if (end <= vma->vm_end) {
+- if (start < end) {
+- error = mincore_vma(vma, start, end,
+- &vec[index]);
+- if (error)
+- goto out;
+- }
+- error = unmapped_error;
+- goto out;
++ if (start < end) {
++ error = mincore_vma(vma, start, end, &tmp[index]);
++ if (error)
++ goto error_unlock;
++ index += (end - start) >> PAGE_CACHE_SHIFT;
++ start = end;
++ }
++ goto out;
+ }
+
+ /* Here vma->vm_start <= start < vma->vm_end < end. */
+- error = mincore_vma(vma, start, vma->vm_end, &vec[index]);
++ error = mincore_vma(vma, start, vma->vm_end, &tmp[index]);
+ if (error)
+- goto out;
++ goto error_unlock;
+ index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT;
+ start = vma->vm_end;
+ vma = vma->vm_next;
+- }
++ }
+
+- /* we found a hole in the area queried if we arrive here */
+- error = -ENOMEM;
++
++ /* we found a hole in the area queried if we arrive here */
++ error = -ENOMEM;
++ goto error_unlock;
+
+ out:
++ up_read(¤t->mm->mmap_sem);
++ if (copy_to_user(vec, tmp, index))
++ error = -EFAULT;
++ vec += index;
++ free_page((unsigned long)tmp);
++ tmp = NULL;
++ }
++ return error;
++
++error_unlock:
++ if (tmp)
++ free_page((unsigned long)tmp);
+ up_read(¤t->mm->mmap_sem);
+ return error;
+
+
+
Added: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge7
==============================================================================
--- (empty file)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge7 Sat Dec 16 09:14:20 2006
@@ -0,0 +1,2 @@
++ debian/patches/mincore-fixes.dpatch
++ debian/patches/mincore_hang.dpatch
More information about the Kernel-svn-changes
mailing list