Merge branch 'f12/master' into f12/user/myoung/xendom0
Conflicts: kernel.spec
This commit is contained in:
commit
2022e0a640
|
@ -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 = ¤t->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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
|
@ -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;
|
|
@ -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;
|
62
kernel.spec
62
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -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,
|
||||
};
|
||||
|
Loading…
Reference in New Issue