[kernel] r11592 - in dists/etch/linux-2.6.24/debian: . patches/bugfix patches/series

Dann Frazier dannf at alioth.debian.org
Mon Jun 9 22:29:58 UTC 2008


Author: dannf
Date: Mon Jun  9 22:28:45 2008
New Revision: 11592

Log:
* [sparc] Validate address ranges regardless of MAP_FIXED (CVE-2008-2137)

Added:
   dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mmap-va-span-checking.patch
   dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mremap-addr-range-validation.patch
Modified:
   dists/etch/linux-2.6.24/debian/changelog
   dists/etch/linux-2.6.24/debian/patches/series/6~etchnhalf.3

Modified: dists/etch/linux-2.6.24/debian/changelog
==============================================================================
--- dists/etch/linux-2.6.24/debian/changelog	(original)
+++ dists/etch/linux-2.6.24/debian/changelog	Mon Jun  9 22:28:45 2008
@@ -8,8 +8,9 @@
     (CVE-2008-1615)
   * Fix issue with blkdev_issue_flush() not detecting/passing EOPNOTSUPP back,
     (closes: #482943)
+  * [sparc] Validate address ranges regardless of MAP_FIXED (CVE-2008-2137)
 
- -- dann frazier <dannf at debian.org>  Wed, 04 Jun 2008 02:05:40 -0600
+ -- dann frazier <dannf at debian.org>  Mon, 09 Jun 2008 16:28:15 -0600
 
 linux-2.6.24 (2.6.24-6~etchnhalf.2) stable; urgency=low
 

Added: dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mmap-va-span-checking.patch
==============================================================================
--- (empty file)
+++ dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mmap-va-span-checking.patch	Mon Jun  9 22:28:45 2008
@@ -0,0 +1,44 @@
+commit 5816339310b2d9623cf413d33e538b45e815da5d
+Author: David S. Miller <davem at davemloft.net>
+Date:   Wed May 7 02:24:28 2008 -0700
+
+    sparc: Fix mmap VA span checking.
+    
+    We should not conditionalize VA range checks on MAP_FIXED.
+    
+    Signed-off-by: David S. Miller <davem at davemloft.net>
+
+diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
+index f188b5d..e995491 100644
+--- a/arch/sparc/kernel/sys_sparc.c
++++ b/arch/sparc/kernel/sys_sparc.c
+@@ -223,8 +223,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
+ {
+ 	if (ARCH_SUN4C_SUN4 &&
+ 	    (len > 0x20000000 ||
+-	     ((flags & MAP_FIXED) &&
+-	      addr < 0xe0000000 && addr + len > 0x20000000)))
++	     (addr < 0xe0000000 && addr + len > 0x20000000)))
+ 		return -EINVAL;
+ 
+ 	/* See asm-sparc/uaccess.h */
+diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
+index 8d4761f..0dbc941 100644
+--- a/arch/sparc64/kernel/sys_sparc.c
++++ b/arch/sparc64/kernel/sys_sparc.c
+@@ -549,13 +549,13 @@ int sparc64_mmap_check(unsigned long addr, unsigned long len,
+ 		if (len >= STACK_TOP32)
+ 			return -EINVAL;
+ 
+-		if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
++		if (addr > STACK_TOP32 - len)
+ 			return -EINVAL;
+ 	} else {
+ 		if (len >= VA_EXCLUDE_START)
+ 			return -EINVAL;
+ 
+-		if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
++		if (invalid_64bit_range(addr, len))
+ 			return -EINVAL;
+ 	}
+ 

