View Issue Details

IDProjectCategoryView StatusLast Update
0004518CentOS-5kernelpublic2010-09-21 18:13
Reportertru 
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version5.5 
Target VersionFixed in Version 
Summary0004518: CVE-2010-3081
Description1) public exploit (with backdoor) for gaining root on a CentOS-5 x86_64 machine
2) only x86_64 machine are affected from kernel-2.6.18-164 and onward (CentOS-5.4 too)
Additional Informationreference and workaround (looing 32 bits compatibility)

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-3081

uptream:
https://access.redhat.com/kb/docs/DOC-40265
https://bugzilla.redhat.com/show_bug.cgi?id=634457
(expect new kernel in the next days)

ksplice:
http://www.ksplice.com/uptrack/cve-2010-3081
http://blog.ksplice.com/2010/09/cve-2010-3081/
TagsNo tags attached.

Activities

tru

tru

2010-09-20 13:06

administrator   ~0011860

a kernel (kernel-2.6.18-194.11.3.el5.CVE_2010_3081) in c5 testing is being built (credits to gmk and mej)

2010-09-20 19:55

 

linux-2.6.18rh-CVE_2010_3081.patch (4,389 bytes)
diff -Nur linux-2.6.18.x86_64/include/asm-mips/compat.h linux-2.6.18.x86_64.mej/include/asm-mips/compat.h
--- linux-2.6.18.x86_64/include/asm-mips/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/asm-mips/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -138,7 +138,7 @@
 	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 -Nur linux-2.6.18.x86_64/include/asm-parisc/compat.h linux-2.6.18.x86_64.mej/include/asm-parisc/compat.h
--- linux-2.6.18.x86_64/include/asm-parisc/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/asm-parisc/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -144,7 +144,7 @@
 	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 -Nur linux-2.6.18.x86_64/include/asm-powerpc/compat.h linux-2.6.18.x86_64.mej/include/asm-powerpc/compat.h
--- linux-2.6.18.x86_64/include/asm-powerpc/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/asm-powerpc/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -131,7 +131,7 @@
 	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 -Nur linux-2.6.18.x86_64/include/asm-s390/compat.h linux-2.6.18.x86_64.mej/include/asm-s390/compat.h
--- linux-2.6.18.x86_64/include/asm-s390/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/asm-s390/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -133,7 +133,7 @@
 	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)
 {
 	unsigned long stack;
 
diff -Nur linux-2.6.18.x86_64/include/asm-x86_64/compat.h linux-2.6.18.x86_64.mej/include/asm-x86_64/compat.h
--- linux-2.6.18.x86_64/include/asm-x86_64/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/asm-x86_64/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -196,7 +196,7 @@
 	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->rsp - len; 
diff -Nur linux-2.6.18.x86_64/include/linux/compat.h linux-2.6.18.x86_64.mej/include/linux/compat.h
--- linux-2.6.18.x86_64/include/linux/compat.h	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/include/linux/compat.h	2010-09-16 14:45:26.000000000 -0700
@@ -5,6 +5,10 @@
  * syscall compatibility layer.
  */
 
+#include <linux/compiler.h>
+
+extern void __user *compat_alloc_user_space(unsigned long len);
+
 #ifdef CONFIG_COMPAT
 
 #include <linux/stat.h>
diff -Nur linux-2.6.18.x86_64/kernel/compat.c linux-2.6.18.x86_64.mej/kernel/compat.c
--- linux-2.6.18.x86_64/kernel/compat.c	2010-09-16 14:46:21.000000000 -0700
+++ linux-2.6.18.x86_64.mej/kernel/compat.c	2010-09-16 14:47:08.000000000 -0700
@@ -22,6 +22,7 @@
 #include <linux/security.h>
 #include <linux/timex.h>
 #include <linux/migrate.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 
@@ -950,3 +951,24 @@
 	return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
 }
 #endif
