Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4060

kernel-2.6.18-194.11.1.el5.src.rpm

From: Jiri Olsa <jolsa@redhat.com>
Date: Tue, 12 May 2009 16:00:56 +0200
Subject: [x86_64] 32-bit ptrace emulation mishandles 6th arg
Message-id: 20090512140056.GA3453@jolsa.englab.brq.redhat.com
O-Subject: [PATCH RHEL5.4] BZ495125 x86_64 - 32-bit ptrace emulation mishandles 6th arg
Bugzilla: 495125
RH-Acked-by: Vitaly Mayatskikh <vmayatsk@redhat.com>
RH-Acked-by: Chris Lalancette <clalance@redhat.com>

Bugzilla:
=========
https://bugzilla.redhat.com/show_bug.cgi?id=495125

Description:
============
On x86_64, strace is reporting invalid values of the 6th syscall argument when
run on 32-bit executables.

Upstream status:
================
x86 - 32-bit ptrace emulation mishandles 6th arg
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ecd744eec3aa8bbc949ec04ed3fbf7ecb2958a0e

x86-64: slightly stream-line 32-bit syscall entry code
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=295286a89107c353b9677bc604361c537fd6a1c0

Test status of the patch:
=========================
tested with attached reproducer on AMD and INTEL CPUs

wbr, jirka

diff --git a/arch/x86_64/ia32/ia32entry-xen.S b/arch/x86_64/ia32/ia32entry-xen.S
index 8aa41fb..b0838f8 100644
--- a/arch/x86_64/ia32/ia32entry-xen.S
+++ b/arch/x86_64/ia32/ia32entry-xen.S
@@ -32,11 +32,11 @@
 	.endm 
 
 	/* clobbers %eax */	
-	.macro  CLEAR_RREGS
+	.macro  CLEAR_RREGS _r9=rax
 	xorl 	%eax,%eax
 	movq	%rax,R11(%rsp)
 	movq	%rax,R10(%rsp)
-	movq	%rax,R9(%rsp)
+	movq    %\_r9,R9(%rsp)
 	movq	%rax,R8(%rsp)
 	.endm
 
@@ -55,11 +55,10 @@
 #define __sti		sti	
 #endif			
 
-	.macro LOAD_ARGS32 offset
-	movl \offset(%rsp),%r11d
-	movl \offset+8(%rsp),%r10d
+	.macro LOAD_ARGS32 offset, _r9=0
+	.if \_r9
 	movl \offset+16(%rsp),%r9d
-	movl \offset+24(%rsp),%r8d
+	.endif
 	movl \offset+40(%rsp),%ecx
 	movl \offset+48(%rsp),%edx
 	movl \offset+56(%rsp),%esi
@@ -136,7 +135,7 @@ ENTRY(ia32_sysenter_target)
 	SAVE_ARGS 0,0,0
  	/* no need to do an access_ok check here because rbp has been
  	   32bit zero extended */ 
-1:	movl	(%rbp),%r9d
+1:	movl	(%rbp),%ebp
  	.section __ex_table,"a"
  	.quad 1b,ia32_badarg
  	.previous	
@@ -148,7 +147,7 @@ ENTRY(ia32_sysenter_target)
 sysenter_do_call:	
 	cmpl	$(IA32_NR_syscalls-1),%eax
 	ja	ia32_badsys
-	IA32_ARG_FIXUP 1
+	IA32_ARG_FIXUP
 	call	*ia32_sys_call_table(,%rax,8)
 	movq	%rax,RAX-ARGOFFSET(%rsp)
 	GET_THREAD_INFO(%r10)
@@ -185,13 +184,6 @@ sysenter_tracesys:
 	call	syscall_trace_enter
 	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	movl	%ebp, %ebp
-	/* no need to do an access_ok check here because rbp has been
-	   32bit zero extended */ 
-1:	movl	(%rbp),%r9d
-	.section __ex_table,"a"
-	.quad 1b,ia32_badarg
-	.previous
 	jmp	sysenter_do_call
 	CFI_ENDPROC
 ENDPROC(ia32_sysenter_target)
@@ -282,20 +274,15 @@ cstar_do_call:
 	
 cstar_tracesys:	
 	CFI_RESTORE_STATE
