diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2010-09-14 15:42:41 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-09-14 19:08:46 -0400 |
commit | 36d001c70d8a0144ac1d038f6876c484849a74de (patch) | |
tree | 98e061ce49af5ce48d6d67ffe5d3258563f4445d /arch/x86/ia32 | |
parent | c41d68a513c71e35a14f66d71782d27a79a81ea6 (diff) |
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>
Diffstat (limited to 'arch/x86/ia32')
-rw-r--r-- | 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 b86feabed69b..84e3a4ef9719 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -153,7 +153,7 @@ ENTRY(ia32_sysenter_target) | |||
153 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 153 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
154 | CFI_REMEMBER_STATE | 154 | CFI_REMEMBER_STATE |
155 | jnz sysenter_tracesys | 155 | jnz sysenter_tracesys |
156 | cmpl $(IA32_NR_syscalls-1),%eax | 156 | cmpq $(IA32_NR_syscalls-1),%rax |
157 | ja ia32_badsys | 157 | ja ia32_badsys |
158 | sysenter_do_call: | 158 | sysenter_do_call: |
159 | IA32_ARG_FIXUP | 159 | IA32_ARG_FIXUP |
@@ -195,7 +195,7 @@ sysexit_from_sys_call: | |||
195 | movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ | 195 | movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ |
196 | call audit_syscall_entry | 196 | call audit_syscall_entry |
197 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ | 197 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ |
198 | cmpl $(IA32_NR_syscalls-1),%eax | 198 | cmpq $(IA32_NR_syscalls-1),%rax |
199 | ja ia32_badsys | 199 | ja ia32_badsys |
200 | movl %ebx,%edi /* reload 1st syscall arg */ | 200 | movl %ebx,%edi /* reload 1st syscall arg */ |
201 | movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ | 201 | movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ |
@@ -248,7 +248,7 @@ sysenter_tracesys: | |||
248 | call syscall_trace_enter | 248 | call syscall_trace_enter |
249 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | 249 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ |
250 | RESTORE_REST | 250 | RESTORE_REST |
251 | cmpl $(IA32_NR_syscalls-1),%eax | 251 | cmpq $(IA32_NR_syscalls-1),%rax |
252 | ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ | 252 | ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ |
253 | jmp sysenter_do_call | 253 | jmp sysenter_do_call |
254 | CFI_ENDPROC | 254 | CFI_ENDPROC |
@@ -314,7 +314,7 @@ ENTRY(ia32_cstar_target) | |||
314 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 314 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
315 | CFI_REMEMBER_STATE | 315 | CFI_REMEMBER_STATE |
316 | jnz cstar_tracesys | 316 | jnz cstar_tracesys |
317 | cmpl $IA32_NR_syscalls-1,%eax | 317 | cmpq $IA32_NR_syscalls-1,%rax |
318 | ja ia32_badsys | 318 | ja ia32_badsys |
319 | cstar_do_call: | 319 | cstar_do_call: |
320 | IA32_ARG_FIXUP 1 | 320 | IA32_ARG_FIXUP 1 |
@@ -367,7 +367,7 @@ cstar_tracesys: | |||
367 | LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ | 367 | LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ |
368 | RESTORE_REST | 368 | RESTORE_REST |
369 | xchgl %ebp,%r9d | 369 | xchgl %ebp,%r9d |
370 | cmpl $(IA32_NR_syscalls-1),%eax | 370 | cmpq $(IA32_NR_syscalls-1),%rax |
371 | ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ | 371 | ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ |
372 | jmp cstar_do_call | 372 | jmp cstar_do_call |
373 | END(ia32_cstar_target) | 373 | END(ia32_cstar_target) |
@@ -425,7 +425,7 @@ ENTRY(ia32_syscall) | |||
425 | orl $TS_COMPAT,TI_status(%r10) | 425 | orl $TS_COMPAT,TI_status(%r10) |
426 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 426 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
427 | jnz ia32_tracesys | 427 | jnz ia32_tracesys |
428 | cmpl $(IA32_NR_syscalls-1),%eax | 428 | cmpq $(IA32_NR_syscalls-1),%rax |
429 | ja ia32_badsys | 429 | ja ia32_badsys |
430 | ia32_do_call: | 430 | ia32_do_call: |
431 | IA32_ARG_FIXUP | 431 | IA32_ARG_FIXUP |
@@ -444,7 +444,7 @@ ia32_tracesys: | |||
444 | call syscall_trace_enter | 444 | call syscall_trace_enter |
445 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | 445 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ |
446 | RESTORE_REST | 446 | RESTORE_REST |
447 | cmpl $(IA32_NR_syscalls-1),%eax | 447 | cmpq $(IA32_NR_syscalls-1),%rax |
448 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ | 448 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ |
449 | jmp ia32_do_call | 449 | jmp ia32_do_call |
450 | END(ia32_syscall) | 450 | END(ia32_syscall) |