+
+/*
+ * 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);
tru

tru

2010-09-20 19:58

administrator   ~0011861

linux-2.6.18rh-CVE_2010_3081.patch is the included patch, I am also attaching the proposed patch in the upstream bugzilla entry (https://bugzilla.redhat.com/attachment.cgi?id=448317 -> linux-2.6-security-64-bit-compatibility-mode-stack-pointer-underflow.patch)

2010-09-20 19:59

 

linux-2.6-security-64-bit-compatibility-mode-stack-pointer-underflow.patch (6,974 bytes)
#################################################################
# Roberto Yokota						#
# roberto.yokota at locaweb.com.br - bob69xxx at gmail.com	#
# RHCE #805007735629340						#
#################################################################
# Sun Sep 19 11:37:59 BRT 2010					#
# patch for rhel5 - 2.6.18-194.11.3.el5 			#
#################################################################

# Bug 634457 - CVE-2010-3081
# https://bugzilla.redhat.com/show_bug.cgi?id=634457

## Retro vulnerability 
# http://xorl.wordpress.com/2009/08/07/cve-2007-4573-linux-kernel-ia32-system-call-emulation-vulnerability/

## New report
# http://sota.gen.nz/compat1/
# http://sota.gen.nz/compat2/

## Fix
# http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=36d001c70d8a0144ac1d038f6876c484849a74de
# http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=eefdca043e8391dcd719711716492063030b55ac
# http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c41d68a513c71e35a14f66d71782d27a79a81ea6


--- a/arch/x86_64/ia32/ia32entry.S	2010-09-19 10:46:28.000000000 -0300
+++ b/arch/x86_64/ia32/ia32entry.S	2010-09-19 10:41:32.000000000 -0300
@@ -127,7 +127,7 @@ ENTRY(ia32_sysenter_target)
 	CFI_REMEMBER_STATE
 	jnz  sysenter_tracesys
 sysenter_do_call:	
-	cmpl	$(IA32_NR_syscalls-1),%eax
+	cmpq	$(IA32_NR_syscalls-1),%rax
 	ja	ia32_badsys
 	IA32_ARG_FIXUP
 	call	*ia32_sys_call_table(,%rax,8)
@@ -232,7 +232,7 @@ ENTRY(ia32_cstar_target)
 	CFI_REMEMBER_STATE
 	jnz   cstar_tracesys
 cstar_do_call:	
-	cmpl $IA32_NR_syscalls-1,%eax
+	cmpq $IA32_NR_syscalls-1,%rax
 	ja  ia32_badsys
 	IA32_ARG_FIXUP 1
 	call *ia32_sys_call_table(,%rax,8)
@@ -322,7 +322,7 @@ ENTRY(ia32_syscall)
 	orl   $TS_COMPAT,threadinfo_status(%r10)
 	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_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
@@ -340,7 +340,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)
--- a/include/asm-ia64/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-ia64/compat.h	2010-09-19 10:53:05.000000000 -0300
@@ -196,7 +196,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);
--- a/include/asm-mips/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-mips/compat.h	2010-09-19 10:53:51.000000000 -0300
@@ -138,7 +138,7 @@ static inline compat_uptr_t ptr_to_compa
 	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;
--- a/include/asm-parisc/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-parisc/compat.h	2010-09-19 10:54:47.000000000 -0300
@@ -144,7 +144,7 @@ static inline compat_uptr_t ptr_to_compa
 	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];
--- a/include/asm-powerpc/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-powerpc/compat.h	2010-09-19 10:55:33.000000000 -0300
@@ -131,7 +131,7 @@ static inline compat_uptr_t ptr_to_compa
 	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];
--- a/include/asm-s390/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-s390/compat.h	2010-09-19 10:56:15.000000000 -0300
@@ -133,7 +133,7 @@ static inline compat_uptr_t ptr_to_compa
 	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)
 {
 	unsigned long stack;
 
--- a/include/asm-sparc64/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-sparc64/compat.h	2010-09-19 10:57:21.000000000 -0300
@@ -164,7 +164,7 @@ static inline compat_uptr_t ptr_to_compa
 	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];
--- a/include/asm-x86_64/compat.h	2006-09-20 00:42:06.000000000 -0300
+++ b/include/asm-x86_64/compat.h	2010-09-19 10:41:32.000000000 -0300
@@ -196,7 +196,7 @@ static inline compat_uptr_t ptr_to_compa
 	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->rsp - len; 
--- a/include/linux/compat.h	2010-09-19 10:45:53.000000000 -0300
+++ b/include/linux/compat.h	2010-09-19 10:41:32.000000000 -0300
@@ -235,6 +235,7 @@ static inline int compat_timespec_compar
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int compat_printk(const char *fmt, ...);
+extern void __user *compat_alloc_user_space(unsigned long len);
 
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
--- a/kernel/compat.c	2006-09-20 00:42:06.000000000 -0300
+++ b/kernel/compat.c	2010-09-19 10:41:32.000000000 -0300
@@ -22,6 +22,7 @@
 #include <linux/security.h>
 #include <linux/timex.h>
 #include <linux/migrate.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 
@@ -950,3 +951,24 @@ asmlinkage long compat_sys_move_pages(pi
 	return sys_move_pages(pid, nr_pages, pages, nodes, status, flags);
 }
 #endif
+
+/*
+ * 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);
tru

tru

2010-09-20 20:35

administrator   ~0011862

c5 testing has been populated, please test and report (success or failure)
tru

tru

2010-09-20 20:58

administrator   ~0011863

wget http://dev.centos.org/centos/5/CentOS-Testing.repo -O /etc/yum.repos.d/CentOS-Testing.repo
edit the file if needed for priority/... (see wiki.centos.org for more details)
and run
yum --enablerepo=c5-testing update kernel\*
then reboot
kbsingh@karan.org

kbsingh@karan.org

2010-09-20 23:30

administrator   ~0011864

we are aware of the limited bandwidth available to the machine and are working to get a couple of mirrors setup
tru

tru

2010-09-21 08:26

administrator   ~0011865

https://rhn.redhat.com/errata/RHSA-2010-0704.html has been released

the official kernel (kernel-2.6.18-194.11.4.el5.src.rpm) will be pushed as soon as possible
tru

tru

2010-09-21 18:13

administrator   ~0011867

the patched kernel has been released :)

Issue History

Date Modified Username Field Change
2010-09-20 13:04 tru New Issue
2010-09-20 13:06 tru Note Added: 0011860
2010-09-20 13:07 tru Status new => confirmed
2010-09-20 19:55 tru File Added: linux-2.6.18rh-CVE_2010_3081.patch
2010-09-20 19:58 tru Note Added: 0011861
2010-09-20 19:59 tru File Added: linux-2.6-security-64-bit-compatibility-mode-stack-pointer-underflow.patch
2010-09-20 20:35 tru Note Added: 0011862
2010-09-20 20:58 tru Note Added: 0011863
2010-09-20 23:30 kbsingh@karan.org Note Added: 0011864
2010-09-21 08:26 tru Note Added: 0011865
2010-09-21 18:13 tru Note Added: 0011867
2010-09-21 18:13 tru Status confirmed => closed
2010-09-21 18:13 tru Resolution open => fixed