x86: prevent binaries from making system calls using the wrong syscall interface
PATCH 1/1 x86: prevent binaries from making system calls using the wrong syscall interface
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
Since the 32 bit and 64 bit system call numbers are different this means that a binary could attempt to obfuscate which system calls it was actually making by using the "wrong" system call interface. In particular, the call to audit_syscall_entry() relies on checking the TIF_IA32 flag to determine whether it is dealing with a 32 or 64 bit system call without regard to the actual type of system call that was made.While this specific issue could be addressed by checking the TS_COMPAT flag in threadinfo_status it seems preferable to simply disallow this situation altogether.
---
arch/x86/ia32/ia32entry.S +8 -0
@@ -123,6 +123,8 @@ .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) CFI_REMEMBER_STATE
@@ -230,6 +232,8 @@ .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) CFI_REMEMBER_STATE
@@ -324,6 +328,8 @@ this could be a problem. */ SAVE_ARGS 0,0,1 GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) jnz ia32_tracesys
@@ -347,6 +353,8 @@ jmp ia32_do_syscall END(ia32_syscall) +ia32_bad_abi: + CFI_REMEMBER_STATE ia32_badsys: movq $0,ORIG_RAX-ARGOFFSET(%rsp) movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
arch/x86/kernel/entry_64.S +3 -1
@@ -244,7 +244,7 @@ movq %rcx,RIP-ARGOFFSET(%rsp) CFI_REL_OFFSET rip,RIP-ARGOFFSET GET_THREAD_INFO(%rcx) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP|_TIF_IA32),threadinfo_flags(%rcx) jnz tracesys cmpq $__NR_syscall_max,%rax ja badsys
@@ -318,6 +318,8 @@ /* Do syscall tracing */ tracesys: + testl $_TIF_IA32,threadinfo_flags(%rcx) + jnz badsys SAVE_REST movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ FIXUP_TOP_OF_STACK %rdi
Quoted 6 lines
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
I thought this was a feature?
arch/x86/ia32/ia32entry.S line 130
Quoted 13 lines
Index:
linux-2.6.26.2/arch/x86/ia32/ia32entry.S
===================================================================arch/x86/ia32/ia32entry.S +2
-0@@ -123,6 +123,8 @@ .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) CFI_REMEMBER_STATE
...and slowing down all syscalls for this is certainly bad idea.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Quoted 7 lines · Michael Davidson
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
Quoted 9 lines
Since the 32 bit and 64 bit system call numbers are different this means that a binary could attempt to obfuscate which system calls it was actually making by using the "wrong" system call interface. In particular, the call to
audit_syscall_entry()relies on checking theTIF_IA32flag to determine whether it is dealing with a 32 or 64 bit system call without regard to the actual type of system call that was made.While this specific issue could be addressed by checking theTS_COMPATflag inthreadinfo_statusit seems preferable to simply disallow this situation altogether.
I asked Andi whether 64-bit processes are allowed to make 32-bit syscalls on May 4 2007, and he stated that yes it's both allowed and supposed to work. (The thread was cc:d to [email protected].)
Quoted 21 lines
arch/x86/ia32/ia32entry.S +4
-0@@ -123,6 +123,8 @@ .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) CFI_REMEMBER_STATE@@ -230,6 +232,8 @@ .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) CFI_REMEMBER_STATE
arch/x86/ia32/ia32entry.S line 335
Quoted 8 lines
arch/x86/ia32/ia32entry.S +2
-0@@ -324,6 +328,8 @@ this could be a problem. */ SAVE_ARGS 0,0,1 GET_THREAD_INFO(%r10) + testl $_TIF_IA32,threadinfo_flags(%r10) + jz ia32_bad_abi orl $TS_COMPAT,threadinfo_status(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) jnz ia32_tracesys
Your patch slows down all compat-mode syscalls.
/Mikael
Quoted 3 lines
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
What about applications that choose to do this
- Test tools
- Tools where certain interfaces are only available 32bit ?
Quoted 9 lines
Since the 32 bit and 64 bit system call numbers are different this means that a binary could attempt to obfuscate which system calls it was actually making by using the "wrong" system call interface. In particular, the call to
audit_syscall_entry()relies on checking theTIF_IA32flag to determine whether it is dealing with a 32 or 64 bit system call without regard to the actual type of system call that was made.While this specific issue could be addressed by checking theTS_COMPATflag inthreadinfo_statusit seems preferable to simply disallow this situation altogether.
That is a significant change of kernel ABI considering it exists just to wallpaper over crappy audit tools.
I'm definitely against that approach.
Alan
Quoted 2 lines · On Wed, 6 Aug 2008 17:34:59 -0700 (PDT) [email protected] (Michael Davidson) wrote:
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
since you can have mixed 32 / 64 binaries just fine I don't think your patch is the right thing to do in general.
Signature · 3 lines
If you want to reach me at my work email, use [email protected] For development, discussion and tips for power savings, visit http://www.lesswatts.org
Quoted 7 lines · Michael Davidson
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
No. While I'm not sure it's been used, it would definitely be useful to be able to invoke 32-bit int 0x80 syscalls in 64-bit bit process for something like Valgrind.
Issuing 64-bit syscalls from a 32-bit process would be... interesting.
Quoted 7 lines
Since the 32 bit and 64 bit system call numbers are different this means that a binary could attempt to obfuscate which system calls it was actually making by using the "wrong" system call interface. In particular, the call to
audit_syscall_entry()relies on checking theTIF_IA32flag to determine whether it is dealing with a 32 or 64 bit system call without regard to the actual type of system call that was made.
Or just have separate 32-compat vs 64 bit audit paths which can clearly make the distinction.
J
Quoted 6 lines · [email protected] (Michael Davidson) writes:
Prevent binaries from making system calls using other than one of the "normal" system call interfaces for that binary type.
Currently there is nothing to prevent 64 bit binaries from attempting to make system calls using the 32 bit system call interfaces and vice versa.
nack. That was allowed intentionally because there are some use cases for 32bit syscalls from 64bit (e.g. 64bit JIT running 32bit executable). I believe it is used in production in a few cases.
Quoted 10 lines
Since the 32 bit and 64 bit system call numbers are different this means that a binary could attempt to obfuscate which system calls it was actually making by using the "wrong" system call interface. In particular, the call to
audit_syscall_entry()relies on checking theTIF_IA32flag to determine whether it is dealing with a 32 or 64 bit system call without regard to the actual type of system call that was made.While this specific issue could be addressed by checking theTS_COMPATflag inthreadinfo_statusit seems preferable to simply disallow this situation altogether.
audit is wrong to assume this and should be just fixed
-Andi
OK - I did not realize that this was a "feature".
I have already submitted a one line patch to fix the audit path.