[kernel] r7738 - 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
Fri Nov 10 22:29:24 UTC 2006


Author: dannf
Date: Fri Nov 10 23:29:23 2006
New Revision: 7738

Added:
   dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ia64-sparc-cross-region-mappings.dpatch
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/patches/series/2.6.8-16sarge6
Log:
* ia64-sparc-cross-region-mappings.dpatch
  [SECURITY] Prevent cross-region mappings on ia64 and sparc which
  could be used in a local DoS attack (system crash)
  See CVE-2006-4538

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	Fri Nov 10 23:29:23 2006
@@ -5,6 +5,10 @@
     system call which could be used as a local denial of service attack
     by depleting the system of file descriptors
     See CVE-2006-3741
+  * ia64-sparc-cross-region-mappings.dpatch
+    [SECURITY] Prevent cross-region mappings on ia64 and sparc which
+    could be used in a local DoS attack (system crash)
+    See CVE-2006-4538
 
  -- dann frazier <dannf at debian.org>  Wed,  8 Nov 2006 00:05:49 -0700
 

Added: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ia64-sparc-cross-region-mappings.dpatch
==============================================================================
--- (empty file)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ia64-sparc-cross-region-mappings.dpatch	Fri Nov 10 23:29:23 2006
@@ -0,0 +1,284 @@
+From: Kirill Korotaev <dev at openvz.org>
+Date: Thu, 7 Sep 2006 10:17:04 +0000 (+0400)
+Subject: [PATCH] IA64,sparc: local DoS with corrupted ELFs
+X-Git-Tag: v2.6.18-rc7
+X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3a459756810912d2c2bf188cef566af255936b4d
+
+[PATCH] IA64,sparc: local DoS with corrupted ELFs
+
+This prevents cross-region mappings on IA64 and SPARC which could lead
+to system crash.  They were correctly trapped for normal mmap() calls,
+but not for the kernel internal calls generated by executable loading.
+
+This code just moves the architecture-specific cross-region checks into
+an arch-specific "arch_mmap_check()" macro, and defines that for the
+architectures that needed it (ia64, sparc and sparc64).
+
+Architectures that don't have any special requirements can just ignore
+the new cross-region check, since the mmap() code will just notice on
+its own when the macro isn't defined.
+
+Signed-off-by: Pavel Emelianov <xemul at openvz.org>
+Signed-off-by: Kirill Korotaev <dev at openvz.org>
+Acked-by: David Miller <davem at davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+[ Cleaned up to not affect architectures that don't need it ]
+Signed-off-by: Linus Torvalds <torvalds at osdl.org>
+---
+
+Backported to Debian's 2.6.8 by dann frazier <dannf at hp.com>
+
+diff -urpN kernel-source-2.6.8.orig/arch/ia64/kernel/sys_ia64.c kernel-source-2.6.8/arch/ia64/kernel/sys_ia64.c
+--- kernel-source-2.6.8.orig/arch/ia64/kernel/sys_ia64.c	2004-08-13 23:37:14.000000000 -0600
++++ kernel-source-2.6.8/arch/ia64/kernel/sys_ia64.c	2006-11-09 17:16:53.492190017 -0700
+@@ -179,10 +179,25 @@ sys_pipe (long arg0, long arg1, long arg
+ 	return retval;
+ }
+ 
++int ia64_mmap_check(unsigned long addr, unsigned long len,
++		unsigned long flags)
++{
++	unsigned long roff;
++
++	/*
++	 * Don't permit mappings into unmapped space, the virtual page table
++	 * of a region, or across a region boundary.  Note: RGN_MAP_LIMIT is
++	 * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
++	 */
++	roff = REGION_OFFSET(addr);
++	if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
++		return -EINVAL;
++	return 0;
++}
++
+ static inline unsigned long
+ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
+ {
+-	unsigned long roff;
+ 	struct file *file = 0;
+ 
+ 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+@@ -211,17 +226,6 @@ do_mmap2 (unsigned long addr, unsigned l
+ 		goto out;
+ 	}
+ 
+-	/*
+-	 * Don't permit mappings into unmapped space, the virtual page table of a region,
+-	 * or across a region boundary.  Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
+-	 * (for some integer n <= 61) and len > 0.
+-	 */
+-	roff = REGION_OFFSET(addr);
+-	if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
+-		addr = -EINVAL;
+-		goto out;
+-	}
+-
+ 	down_write(&current->mm->mmap_sem);
+ 	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ 	up_write(&current->mm->mmap_sem);
+diff -urpN kernel-source-2.6.8.orig/arch/sparc/kernel/sys_sparc.c kernel-source-2.6.8/arch/sparc/kernel/sys_sparc.c
+--- kernel-source-2.6.8.orig/arch/sparc/kernel/sys_sparc.c	2004-08-13 23:36:46.000000000 -0600
++++ kernel-source-2.6.8/arch/sparc/kernel/sys_sparc.c	2006-11-09 17:14:59.068902401 -0700
+@@ -220,6 +220,21 @@ out:
+ 	return err;
+ }
+ 
++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)))
++		return -EINVAL;
++
++	/* See asm-sparc/uaccess.h */
++	if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
++		return -EINVAL;
++
++	return 0;
++}
++
+ /* Linux version of mmap */
+ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
+ 	unsigned long prot, unsigned long flags, unsigned long fd,
+@@ -234,25 +249,13 @@ static unsigned long do_mmap2(unsigned l
+ 			goto out;
+ 	}
+ 
+-	retval = -EINVAL;
+ 	len = PAGE_ALIGN(len);
+-	if (ARCH_SUN4C_SUN4 &&
+-	    (len > 0x20000000 ||
+-	     ((flags & MAP_FIXED) &&
+-	      addr < 0xe0000000 && addr + len > 0x20000000)))
+-		goto out_putf;
+-
+-	/* See asm-sparc/uaccess.h */
+-	if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
+-		goto out_putf;
+-
+ 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ 
+ 	down_write(&current->mm->mmap_sem);
+ 	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ 	up_write(&current->mm->mmap_sem);
+ 
+-out_putf:
+ 	if (file)
+ 		fput(file);
+ out:
+diff -urpN kernel-source-2.6.8.orig/arch/sparc64/kernel/sys_sparc.c kernel-source-2.6.8/arch/sparc64/kernel/sys_sparc.c
+--- kernel-source-2.6.8.orig/arch/sparc64/kernel/sys_sparc.c	2004-08-13 23:37:14.000000000 -0600
++++ kernel-source-2.6.8/arch/sparc64/kernel/sys_sparc.c	2006-11-09 17:22:30.389532950 -0700
+@@ -311,6 +311,23 @@ asmlinkage long sparc64_personality(unsi
+ 	return ret;
+ }
+ 
++int sparc64_mmap_check(unsigned long addr, unsigned long len,
++		unsigned long flags)
++{
++	if (test_thread_flag(TIF_32BIT)) {
++		if (len > 0xf0000000UL ||
++		    ((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
++			return -EINVAL;
++	} else {
++		if (len > -PAGE_OFFSET ||
++		    ((flags & MAP_FIXED) &&
++		     addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
++			return -EINVAL;
++	}
++
++	return 0;
++}
++
+ /* Linux version of mmap */
+ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+ 	unsigned long prot, unsigned long flags, unsigned long fd,
+@@ -326,24 +343,12 @@ asmlinkage unsigned long sys_mmap(unsign
+ 	}
+ 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ 	len = PAGE_ALIGN(len);
+-	retval = -EINVAL;
+ 
+-	if (test_thread_flag(TIF_32BIT)) {
+-		if (len > 0xf0000000UL ||
+-		    ((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
+-			goto out_putf;
+-	} else {
+-		if (len > -PAGE_OFFSET ||
+-		    ((flags & MAP_FIXED) &&
+-		     addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
+-			goto out_putf;
+-	}
+ 
+ 	down_write(&current->mm->mmap_sem);
+ 	retval = do_mmap(file, addr, len, prot, flags, off);
+ 	up_write(&current->mm->mmap_sem);
+ 
+-out_putf:
+ 	if (file)
+ 		fput(file);
+ out:
+diff -urpN kernel-source-2.6.8.orig/include/asm-ia64/mman.h kernel-source-2.6.8/include/asm-ia64/mman.h
+--- kernel-source-2.6.8.orig/include/asm-ia64/mman.h	2004-08-13 23:36:58.000000000 -0600
++++ kernel-source-2.6.8/include/asm-ia64/mman.h	2006-11-09 17:14:59.126531617 -0700
+@@ -48,4 +48,12 @@
+ #define MAP_ANON	MAP_ANONYMOUS
+ #define MAP_FILE	0
+ 
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
++#define arch_mmap_check	ia64_mmap_check
++int ia64_mmap_check(unsigned long addr, unsigned long len,
++		unsigned long flags);
++#endif
++#endif
++
+ #endif /* _ASM_IA64_MMAN_H */
+diff -urpN kernel-source-2.6.8.orig/include/asm-sparc/mman.h kernel-source-2.6.8/include/asm-sparc/mman.h
+--- kernel-source-2.6.8.orig/include/asm-sparc/mman.h	2004-08-13 23:38:04.000000000 -0600
++++ kernel-source-2.6.8/include/asm-sparc/mman.h	2006-11-09 17:14:59.137276048 -0700
+@@ -59,4 +59,12 @@
+ #define MAP_ANON	MAP_ANONYMOUS
+ #define MAP_FILE	0
+ 
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
++#define arch_mmap_check	sparc_mmap_check
++int sparc_mmap_check(unsigned long addr, unsigned long len,
++		unsigned long flags);
++#endif
++#endif
++
+ #endif /* __SPARC_MMAN_H__ */
+diff -urpN kernel-source-2.6.8.orig/include/asm-sparc64/mman.h kernel-source-2.6.8/include/asm-sparc64/mman.h
+--- kernel-source-2.6.8.orig/include/asm-sparc64/mman.h	2004-08-13 23:36:57.000000000 -0600
++++ kernel-source-2.6.8/include/asm-sparc64/mman.h	2006-11-09 17:14:59.154857842 -0700
+@@ -59,4 +59,12 @@
+ #define MAP_ANON	MAP_ANONYMOUS
+ #define MAP_FILE	0
+ 
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
++#define arch_mmap_check	sparc64_mmap_check
++int sparc64_mmap_check(unsigned long addr, unsigned long len,
++		unsigned long flags);
++#endif
++#endif
++
+ #endif /* __SPARC64_MMAN_H__ */
+diff -urpN kernel-source-2.6.8.orig/mm/mmap.c kernel-source-2.6.8/mm/mmap.c
+--- kernel-source-2.6.8.orig/mm/mmap.c	2006-09-06 19:09:30.000000000 -0600
++++ kernel-source-2.6.8/mm/mmap.c	2006-11-09 17:15:31.492661488 -0700
+@@ -28,6 +28,10 @@
+ #include <asm/cacheflush.h>
+ #include <asm/tlb.h>
+ 
++#ifndef arch_mmap_check
++#define arch_mmap_check(addr, len, flags)	(0)
++#endif
++
+ /*
+  * WARNING: the debugging will use recursive algorithms so never enable this
+  * unless you know what you are doing.
+@@ -772,6 +776,10 @@ unsigned long do_mmap_pgoff(struct file 
+ 	if (!len)
+ 		return addr;
+ 
++	error = arch_mmap_check(addr, len, flags);
++	if (error)
++		return error;
++
+ 	/* Careful about overflows.. */
+ 	len = PAGE_ALIGN(len);
+ 	if (!len || len > TASK_SIZE)
+@@ -1643,6 +1651,7 @@ unsigned long do_brk(unsigned long addr,
+ 	unsigned long flags;
+ 	struct rb_node ** rb_link, * rb_parent;
+ 	pgoff_t pgoff = addr >> PAGE_SHIFT;
++	int error;
+ 
+ 	len = PAGE_ALIGN(len);
+ 	if (!len)
+@@ -1651,6 +1660,12 @@ unsigned long do_brk(unsigned long addr,
+ 	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
+ 		return -EINVAL;
+ 
++	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
++
++	error = arch_mmap_check(addr, len, flags);
++	if (error)
++		return error;
++
+ 	/*
+ 	 * mlock MCL_FUTURE?
+ 	 */
+@@ -1689,8 +1704,6 @@ unsigned long do_brk(unsigned long addr,
+ 	if (security_vm_enough_memory(len >> PAGE_SHIFT))
+ 		return -ENOMEM;
+ 
+-	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+-
+ 	/* Can we just expand an old private anonymous mapping? */
+ 	if (vma_merge(mm, prev, addr, addr + len, flags,
+ 					NULL, NULL, pgoff, NULL))

Modified: dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge6
==============================================================================
--- dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge6	(original)
+++ dists/sarge-security/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-16sarge6	Fri Nov 10 23:29:23 2006
@@ -1 +1,2 @@
 + perfmon-fd-refcnt.dpatch
++ ia64-sparc-cross-region-mappings.dpatch



More information about the Kernel-svn-changes mailing list