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 <[EMAIL PROTECTED]>  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 <[EMAIL PROTECTED]>
+Signed-Off-By: Linus Torvalds <[EMAIL PROTECTED]>
+
+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(&current->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(&current->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(&current->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(&current->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(&current->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(&current->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(&current->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

_______________________________________________
Kernel-svn-changes mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/kernel-svn-changes

Reply via email to