Added: dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mremap-addr-range-validation.patch
==============================================================================
--- (empty file)
+++ dists/etch/linux-2.6.24/debian/patches/bugfix/sparc-fix-mremap-addr-range-validation.patch	Mon Jun  9 22:28:45 2008
@@ -0,0 +1,233 @@
+commit 94d149c34cda933ff5096aca94bb23bf68602f4e
+Author: David S. Miller <davem at davemloft.net>
+Date:   Mon May 12 16:33:33 2008 -0700
+
+    sparc: Fix mremap address range validation.
+    
+    Just like mmap, we need to validate address ranges regardless
+    of MAP_FIXED.
+    
+    sparc{,64}_mmap_check()'s flag argument is unused, remove.
+    
+    Based upon a report and preliminary patch by
+    Jan Lieskovsky <jlieskov at redhat.com>
+    
+    Signed-off-by: David S. Miller <davem at davemloft.net>
+
+diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
+index e995491..3c6b49a 100644
+--- a/arch/sparc/kernel/sys_sparc.c
++++ b/arch/sparc/kernel/sys_sparc.c
+@@ -219,7 +219,7 @@ out:
+ 	return err;
+ }
+ 
+-int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
++int sparc_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (ARCH_SUN4C_SUN4 &&
+ 	    (len > 0x20000000 ||
+@@ -295,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+-	if (ARCH_SUN4C_SUN4) {
+-		if (old_len > 0x20000000 || new_len > 0x20000000)
+-			goto out;
+-		if (addr < 0xe0000000 && addr + old_len > 0x20000000)
+-			goto out;
+-	}
+-	if (old_len > TASK_SIZE - PAGE_SIZE ||
+-	    new_len > TASK_SIZE - PAGE_SIZE)
++
++	if (unlikely(sparc_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (ARCH_SUN4C_SUN4 &&
+-		    new_addr < 0xe0000000 &&
+-		    new_addr + new_len > 0x20000000)
+-			goto out_sem;
+-		if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
+-			goto out_sem;
+-	} else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
+-		    addr + new_len > 0x20000000) ||
+-		   addr + new_len > TASK_SIZE - PAGE_SIZE) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				     vma ? vma->vm_pgoff : 0,
+-				     map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
+index 0dbc941..ac1bff5 100644
+--- a/arch/sparc64/kernel/sys_sparc.c
++++ b/arch/sparc64/kernel/sys_sparc.c
+@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
+ 	return ret;
+ }
+ 
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags)
++int sparc64_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (test_thread_flag(TIF_32BIT)) {
+ 		if (len >= STACK_TOP32)
+@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 
+ 	if (test_thread_flag(TIF_32BIT))
+ 		goto out;
+ 	if (unlikely(new_len >= VA_EXCLUDE_START))
+ 		goto out;
+-	if (unlikely(invalid_64bit_range(addr, old_len)))
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (invalid_64bit_range(new_addr, new_len))
+-			goto out_sem;
+-	} else if (invalid_64bit_range(addr, new_len)) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
+index 1aa4288..ba5bd62 100644
+--- a/arch/sparc64/kernel/sys_sparc32.c
++++ b/arch/sparc64/kernel/sys_sparc32.c
+@@ -867,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, u32 __new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 	unsigned long new_addr = __new_addr;
+ 
+-	if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
+ 		goto out;
+-	if (addr > STACK_TOP32 - old_len)
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (new_addr > STACK_TOP32 - new_len)
+-			goto out_sem;
+-	} else if (addr > STACK_TOP32 - new_len) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
+index e18be98..3d16b40 100644
+--- a/include/asm-sparc/mman.h
++++ b/include/asm-sparc/mman.h
+@@ -24,9 +24,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc_mmap_check
+-int sparc_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
++int sparc_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 
+diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
+index e584563..625be4d 100644
+--- a/include/asm-sparc64/mman.h
++++ b/include/asm-sparc64/mman.h
+@@ -24,9 +24,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc64_mmap_check
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc64_mmap_check(addr,len)
++int sparc64_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 

Modified: dists/etch/linux-2.6.24/debian/patches/series/6~etchnhalf.3
==============================================================================
--- dists/etch/linux-2.6.24/debian/patches/series/6~etchnhalf.3	(original)
+++ dists/etch/linux-2.6.24/debian/patches/series/6~etchnhalf.3	Mon Jun  9 22:28:45 2008
@@ -2,3 +2,5 @@
 + bugfix/sit-missing-kfree_skb-on-pskb_may_pull.patch
 + bugfix/amd64-cs-corruption.patch
 + bugfix/block-fix-blkdev_issue_flush.patch
++ bugfix/sparc-fix-mmap-va-span-checking.patch
++ bugfix/sparc-fix-mremap-addr-range-validation.patch



More information about the Kernel-svn-changes mailing list