summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Young <m.a.young@durham.ac.uk>2010-09-20 20:03:58 +0100
committerMichael Young <m.a.young@durham.ac.uk>2010-09-20 20:03:58 +0100
commit2022e0a6403d563ac19d26335e6ca72e7a860a32 (patch)
treea7372ad6beb905c2ddd627231bfe2f0f9e25fc80
parent8a139d83f054c9bff13df055779acf03cb010d6a (diff)
parent55a7c987aaf2cd94ace449b6594638b572b8c14f (diff)
downloaddom0-kernel-2022e0a6403d563ac19d26335e6ca72e7a860a32.tar.gz
dom0-kernel-2022e0a6403d563ac19d26335e6ca72e7a860a32.tar.xz
dom0-kernel-2022e0a6403d563ac19d26335e6ca72e7a860a32.zip
Merge branch 'f12/master' into f12/user/myoung/xendom0
Conflicts: kernel.spec
-rw-r--r--01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch198
-rw-r--r--02-compat-test-rax-for-the-system-call-number-not-eax.patch97
-rw-r--r--03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch49
-rw-r--r--aio-check-for-multiplication-overflow-in-do_io_submit.patch47
-rw-r--r--alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch53
-rw-r--r--execve-improve-interactivity-with-large-arguments.patch36
-rw-r--r--execve-make-responsive-to-sigkill-with-large-arguments.patch51
-rw-r--r--kernel.spec62
-rw-r--r--keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch52
-rw-r--r--keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch64
-rw-r--r--net-do-not-check-capable-if-kernel.patch682
-rw-r--r--setup_arg_pages-diagnose-excessive-argument-size.patch42
-rw-r--r--tracing-do-not-allow-llseek-to-set_ftrace_filter.patch51
13 files changed, 1483 insertions, 1 deletions
diff --git a/01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch b/01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
new file mode 100644
index 0000000..2053e03
--- /dev/null
+++ b/01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
@@ -0,0 +1,198 @@
+From f45716729488bd8263b06e7d672c8ff8f2ded8b7 Mon Sep 17 00:00:00 2001
+From: H. Peter Anvin <hpa@linux.intel.com>
+Date: Tue, 7 Sep 2010 16:16:18 -0700
+Subject: [PATCH 1/4] compat: Make compat_alloc_user_space() incorporate the access_ok()
+
+compat_alloc_user_space() expects the caller to independently call
+access_ok() to verify the returned area. A missing call could
+introduce problems on some architectures.
+
+This patch incorporates the access_ok() check into
+compat_alloc_user_space() and also adds a sanity check on the length.
+The existing compat_alloc_user_space() implementations are renamed
+arch_compat_alloc_user_space() and are used as part of the
+implementation of the new global function.
+
+This patch assumes NULL will cause __get_user()/__put_user() to either
+fail or access userspace on all architectures. This should be
+followed by checking the return value of compat_access_user_space()
+for NULL in the callers, at which time the access_ok() in the callers
+can also be removed.
+
+Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Acked-by: Chris Metcalf <cmetcalf@tilera.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Tony Luck <tony.luck@intel.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Helge Deller <deller@gmx.de>
+Cc: James Bottomley <jejb@parisc-linux.org>
+Cc: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: <stable@kernel.org>
+---
+
+ [ edited to fix build on 2.6.32 ]
+
+ arch/ia64/include/asm/compat.h | 2 +-
+ arch/mips/include/asm/compat.h | 2 +-
+ arch/parisc/include/asm/compat.h | 2 +-
+ arch/powerpc/include/asm/compat.h | 2 +-
+ arch/s390/include/asm/compat.h | 2 +-
+ arch/sparc/include/asm/compat.h | 2 +-
+ arch/x86/include/asm/compat.h | 2 +-
+ include/linux/compat.h | 2 ++
+ kernel/compat.c | 22 +++++++++++++++++++++
+ 9 files changed, 30 insertions(+), 7 deletions(-)
+
+diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h
+index dfcf75b..c8662cd 100644
+--- a/arch/ia64/include/asm/compat.h
++++ b/arch/ia64/include/asm/compat.h
+@@ -198,7 +198,7 @@ ptr_to_compat(void __user *uptr)
+ }
+
+ static __inline__ void __user *
+-compat_alloc_user_space (long len)
++arch_compat_alloc_user_space (long len)
+ {
+ struct pt_regs *regs = task_pt_regs(current);
+ return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
+diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
+index f58aed3..27505bd 100644
+--- a/arch/mips/include/asm/compat.h
++++ b/arch/mips/include/asm/compat.h
+@@ -144,7 +144,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+ return (u32)(unsigned long)uptr;
+ }
+
+-static inline void __user *compat_alloc_user_space(long len)
++static inline void __user *arch_compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = (struct pt_regs *)
+ ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
+diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
+index 7f32611..7c77fa9 100644
+--- a/arch/parisc/include/asm/compat.h
++++ b/arch/parisc/include/asm/compat.h
+@@ -146,7 +146,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+ return (u32)(unsigned long)uptr;
+ }
+
+-static __inline__ void __user *compat_alloc_user_space(long len)
++static __inline__ void __user *arch_compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = &current->thread.regs;
+ return (void __user *)regs->gr[30];
+diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
+index 4774c2f..8d0fff3 100644
+--- a/arch/powerpc/include/asm/compat.h
++++ b/arch/powerpc/include/asm/compat.h
+@@ -133,7 +133,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+ return (u32)(unsigned long)uptr;
+ }
+
+-static inline void __user *compat_alloc_user_space(long len)
++static inline void __user *arch_compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = current->thread.regs;
+ unsigned long usp = regs->gpr[1];
+diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
+index 01a0802..0c940d3 100644
+--- a/arch/s390/include/asm/compat.h
++++ b/arch/s390/include/asm/compat.h
+@@ -180,7 +180,7 @@ static inline int is_compat_task(void)
+
+ #endif
+
+-static inline void __user *compat_alloc_user_space(long len)
++static inline void __user *arch_compat_alloc_user_space(long len)
+ {
+ unsigned long stack;
+
+diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
+index 0e70625..612bb38 100644
+--- a/arch/sparc/include/asm/compat.h
++++ b/arch/sparc/include/asm/compat.h
+@@ -166,7 +166,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+ return (u32)(unsigned long)uptr;
+ }
+
+-static inline void __user *compat_alloc_user_space(long len)
++static inline void __user *arch_compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = current_thread_info()->kregs;
+ unsigned long usp = regs->u_regs[UREG_I6];
+diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
+index 9a9c7bd..c8c9a74 100644
+--- a/arch/x86/include/asm/compat.h
++++ b/arch/x86/include/asm/compat.h
+@@ -204,7 +204,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+ return (u32)(unsigned long)uptr;
+ }
+
+-static inline void __user *compat_alloc_user_space(long len)
++static inline void __user *arch_compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = task_pt_regs(current);
+ return (void __user *)regs->sp - len;
+diff --git a/include/linux/compat.h b/include/linux/compat.h
+index af931ee..cab23f2 100644
+--- a/include/linux/compat.h
++++ b/include/linux/compat.h
+@@ -309,5 +309,7 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
+ asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
+ int flags, int mode);
+
++extern void __user *compat_alloc_user_space(unsigned long len);
++
+ #endif /* CONFIG_COMPAT */
+ #endif /* _LINUX_COMPAT_H */
+diff a/kernel/compat.c b/kernel/compat.c
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -13,6 +13,7 @@
+
+ #include <linux/linkage.h>
+ #include <linux/compat.h>
++#include <linux/module.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+ #include <linux/signal.h>
+@@ -1137,3 +1137,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
+
+ return 0;
+ }
++
++/*
++ * Allocate user-space memory for the duration of a single system call,
++ * in order to marshall parameters inside a compat thunk.
++ */
++void __user *compat_alloc_user_space(unsigned long len)
++{
++ void __user *ptr;
++
++ /* If len would occupy more than half of the entire compat space... */
++ if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
++ return NULL;
++
++ ptr = arch_compat_alloc_user_space(len);
++
++ if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
++ return NULL;
++
++ return ptr;
++}
++EXPORT_SYMBOL_GPL(compat_alloc_user_space);
+--
+1.7.2.3
+
diff --git a/02-compat-test-rax-for-the-system-call-number-not-eax.patch b/02-compat-test-rax-for-the-system-call-number-not-eax.patch
new file mode 100644
index 0000000..8fd7490
--- /dev/null
+++ b/02-compat-test-rax-for-the-system-call-number-not-eax.patch
@@ -0,0 +1,97 @@
+From aaeacea2992c28f1d355ff7cd4c4754131bdd831 Mon Sep 17 00:00:00 2001
+From: H. Peter Anvin <hpa@linux.intel.com>
+Date: Tue, 14 Sep 2010 12:42:41 -0700
+Subject: [PATCH 2/4] x86-64, compat: Test %rax for the syscall number, not %eax
+
+On 64 bits, we always, by necessity, jump through the system call
+table via %rax. For 32-bit system calls, in theory the system call
+number is stored in %eax, and the code was testing %eax for a valid
+system call number. At one point we loaded the stored value back from
+the stack to enforce zero-extension, but that was removed in checkin
+d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
+will not be able to introduce a non-zero-extended number, but it can
+happen via ptrace.
+
+Instead of re-introducing the zero-extension, test what we are
+actually going to use, i.e. %rax. This only adds a handful of REX
+prefixes to the code.
+
+Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Cc: <stable@kernel.org>
+Cc: Roland McGrath <roland@redhat.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+---
+ arch/x86/ia32/ia32entry.S | 14 +++++++-------
+ 1 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 5294d84..7f9eb54 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -153,7 +153,7 @@ ENTRY(ia32_sysenter_target)
+ testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
+ CFI_REMEMBER_STATE
+ jnz sysenter_tracesys
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja ia32_badsys
+ sysenter_do_call:
+ IA32_ARG_FIXUP
+@@ -195,7 +195,7 @@ sysexit_from_sys_call:
+ movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */
+ call audit_syscall_entry
+ movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja ia32_badsys
+ movl %ebx,%edi /* reload 1st syscall arg */
+ movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */
+@@ -248,7 +248,7 @@ sysenter_tracesys:
+ call syscall_trace_enter
+ LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
+ jmp sysenter_do_call
+ CFI_ENDPROC
+@@ -314,7 +314,7 @@ ENTRY(ia32_cstar_target)
+ testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
+ CFI_REMEMBER_STATE
+ jnz cstar_tracesys
+- cmpl $IA32_NR_syscalls-1,%eax
++ cmpq $IA32_NR_syscalls-1,%rax
+ ja ia32_badsys
+ cstar_do_call:
+ IA32_ARG_FIXUP 1
+@@ -367,7 +367,7 @@ cstar_tracesys:
+ LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+ xchgl %ebp,%r9d
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
+ jmp cstar_do_call
+ END(ia32_cstar_target)
+@@ -425,7 +425,7 @@ ENTRY(ia32_syscall)
+ orl $TS_COMPAT,TI_status(%r10)
+ testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
+ jnz ia32_tracesys
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja ia32_badsys
+ ia32_do_call:
+ IA32_ARG_FIXUP
+@@ -444,7 +444,7 @@ ia32_tracesys:
+ call syscall_trace_enter
+ LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
+ RESTORE_REST
+- cmpl $(IA32_NR_syscalls-1),%eax
++ cmpq $(IA32_NR_syscalls-1),%rax
+ ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */
+ jmp ia32_do_call
+ END(ia32_syscall)
+--
+1.7.2.3
+
diff --git a/03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch b/03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
new file mode 100644
index 0000000..96c269b
--- /dev/null
+++ b/03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
@@ -0,0 +1,49 @@
+From 1fa16daaa76d1b132c8fee027c11bad5a5d25761 Mon Sep 17 00:00:00 2001
+From: Roland McGrath <roland@redhat.com>
+Date: Tue, 14 Sep 2010 12:22:58 -0700
+Subject: [PATCH 3/4] x86-64, compat: Retruncate rax after ia32 syscall entry tracing
+
+In commit d4d6715, we reopened an old hole for a 64-bit ptracer touching a
+32-bit tracee in system call entry. A %rax value set via ptrace at the
+entry tracing stop gets used whole as a 32-bit syscall number, while we
+only check the low 32 bits for validity.
+
+Fix it by truncating %rax back to 32 bits after syscall_trace_enter,
+in addition to testing the full 64 bits as has already been added.
+
+Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
+Signed-off-by: Roland McGrath <roland@redhat.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+---
+ arch/x86/ia32/ia32entry.S | 8 +++++++-
+ 1 files changed, 7 insertions(+), 1 deletions(-)
+
+diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 7f9eb54..4edd8eb 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -50,7 +50,12 @@
+ /*
+ * Reload arg registers from stack in case ptrace changed them.
+ * We don't reload %eax because syscall_trace_enter() returned
+- * the value it wants us to use in the table lookup.
++ * the %rax value we should see. Instead, we just truncate that
++ * value to 32 bits again as we did on entry from user mode.
++ * If it's a new value set by user_regset during entry tracing,
++ * this matches the normal truncation of the user-mode value.
++ * If it's -1 to make us punt the syscall, then (u32)-1 is still
++ * an appropriately invalid value.
+ */
+ .macro LOAD_ARGS32 offset, _r9=0
+ .if \_r9
+@@ -60,6 +65,7 @@
+ movl \offset+48(%rsp),%edx
+ movl \offset+56(%rsp),%esi
+ movl \offset+64(%rsp),%edi
++ movl %eax,%eax /* zero extension */
+ .endm
+
+ .macro CFI_STARTPROC32 simple
+--
+1.7.2.3
+
diff --git a/aio-check-for-multiplication-overflow-in-do_io_submit.patch b/aio-check-for-multiplication-overflow-in-do_io_submit.patch
new file mode 100644
index 0000000..8706792
--- /dev/null
+++ b/aio-check-for-multiplication-overflow-in-do_io_submit.patch
@@ -0,0 +1,47 @@
+From be18992d0630149403bfae5882601cf01a7d4eea Mon Sep 17 00:00:00 2001
+From: Jeff Moyer <jmoyer@redhat.com>
+Date: Fri, 10 Sep 2010 14:16:00 -0700
+Subject: [PATCH 4/4] aio: check for multiplication overflow in do_io_submit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Tavis Ormandy pointed out that do_io_submit does not do proper bounds
+checking on the passed-in iocb array:
+
+       if (unlikely(nr < 0))
+               return -EINVAL;
+
+       if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(iocbpp)))))
+               return -EFAULT;                      ^^^^^^^^^^^^^^^^^^
+
+The attached patch checks for overflow, and if it is detected, the
+number of iocbs submitted is scaled down to a number that will fit in
+the long.  This is an ok thing to do, as sys_io_submit is documented as
+returning the number of iocbs submitted, so callers should handle a
+return value of less than the 'nr' argument passed in.
+
+Reported-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+ fs/aio.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/fs/aio.c b/fs/aio.c
+index 02a2c93..b84a769 100644
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -1639,6 +1639,9 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
+ if (unlikely(nr < 0))
+ return -EINVAL;
+
++ if (unlikely(nr > LONG_MAX/sizeof(*iocbpp)))
++ nr = LONG_MAX/sizeof(*iocbpp);
++
+ if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp)))))
+ return -EFAULT;
+
+--
+1.7.2.3
+
diff --git a/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch b/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
new file mode 100644
index 0000000..73e65ec
--- /dev/null
+++ b/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
@@ -0,0 +1,53 @@
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 6 Sep 2010 07:13:45 +0000 (+0200)
+Subject: ALSA: seq/oss - Fix double-free at error path of snd_seq_oss_open()
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=27f7ad53829f79e799a253285318bff79ece15bd
+
+ALSA: seq/oss - Fix double-free at error path of snd_seq_oss_open()
+
+The error handling in snd_seq_oss_open() has several bad codes that
+do dereferecing released pointers and double-free of kmalloc'ed data.
+The object dp is release in free_devinfo() that is called via
+private_free callback. The rest shouldn't touch this object any more.
+
+The patch changes delete_port() to call kfree() in any case, and gets
+rid of unnecessary calls of destructors in snd_seq_oss_open().
+
+Fixes CVE-2010-3080.
+
+Reported-and-tested-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+---
+
+diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
+index 6857122..69cd7b3 100644
+--- a/sound/core/seq/oss/seq_oss_init.c
++++ b/sound/core/seq/oss/seq_oss_init.c
+@@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level)
+ return 0;
+
+ _error:
+- snd_seq_oss_writeq_delete(dp->writeq);
+- snd_seq_oss_readq_delete(dp->readq);
+ snd_seq_oss_synth_cleanup(dp);
+ snd_seq_oss_midi_cleanup(dp);
+- delete_port(dp);
+ delete_seq_queue(dp->queue);
+- kfree(dp);
++ delete_port(dp);
+
+ return rc;
+ }
+@@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp)
+ static int
+ delete_port(struct seq_oss_devinfo *dp)
+ {
+- if (dp->port < 0)
++ if (dp->port < 0) {
++ kfree(dp);
+ return 0;
++ }
+
+ debug_printk(("delete_port %i\n", dp->port));
+ return snd_seq_event_port_detach(dp->cseq, dp->port);
diff --git a/execve-improve-interactivity-with-large-arguments.patch b/execve-improve-interactivity-with-large-arguments.patch
new file mode 100644
index 0000000..7908e6c
--- /dev/null
+++ b/execve-improve-interactivity-with-large-arguments.patch
@@ -0,0 +1,36 @@
+From: Roland McGrath <roland@redhat.com>
+Date: Wed, 8 Sep 2010 02:36:28 +0000 (-0700)
+Subject: execve: improve interactivity with large arguments
+X-Git-Tag: v2.6.36-rc4~13
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7993bc1f4663c0db67bb8f0d98e6678145b387cd
+
+execve: improve interactivity with large arguments
+
+This adds a preemption point during the copying of the argument and
+environment strings for execve, in copy_strings(). There is already
+a preemption point in the count() loop, so this doesn't add any new
+points in the abstract sense.
+
+When the total argument+environment strings are very large, the time
+spent copying them can be much more than a normal user time slice.
+So this change improves the interactivity of the rest of the system
+when one process is doing an execve with very large arguments.
+
+Signed-off-by: Roland McGrath <roland@redhat.com>
+Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 1b63237..6f2d777 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -419,6 +419,8 @@ static int copy_strings(int argc, const char __user *const __user *argv,
+ while (len > 0) {
+ int offset, bytes_to_copy;
+
++ cond_resched();
++
+ offset = pos % PAGE_SIZE;
+ if (offset == 0)
+ offset = PAGE_SIZE;
diff --git a/execve-make-responsive-to-sigkill-with-large-arguments.patch b/execve-make-responsive-to-sigkill-with-large-arguments.patch
new file mode 100644
index 0000000..a9e531a
--- /dev/null
+++ b/execve-make-responsive-to-sigkill-with-large-arguments.patch
@@ -0,0 +1,51 @@
+From: Roland McGrath <roland@redhat.com>
+Date: Wed, 8 Sep 2010 02:37:06 +0000 (-0700)
+Subject: execve: make responsive to SIGKILL with large arguments
+X-Git-Tag: v2.6.36-rc4~12
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9aea5a65aa7a1af9a4236dfaeb0088f1624f9919
+
+execve: make responsive to SIGKILL with large arguments
+
+An execve with a very large total of argument/environment strings
+can take a really long time in the execve system call. It runs
+uninterruptibly to count and copy all the strings. This change
+makes it abort the exec quickly if sent a SIGKILL.
+
+Note that this is the conservative change, to interrupt only for
+SIGKILL, by using fatal_signal_pending(). It would be perfectly
+correct semantics to let any signal interrupt the string-copying in
+execve, i.e. use signal_pending() instead of fatal_signal_pending().
+We'll save that change for later, since it could have user-visible
+consequences, such as having a timer set too quickly make it so that
+an execve can never complete, though it always happened to work before.
+
+Signed-off-by: Roland McGrath <roland@redhat.com>
+Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 6f2d777..828dd24 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -376,6 +376,9 @@ static int count(const char __user * const __user * argv, int max)
+ argv++;
+ if (i++ >= max)
+ return -E2BIG;
++
++ if (fatal_signal_pending(current))
++ return -ERESTARTNOHAND;
+ cond_resched();
+ }
+ }
+@@ -419,6 +422,10 @@ static int copy_strings(int argc, const char __user *const __user *argv,
+ while (len > 0) {
+ int offset, bytes_to_copy;
+
++ if (fatal_signal_pending(current)) {
++ ret = -ERESTARTNOHAND;
++ goto out;
++ }
+ cond_resched();
+
+ offset = pos % PAGE_SIZE;
diff --git a/kernel.spec b/kernel.spec
index 797f477..e87e09e 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -48,7 +48,7 @@ Summary: The Linux kernel
# reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
# scripts/rebase.sh should be made to do that for you, actually.
#
-%global baserelease 167
+%global baserelease 168
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -640,6 +640,11 @@ Patch21: linux-2.6-tracehook.patch
Patch22: linux-2.6-utrace.patch
Patch23: linux-2.6-utrace-ptrace.patch
+Patch100: 01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
+Patch101: 02-compat-test-rax-for-the-system-call-number-not-eax.patch
+Patch102: 03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
+Patch103: aio-check-for-multiplication-overflow-in-do_io_submit.patch
+
Patch141: linux-2.6-ps3-storage-alias.patch
Patch143: linux-2.6-g5-therm-shutdown.patch
Patch144: linux-2.6-vio-modalias.patch
@@ -842,6 +847,21 @@ Patch14141: hid-02-fix-suspend-crash-by-moving-initializations-earlier.patch
Patch14150: irda-correctly-clean-up-self-ias_obj-on-irda_bind-failure.patch
+Patch14200: net-do-not-check-capable-if-kernel.patch
+
+# Mitigate DOS with large argument lists
+Patch14210: execve-improve-interactivity-with-large-arguments.patch
+Patch14211: execve-make-responsive-to-sigkill-with-large-arguments.patch
+Patch14212: setup_arg_pages-diagnose-excessive-argument-size.patch
+
+# CVE-2010-3080
+Patch14220: alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
+# CVE-2010-2960
+Patch14230: keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
+Patch14231: keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
+# CVE-2010-3079
+Patch14240: tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
+
Patch19997: xen.pvops.pre.patch
Patch19998: xen.pvops.patch
Patch19999: xen.pvops.post.patch
@@ -1286,6 +1306,11 @@ ApplyPatch linux-2.6-utrace-ptrace.patch
ApplyPatch via-hwmon-temp-sensor.patch
ApplyPatch linux-2.6-dell-laptop-rfkill-fix.patch
+ApplyPatch 01-compat-make-compat_alloc_user_space-incorporate-the-access_ok-check.patch
+ApplyPatch 02-compat-test-rax-for-the-system-call-number-not-eax.patch
+ApplyPatch 03-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch
+
+
#
# Intel IOMMU
#
@@ -1319,6 +1344,7 @@ ApplyPatch linux-2.6-execshield.patch
#
# bugfixes to drivers and filesystems
#
+ApplyPatch aio-check-for-multiplication-overflow-in-do_io_submit.patch
# ext4
@@ -1556,6 +1582,22 @@ ApplyPatch hid-02-fix-suspend-crash-by-moving-initializations-earlier.patch
# CVE-2010-2954
ApplyPatch irda-correctly-clean-up-self-ias_obj-on-irda_bind-failure.patch
+# rhbz #598796
+ApplyPatch net-do-not-check-capable-if-kernel.patch
+
+# Mitigate DOS with large argument lists
+ApplyPatch execve-improve-interactivity-with-large-arguments.patch
+ApplyPatch execve-make-responsive-to-sigkill-with-large-arguments.patch
+ApplyPatch setup_arg_pages-diagnose-excessive-argument-size.patch
+
+# CVE-2010-3080
+ApplyPatch alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
+# CVE-2010-2960
+ApplyPatch keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
+ApplyPatch keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
+# CVE-2010-3079
+ApplyPatch tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
+
ApplyPatch xen.pvops.pre.patch
ApplyPatch xen.pvops.patch
ApplyPatch xen.pvops.post.patch
@@ -2212,6 +2254,24 @@ fi
%kernel_variant_files -k vmlinux %{with_kdump} kdump
%changelog
+* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.32.21-168
+- Fix three CVEs:
+ CVE-2010-3080: /dev/sequencer open failure is not handled correctly
+ CVE-2010-2960: keyctl_session_to_parent NULL deref system crash
+ CVE-2010-3079: ftrace NULL pointer dereference
+
+* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com>
+- Mitigate DOS with large argument lists.
+
+* Tue Sep 14 2010 Kyle McMartin <kyle@redhat.com>
+- x86_64: plug compat syscalls holes. (CVE-2010-3081, CVE-2010-3301)
+ upgrading is highly recommended.
+- aio: check for multiplication overflow in do_io_submit. (CVE-2010-3067)
+
+* Mon Sep 06 2010 Kyle McMartin <kyle@redhat.com>
+- Backport two fixes from Eric Paris to resolve #598796 which avoids a
+ capability check if the request comes from the kernel.
+
* Fri Sep 03 2010 Michael Young <m.a.young@durham.ac.uk>
- update pvops to 2.6.32.21
- Set new dom0 related option CONFIG_NET_SCH_PLUG=m
diff --git a/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch b/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
new file mode 100644
index 0000000..fb62519
--- /dev/null
+++ b/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
@@ -0,0 +1,52 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 10 Sep 2010 08:59:51 +0000 (+0100)
+Subject: KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3d96406c7da1ed5811ea52a3b0905f4f0e295376
+
+KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring
+
+Fix a bug in keyctl_session_to_parent() whereby it tries to check the ownership
+of the parent process's session keyring whether or not the parent has a session
+keyring [CVE-2010-2960].
+
+This results in the following oops:
+
+ BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0
+ IP: [<ffffffff811ae4dd>] keyctl_session_to_parent+0x251/0x443
+ ...
+ Call Trace:
+ [<ffffffff811ae2f3>] ? keyctl_session_to_parent+0x67/0x443
+ [<ffffffff8109d286>] ? __do_fault+0x24b/0x3d0
+ [<ffffffff811af98c>] sys_keyctl+0xb4/0xb8
+ [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
+
+if the parent process has no session keyring.
+
+If the system is using pam_keyinit then it mostly protected against this as all
+processes derived from a login will have inherited the session keyring created
+by pam_keyinit during the log in procedure.
+
+To test this, pam_keyinit calls need to be commented out in /etc/pam.d/.
+
+Reported-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+[ 2.6.32 backport ]
+
+diff a/security/keys/keyctl.c b/security/keys/keyctl.c
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1291,7 +1291,8 @@ long keyctl_session_to_parent(void)
+ goto not_permitted;
+
+ /* the keyrings must have the same UID */
+- if (pcred ->tgcred->session_keyring->uid != mycred->euid ||
++ if ((pcred->tgcred->session_keyring &&
++ pcred->tgcred->session_keyring->uid != mycred->euid) ||
+ mycred->tgcred->session_keyring->uid != mycred->euid)
+ goto not_permitted;
+
+
diff --git a/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch b/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
new file mode 100644
index 0000000..5318f7e
--- /dev/null
+++ b/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
@@ -0,0 +1,64 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 10 Sep 2010 08:59:46 +0000 (+0100)
+Subject: KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9d1ac65a9698513d00e5608d93fca0c53f536c14
+
+KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
+
+There's an protected access to the parent process's credentials in the middle
+of keyctl_session_to_parent(). This results in the following RCU warning:
+
+ ===================================================
+ [ INFO: suspicious rcu_dereference_check() usage. ]
+ ---------------------------------------------------
+ security/keys/keyctl.c:1291 invoked rcu_dereference_check() without protection!
+
+ other info that might help us debug this:
+
+ rcu_scheduler_active = 1, debug_locks = 0
+ 1 lock held by keyctl-session-/2137:
+ #0: (tasklist_lock){.+.+..}, at: [<ffffffff811ae2ec>] keyctl_session_to_parent+0x60/0x236
+
+ stack backtrace:
+ Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1
+ Call Trace:
+ [<ffffffff8105606a>] lockdep_rcu_dereference+0xaa/0xb3
+ [<ffffffff811ae379>] keyctl_session_to_parent+0xed/0x236
+ [<ffffffff811af77e>] sys_keyctl+0xb4/0xb6
+ [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
+
+The code should take the RCU read lock to make sure the parents credentials
+don't go away, even though it's holding a spinlock and has IRQ disabled.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index b2b0998..3868c67 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1272,6 +1272,7 @@ long keyctl_session_to_parent(void)
+ keyring_r = NULL;
+
+ me = current;
++ rcu_read_lock();
+ write_lock_irq(&tasklist_lock);
+
+ parent = me->real_parent;
+@@ -1319,6 +1320,7 @@ long keyctl_session_to_parent(void)
+ set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME);
+
+ write_unlock_irq(&tasklist_lock);
++ rcu_read_unlock();
+ if (oldcred)
+ put_cred(oldcred);
+ return 0;
+@@ -1327,6 +1329,7 @@ already_same:
+ ret = 0;
+ not_permitted:
+ write_unlock_irq(&tasklist_lock);
++ rcu_read_unlock();
+ put_cred(cred);
+ return ret;
+
diff --git a/net-do-not-check-capable-if-kernel.patch b/net-do-not-check-capable-if-kernel.patch
new file mode 100644
index 0000000..0669a6c
--- /dev/null
+++ b/net-do-not-check-capable-if-kernel.patch
@@ -0,0 +1,682 @@
+commit abbee616fa69a781c6e58249318a7ae6796a3394
+Author: Eric Paris <eparis@redhat.com>
+Date: Thu Nov 5 20:45:52 2009 -0800
+
+ net: check kern before calling security subsystem
+
+ Before calling capable(CAP_NET_RAW) check if this operations is on behalf
+ of the kernel or on behalf of userspace. Do not do the security check if
+ it is on behalf of the kernel.
+
+ Signed-off-by: Eric Paris <eparis@redhat.com>
+ Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 8b7950c0735ab6228f08e7b19fc0f94c09c7f2ba
+Author: Eric Paris <eparis@redhat.com>
+Date: Thu Nov 5 22:18:14 2009 -0800
+
+ net: pass kern to net_proto_family create function
+
+ The generic __sock_create function has a kern argument which allows the
+ security system to make decisions based on if a socket is being created by
+ the kernel or by userspace. This patch passes that flag to the
+ net_proto_family specific create function, so it can do the same thing.
+
+ Signed-off-by: Eric Paris <eparis@redhat.com>
+ Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+---
+ drivers/isdn/mISDN/socket.c | 2 +-
+ drivers/net/pppox.c | 3 ++-
+ include/linux/net.h | 3 ++-
+ net/appletalk/ddp.c | 3 ++-
+ net/atm/pvc.c | 3 ++-
+ net/atm/svc.c | 7 ++++---
+ net/ax25/af_ax25.c | 3 ++-
+ net/bluetooth/af_bluetooth.c | 5 +++--
+ net/bluetooth/bnep/sock.c | 3 ++-
+ net/bluetooth/cmtp/sock.c | 3 ++-
+ net/bluetooth/hci_sock.c | 3 ++-
+ net/bluetooth/hidp/sock.c | 3 ++-
+ net/bluetooth/l2cap.c | 5 +++--
+ net/bluetooth/rfcomm/sock.c | 3 ++-
+ net/bluetooth/sco.c | 3 ++-
+ net/can/af_can.c | 3 ++-
+ net/decnet/af_decnet.c | 3 ++-
+ net/econet/af_econet.c | 3 ++-
+ net/ieee802154/af_ieee802154.c | 2 +-
+ net/ipv4/af_inet.c | 5 +++--
+ net/ipv6/af_inet6.c | 5 +++--
+ net/ipx/af_ipx.c | 3 ++-
+ net/irda/af_irda.c | 7 ++++---
+ net/iucv/af_iucv.c | 3 ++-
+ net/key/af_key.c | 3 ++-
+ net/llc/af_llc.c | 5 ++++-
+ net/netlink/af_netlink.c | 3 ++-
+ net/netrom/af_netrom.c | 3 ++-
+ net/packet/af_packet.c | 3 ++-
+ net/phonet/af_phonet.c | 3 ++-
+ net/rds/af_rds.c | 3 ++-
+ net/rose/af_rose.c | 3 ++-
+ net/rxrpc/af_rxrpc.c | 3 ++-
+ net/socket.c | 2 +-
+ net/tipc/socket.c | 6 ++++--
+ net/unix/af_unix.c | 3 ++-
+ net/x25/af_x25.c | 3 ++-
+ 37 files changed, 83 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
+index feb0fa4..8167346 100644
+--- a/drivers/isdn/mISDN/socket.c
++++ b/drivers/isdn/mISDN/socket.c
+@@ -779,7 +779,7 @@ base_sock_create(struct net *net, struct socket *sock, int protocol)
+ }
+
+ static int
+-mISDN_sock_create(struct net *net, struct socket *sock, int proto)
++mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
+ {
+ int err = -EPROTONOSUPPORT;
+
+diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
+index 4f6d33f..a155baf 100644
+--- a/drivers/net/pppox.c
++++ b/drivers/net/pppox.c
+@@ -104,7 +104,8 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+
+ EXPORT_SYMBOL(pppox_ioctl);
+
+-static int pppox_create(struct net *net, struct socket *sock, int protocol)
++static int pppox_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ int rc = -EPROTOTYPE;
+
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 529a093..3a63efd 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -200,7 +200,8 @@ struct proto_ops {
+
+ struct net_proto_family {
+ int family;
+- int (*create)(struct net *net, struct socket *sock, int protocol);
++ int (*create)(struct net *net, struct socket *sock,
++ int protocol, int kern);
+ struct module *owner;
+ };
+
+diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
+index b1a4290..7c22d90 100644
+--- a/net/appletalk/ddp.c
++++ b/net/appletalk/ddp.c
+@@ -1021,7 +1021,8 @@ static struct proto ddp_proto = {
+ * Create a socket. Initialise the socket, blank the addresses
+ * set the state.
+ */
+-static int atalk_create(struct net *net, struct socket *sock, int protocol)
++static int atalk_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ int rc = -ESOCKTNOSUPPORT;
+diff --git a/net/atm/pvc.c b/net/atm/pvc.c
+index d4c0245..e879725 100644
+--- a/net/atm/pvc.c
++++ b/net/atm/pvc.c
+@@ -127,7 +127,8 @@ static const struct proto_ops pvc_proto_ops = {
+ };
+
+
+-static int pvc_create(struct net *net, struct socket *sock,int protocol)
++static int pvc_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+diff --git a/net/atm/svc.c b/net/atm/svc.c
+index f90d143..ed096a6 100644
+--- a/net/atm/svc.c
++++ b/net/atm/svc.c
+@@ -25,7 +25,7 @@
+ #include "signaling.h"
+ #include "addr.h"
+
+-static int svc_create(struct net *net, struct socket *sock,int protocol);
++static int svc_create(struct net *net, struct socket *sock, int protocol, int kern);
+
+ /*
+ * Note: since all this is still nicely synchronized with the signaling demon,
+@@ -330,7 +330,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
+
+ lock_sock(sk);
+
+- error = svc_create(sock_net(sk), newsock,0);
++ error = svc_create(sock_net(sk), newsock, 0, 0);
+ if (error)
+ goto out;
+
+@@ -650,7 +650,8 @@ static const struct proto_ops svc_proto_ops = {
+ };
+
+
+-static int svc_create(struct net *net, struct socket *sock,int protocol)
++static int svc_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ int error;
+
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index f454607..274d5c0 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -800,7 +800,8 @@ static struct proto ax25_proto = {
+ .obj_size = sizeof(struct sock),
+ };
+
+-static int ax25_create(struct net *net, struct socket *sock, int protocol)
++static int ax25_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ ax25_cb *ax25;
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index 8cfb5a8..af074ed 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -126,7 +126,8 @@ int bt_sock_unregister(int proto)
+ }
+ EXPORT_SYMBOL(bt_sock_unregister);
+
+-static int bt_sock_create(struct net *net, struct socket *sock, int proto)
++static int bt_sock_create(struct net *net, struct socket *sock, int proto,
++ int kern)
+ {
+ int err;
+
+@@ -144,7 +145,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
+ read_lock(&bt_proto_lock);
+
+ if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
+- err = bt_proto[proto]->create(net, sock, proto);
++ err = bt_proto[proto]->create(net, sock, proto, kern);
+ bt_sock_reclassify_lock(sock, proto);
+ module_put(bt_proto[proto]->owner);
+ }
+diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
+index e857628..ee86b31 100644
+--- a/net/bluetooth/bnep/sock.c
++++ b/net/bluetooth/bnep/sock.c
+@@ -195,7 +195,8 @@ static struct proto bnep_proto = {
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int bnep_sock_create(struct net *net, struct socket *sock, int protocol)
++static int bnep_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
+index 16b0fad..536482f 100644
+--- a/net/bluetooth/cmtp/sock.c
++++ b/net/bluetooth/cmtp/sock.c
+@@ -190,7 +190,8 @@ static struct proto cmtp_proto = {
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol)
++static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 75302a9..94a138f 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -621,7 +621,8 @@ static struct proto hci_sk_proto = {
+ .obj_size = sizeof(struct hci_pinfo)
+ };
+
+-static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
++static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
+index 37c9d7d..40fac2c 100644
+--- a/net/bluetooth/hidp/sock.c
++++ b/net/bluetooth/hidp/sock.c
+@@ -241,7 +241,8 @@ static struct proto hidp_proto = {
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
++static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
+index 8d1c4a9..0fdf477 100644
+--- a/net/bluetooth/l2cap.c
++++ b/net/bluetooth/l2cap.c
+@@ -819,7 +819,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
+ return sk;
+ }
+
+-static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
++static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+@@ -831,7 +832,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
+ sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
+ return -ESOCKTNOSUPPORT;
+
+- if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
++ if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
+ return -EPERM;
+
+ sock->ops = &l2cap_sock_ops;
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index 30a3649..f596455 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -323,7 +323,8 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int
+ return sk;
+ }
+
+-static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol)
++static int rfcomm_sock_create(struct net *net, struct socket *sock,
++ int protocol, int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index 5c0685e..2c06950 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -430,7 +430,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
+ return sk;
+ }
+
+-static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
++static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index 6068321..bcd546f 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -114,7 +114,8 @@ static void can_sock_destruct(struct sock *sk)
+ skb_queue_purge(&sk->sk_receive_queue);
+ }
+
+-static int can_create(struct net *net, struct socket *sock, int protocol)
++static int can_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct can_proto *cp;
+diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
+index 7a58c87..5540230 100644
+--- a/net/decnet/af_decnet.c
++++ b/net/decnet/af_decnet.c
+@@ -675,7 +675,8 @@ char *dn_addr2asc(__u16 addr, char *buf)
+
+
+
+-static int dn_create(struct net *net, struct socket *sock, int protocol)
++static int dn_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
+index 0e0254f..b9d5f2f 100644
+--- a/net/econet/af_econet.c
++++ b/net/econet/af_econet.c
+@@ -605,7 +605,8 @@ static struct proto econet_proto = {
+ * Create an Econet socket
+ */
+
+-static int econet_create(struct net *net, struct socket *sock, int protocol)
++static int econet_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct econet_sock *eo;
+diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
+index cd949d5..40dcb54 100644
+--- a/net/ieee802154/af_ieee802154.c
++++ b/net/ieee802154/af_ieee802154.c
+@@ -234,7 +234,7 @@ static const struct proto_ops ieee802154_dgram_ops = {
+ * set the state.
+ */
+ static int ieee802154_create(struct net *net, struct socket *sock,
+- int protocol)
++ int protocol, int kern)
+ {
+ struct sock *sk;
+ int rc;
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 57737b8..e718ab6 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -262,7 +262,8 @@ static inline int inet_netns_ok(struct net *net, int protocol)
+ * Create an inet socket.
+ */
+
+-static int inet_create(struct net *net, struct socket *sock, int protocol)
++static int inet_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct inet_protosw *answer;
+@@ -325,7 +326,7 @@ lookup_protocol:
+ }
+
+ err = -EPERM;
+- if (answer->capability > 0 && !capable(answer->capability))
++ if (answer->capability > 0 && !kern && !capable(answer->capability))
+ goto out_rcu_unlock;
+
+ err = -EAFNOSUPPORT;
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index e127a32..10776f0 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -95,7 +95,8 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
+ return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
+ }
+
+-static int inet6_create(struct net *net, struct socket *sock, int protocol)
++static int inet6_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct inet_sock *inet;
+ struct ipv6_pinfo *np;
+@@ -158,7 +159,7 @@ lookup_protocol:
+ }
+
+ err = -EPERM;
+- if (answer->capability > 0 && !capable(answer->capability))
++ if (answer->capability > 0 && !kern && !capable(answer->capability))
+ goto out_rcu_unlock;
+
+ sock->ops = answer->ops;
+diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
+index 66c7a20..7a7ac38 100644
+--- a/net/ipx/af_ipx.c
++++ b/net/ipx/af_ipx.c
+@@ -1352,7 +1352,8 @@ static struct proto ipx_proto = {
+ .obj_size = sizeof(struct ipx_sock),
+ };
+
+-static int ipx_create(struct net *net, struct socket *sock, int protocol)
++static int ipx_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ int rc = -ESOCKTNOSUPPORT;
+ struct sock *sk;
+diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
+index dd35641..ef1ac44 100644
+--- a/net/irda/af_irda.c
++++ b/net/irda/af_irda.c
+@@ -61,7 +61,7 @@
+
+ #include <net/irda/af_irda.h>
+
+-static int irda_create(struct net *net, struct socket *sock, int protocol);
++static int irda_create(struct net *net, struct socket *sock, int protocol, int kern);
+
+ static const struct proto_ops irda_stream_ops;
+ static const struct proto_ops irda_seqpacket_ops;
+@@ -839,7 +839,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
+
+ IRDA_DEBUG(2, "%s()\n", __func__);
+
+- err = irda_create(sock_net(sk), newsock, sk->sk_protocol);
++ err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
+ if (err)
+ return err;
+
+@@ -1062,7 +1062,8 @@ static struct proto irda_proto = {
+ * Create IrDA socket
+ *
+ */
+-static int irda_create(struct net *net, struct socket *sock, int protocol)
++static int irda_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct irda_sock *self;
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index bada1b9..efc05e1 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -482,7 +482,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+ }
+
+ /* Create an IUCV socket */
+-static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
++static int iucv_sock_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index 4e98193..8c44f69 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -177,7 +177,8 @@ static struct proto key_proto = {
+ .obj_size = sizeof(struct pfkey_sock),
+ };
+
+-static int pfkey_create(struct net *net, struct socket *sock, int protocol)
++static int pfkey_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
+ struct sock *sk;
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index 7aa4fd1..6f38b8a 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -140,14 +140,17 @@ static struct proto llc_proto = {
+
+ /**
+ * llc_ui_create - alloc and init a new llc_ui socket
++ * @net: network namespace (must be default network)
+ * @sock: Socket to initialize and attach allocated sk to.
+ * @protocol: Unused.
++ * @kern: on behalf of kernel or userspace
+ *
+ * Allocate and initialize a new llc_ui socket, validate the user wants a
+ * socket type we have available.
+ * Returns 0 upon success, negative upon failure.
+ */
+-static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
++static int llc_ui_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ int rc = -ESOCKTNOSUPPORT;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 5a7dcdf..eadedb5 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -428,7 +428,8 @@ static int __netlink_create(struct net *net, struct socket *sock,
+ return 0;
+ }
+
+-static int netlink_create(struct net *net, struct socket *sock, int protocol)
++static int netlink_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct module *module = NULL;
+ struct mutex *cb_mutex;
+diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
+index 7a83495..837e10b 100644
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -425,7 +425,8 @@ static struct proto nr_proto = {
+ .obj_size = sizeof(struct nr_sock),
+ };
+
+-static int nr_create(struct net *net, struct socket *sock, int protocol)
++static int nr_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct nr_sock *nr;
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 41866eb..e0e3f6c 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1350,7 +1350,8 @@ static struct proto packet_proto = {
+ * Create a packet of type SOCK_PACKET.
+ */
+
+-static int packet_create(struct net *net, struct socket *sock, int protocol)
++static int packet_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct packet_sock *po;
+diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
+index f60c0c2..61bcae9 100644
+--- a/net/phonet/af_phonet.c
++++ b/net/phonet/af_phonet.c
+@@ -60,7 +60,8 @@ static inline void phonet_proto_put(struct phonet_protocol *pp)
+
+ /* protocol family functions */
+
+-static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
++static int pn_socket_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct pn_sock *pn;
+diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
+index 98e0538..ca35aad 100644
+--- a/net/rds/af_rds.c
++++ b/net/rds/af_rds.c
+@@ -407,7 +407,8 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
+ return 0;
+ }
+
+-static int rds_create(struct net *net, struct socket *sock, int protocol)
++static int rds_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 502cce7..f167ed0 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -512,7 +512,8 @@ static struct proto rose_proto = {
+ .obj_size = sizeof(struct rose_sock),
+ };
+
+-static int rose_create(struct net *net, struct socket *sock, int protocol)
++static int rose_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct rose_sock *rose;
+diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
+index a86afce..b37e304 100644
+--- a/net/rxrpc/af_rxrpc.c
++++ b/net/rxrpc/af_rxrpc.c
+@@ -608,7 +608,8 @@ static unsigned int rxrpc_poll(struct file *file, struct socket *sock,
+ /*
+ * create an RxRPC socket
+ */
+-static int rxrpc_create(struct net *net, struct socket *sock, int protocol)
++static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct rxrpc_sock *rx;
+ struct sock *sk;
+diff --git a/net/socket.c b/net/socket.c
+index 7565536..55c6e4f 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -1216,7 +1216,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol,
+ /* Now protected by module ref count */
+ rcu_read_unlock();
+
+- err = pf->create(net, sock, protocol);
++ err = pf->create(net, sock, protocol, kern);
+ if (err < 0)
+ goto out_module_put;
+
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c
+index e6d9abf..d00c211 100644
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -177,6 +177,7 @@ static void reject_rx_queue(struct sock *sk)
+ * @net: network namespace (must be default network)
+ * @sock: pre-allocated socket structure
+ * @protocol: protocol indicator (must be 0)
++ * @kern: caused by kernel or by userspace?
+ *
+ * This routine creates additional data structures used by the TIPC socket,
+ * initializes them, and links them together.
+@@ -184,7 +185,8 @@ static void reject_rx_queue(struct sock *sk)
+ * Returns 0 on success, errno otherwise
+ */
+
+-static int tipc_create(struct net *net, struct socket *sock, int protocol)
++static int tipc_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ const struct proto_ops *ops;
+ socket_state state;
+@@ -1528,7 +1530,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
+
+ buf = skb_peek(&sk->sk_receive_queue);
+
+- res = tipc_create(sock_net(sock->sk), new_sock, 0);
++ res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
+ if (!res) {
+ struct sock *new_sk = new_sock->sk;
+ struct tipc_sock *new_tsock = tipc_sk(new_sk);
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index fc820cd..a1e3c85 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -621,7 +621,8 @@ out:
+ return sk;
+ }
+
+-static int unix_create(struct net *net, struct socket *sock, int protocol)
++static int unix_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ if (protocol && protocol != PF_UNIX)
+ return -EPROTONOSUPPORT;
+diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
+index 7fa9c7a..62c47a4 100644
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -501,7 +501,8 @@ out:
+ return sk;
+ }
+
+-static int x25_create(struct net *net, struct socket *sock, int protocol)
++static int x25_create(struct net *net, struct socket *sock, int protocol,
++ int kern)
+ {
+ struct sock *sk;
+ struct x25_sock *x25;
diff --git a/setup_arg_pages-diagnose-excessive-argument-size.patch b/setup_arg_pages-diagnose-excessive-argument-size.patch
new file mode 100644
index 0000000..ead972a
--- /dev/null
+++ b/setup_arg_pages-diagnose-excessive-argument-size.patch
@@ -0,0 +1,42 @@
+From: Roland McGrath <roland@redhat.com>
+Date: Wed, 8 Sep 2010 02:35:49 +0000 (-0700)
+Subject: setup_arg_pages: diagnose excessive argument size
+X-Git-Tag: v2.6.36-rc4~14
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1b528181b2ffa14721fb28ad1bd539fe1732c583
+
+setup_arg_pages: diagnose excessive argument size
+
+The CONFIG_STACK_GROWSDOWN variant of setup_arg_pages() does not
+check the size of the argument/environment area on the stack.
+When it is unworkably large, shift_arg_pages() hits its BUG_ON.
+This is exploitable with a very large RLIMIT_STACK limit, to
+create a crash pretty easily.
+
+Check that the initial stack is not too large to make it possible
+to map in any executable. We're not checking that the actual
+executable (or intepreter, for binfmt_elf) will fit. So those
+mappings might clobber part of the initial stack mapping. But
+that is just userland lossage that userland made happen, not a
+kernel problem.
+
+Signed-off-by: Roland McGrath <roland@redhat.com>
+Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 2d94552..1b63237 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -594,6 +594,11 @@ int setup_arg_pages(struct linux_binprm *bprm,
+ #else
+ stack_top = arch_align_stack(stack_top);
+ stack_top = PAGE_ALIGN(stack_top);
++
++ if (unlikely(stack_top < mmap_min_addr) ||
++ unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
++ return -ENOMEM;
++
+ stack_shift = vma->vm_end - stack_top;
+
+ bprm->p -= stack_shift;
diff --git a/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch b/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
new file mode 100644
index 0000000..4bbae71
--- /dev/null
+++ b/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
@@ -0,0 +1,51 @@
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Wed, 8 Sep 2010 15:20:37 +0000 (-0400)
+Subject: tracing: Do not allow llseek to set_ftrace_filter
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9c55cb12c1c172e2d51e85fbb5a4796ca86b77e7
+
+tracing: Do not allow llseek to set_ftrace_filter
+
+Reading the file set_ftrace_filter does three things.
+
+1) shows whether or not filters are set for the function tracer
+2) shows what functions are set for the function tracer
+3) shows what triggers are set on any functions
+
+3 is independent from 1 and 2.
+
+The way this file currently works is that it is a state machine,
+and as you read it, it may change state. But this assumption breaks
+when you use lseek() on the file. The state machine gets out of sync
+and the t_show() may use the wrong pointer and cause a kernel oops.
+
+Luckily, this will only kill the app that does the lseek, but the app
+dies while holding a mutex. This prevents anyone else from using the
+set_ftrace_filter file (or any other function tracing file for that matter).
+
+A real fix for this is to rewrite the code, but that is too much for
+a -rc release or stable. This patch simply disables llseek on the
+set_ftrace_filter() file for now, and we can do the proper fix for the
+next major release.
+
+Reported-by: Robert Swiecki <swiecki@google.com>
+Cc: Chris Wright <chrisw@sous-sol.org>
+Cc: Tavis Ormandy <taviso@google.com>
+Cc: Eugene Teo <eugene@redhat.com>
+Cc: vendor-sec@lst.de
+Cc: <stable@kernel.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+---
+
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 7cb1f45..83a16e9 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -2416,7 +2416,7 @@ static const struct file_operations ftrace_filter_fops = {
+ .open = ftrace_filter_open,
+ .read = seq_read,
+ .write = ftrace_filter_write,
+- .llseek = ftrace_regex_lseek,
++ .llseek = no_llseek,
+ .release = ftrace_filter_release,
+ };
+