+	xchgl %r9d,%ebp
 	SAVE_REST
-	CLEAR_RREGS
+	CLEAR_RREGS r9
 	movq $-ENOSYS,RAX(%rsp)	/* really needed? */
 	movq %rsp,%rdi        /* &pt_regs -> arg1 */
 	call syscall_trace_enter
-	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
+	LOAD_ARGS32 ARGOFFSET 1 /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	movl RSP-ARGOFFSET(%rsp), %r8d
-	/* no need to do an access_ok check here because r8 has been
-	   32bit zero extended */ 
-1:	movl	(%r8),%r9d
-	.section __ex_table,"a"
-	.quad 1b,ia32_badarg
-	.previous
+	xchgl %ebp,%r9d
 	jmp cstar_do_call
 END(ia32_cstar_target)
 				
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 50ca6d6..b365454 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -30,19 +30,18 @@
 	.endm 
 
 	/* clobbers %eax */	
-	.macro  CLEAR_RREGS
+	.macro  CLEAR_RREGS _r9=rax
 	xorl 	%eax,%eax
 	movq	%rax,R11(%rsp)
 	movq	%rax,R10(%rsp)
-	movq	%rax,R9(%rsp)
+	movq    %\_r9,R9(%rsp)
 	movq	%rax,R8(%rsp)
 	.endm
 
-	.macro LOAD_ARGS32 offset
-	movl \offset(%rsp),%r11d
-	movl \offset+8(%rsp),%r10d
+	.macro LOAD_ARGS32 offset, _r9=0
+	.if \_r9
 	movl \offset+16(%rsp),%r9d
-	movl \offset+24(%rsp),%r8d
+	.endif
 	movl \offset+40(%rsp),%ecx
 	movl \offset+48(%rsp),%edx
 	movl \offset+56(%rsp),%esi
@@ -118,7 +117,7 @@ ENTRY(ia32_sysenter_target)
 	SAVE_ARGS 0,0,0
  	/* no need to do an access_ok check here because rbp has been
  	   32bit zero extended */ 
-1:	movl	(%rbp),%r9d
+1:	movl	(%rbp),%ebp
  	.section __ex_table,"a"
  	.quad 1b,ia32_badarg
  	.previous	
@@ -130,7 +129,7 @@ ENTRY(ia32_sysenter_target)
 sysenter_do_call:	
 	cmpl	$(IA32_NR_syscalls-1),%eax
 	ja	ia32_badsys
-	IA32_ARG_FIXUP 1
+	IA32_ARG_FIXUP
 	call	*ia32_sys_call_table(,%rax,8)
 	movq	%rax,RAX-ARGOFFSET(%rsp)
 	GET_THREAD_INFO(%r10)
@@ -165,13 +164,6 @@ sysenter_tracesys:
 	call	syscall_trace_enter
 	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	movl	%ebp, %ebp
-	/* no need to do an access_ok check here because rbp has been
-	   32bit zero extended */ 
-1:	movl	(%rbp),%r9d
-	.section __ex_table,"a"
-	.quad 1b,ia32_badarg
-	.previous
 	jmp	sysenter_do_call
 	CFI_ENDPROC
 ENDPROC(ia32_sysenter_target)
@@ -260,20 +252,15 @@ cstar_do_call:
 	
 cstar_tracesys:	
 	CFI_RESTORE_STATE
+	xchgl %r9d,%ebp
 	SAVE_REST
-	CLEAR_RREGS
+	CLEAR_RREGS r9
 	movq $-ENOSYS,RAX(%rsp)	/* really needed? */
 	movq %rsp,%rdi        /* &pt_regs -> arg1 */
 	call syscall_trace_enter
-	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
+	LOAD_ARGS32 ARGOFFSET 1 /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	movl RSP-ARGOFFSET(%rsp), %r8d
-	/* no need to do an access_ok check here because r8 has been
-	   32bit zero extended */ 
-1:	movl	(%r8),%r9d
-	.section __ex_table,"a"
-	.quad 1b,ia32_badarg
-	.previous
+	xchgl %ebp,%r9d
 	jmp cstar_do_call
 END(ia32_cstar_target)