]>
Commit | Line | Data |
---|---|---|
1fc40873 AM |
1 | From: Andi Kleen <ak@suse.de> |
2 | Date: Fri, 21 Sep 2007 14:16:18 +0000 (+0200) | |
3 | Subject: [PATCH] x86_64: Zero extend all registers after ptrace in 32bit entry path. | |
4 | X-Git-Tag: v2.6.22.7~1 | |
5 | X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.22.y.git;a=commitdiff_plain;h=fc370f287729799250e04cb1d880140d14612bf0 | |
6 | ||
7 | [PATCH] x86_64: Zero extend all registers after ptrace in 32bit entry path. | |
8 | ||
9 | Strictly it's only needed for eax. | |
10 | ||
11 | It actually does a little more than strictly needed -- the other registers | |
12 | are already zero extended. | |
13 | ||
14 | Also remove the now unnecessary and non functional compat task check | |
15 | in ptrace. | |
16 | ||
17 | This is CVE-2007-4573 | |
18 | ||
19 | Found by Wojciech Purczynski | |
20 | ||
21 | Signed-off-by: Andi Kleen <ak@suse.de> | |
22 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
23 | Signed-off-by: Chris Wright <chrisw@sous-sol.org> | |
24 | --- | |
25 | ||
26 | diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S | |
27 | index 47565c3..0bc623a 100644 | |
28 | --- a/arch/x86_64/ia32/ia32entry.S | |
29 | +++ b/arch/x86_64/ia32/ia32entry.S | |
30 | @@ -38,6 +38,18 @@ | |
31 | movq %rax,R8(%rsp) | |
32 | .endm | |
33 | ||
34 | + .macro LOAD_ARGS32 offset | |
35 | + movl \offset(%rsp),%r11d | |
36 | + movl \offset+8(%rsp),%r10d | |
37 | + movl \offset+16(%rsp),%r9d | |
38 | + movl \offset+24(%rsp),%r8d | |
39 | + movl \offset+40(%rsp),%ecx | |
40 | + movl \offset+48(%rsp),%edx | |
41 | + movl \offset+56(%rsp),%esi | |
42 | + movl \offset+64(%rsp),%edi | |
43 | + movl \offset+72(%rsp),%eax | |
44 | + .endm | |
45 | + | |
46 | .macro CFI_STARTPROC32 simple | |
47 | CFI_STARTPROC \simple | |
48 | CFI_UNDEFINED r8 | |
49 | @@ -152,7 +164,7 @@ sysenter_tracesys: | |
50 | movq $-ENOSYS,RAX(%rsp) /* really needed? */ | |
51 | movq %rsp,%rdi /* &pt_regs -> arg1 */ | |
52 | call syscall_trace_enter | |
53 | - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
54 | + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
55 | RESTORE_REST | |
56 | movl %ebp, %ebp | |
57 | /* no need to do an access_ok check here because rbp has been | |
58 | @@ -255,7 +267,7 @@ cstar_tracesys: | |
59 | movq $-ENOSYS,RAX(%rsp) /* really needed? */ | |
60 | movq %rsp,%rdi /* &pt_regs -> arg1 */ | |
61 | call syscall_trace_enter | |
62 | - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
63 | + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
64 | RESTORE_REST | |
65 | movl RSP-ARGOFFSET(%rsp), %r8d | |
66 | /* no need to do an access_ok check here because r8 has been | |
67 | @@ -333,7 +345,7 @@ ia32_tracesys: | |
68 | movq $-ENOSYS,RAX(%rsp) /* really needed? */ | |
69 | movq %rsp,%rdi /* &pt_regs -> arg1 */ | |
70 | call syscall_trace_enter | |
71 | - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
72 | + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | |
73 | RESTORE_REST | |
74 | jmp ia32_do_syscall | |
75 | END(ia32_syscall) | |
76 | diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c | |
77 | index 9409117..8d89d8c 100644 | |
78 | --- a/arch/x86_64/kernel/ptrace.c | |
79 | +++ b/arch/x86_64/kernel/ptrace.c | |
80 | @@ -223,10 +223,6 @@ static int putreg(struct task_struct *child, | |
81 | { | |
82 | unsigned long tmp; | |
83 | ||
84 | - /* Some code in the 64bit emulation may not be 64bit clean. | |
85 | - Don't take any chances. */ | |
86 | - if (test_tsk_thread_flag(child, TIF_IA32)) | |
87 | - value &= 0xffffffff; | |
88 | switch (regno) { | |
89 | case offsetof(struct user_regs_struct,fs): | |
90 | if (value && (value & 3) != 3) |