2008-08-07 00:36:06

by Michael Davidson

[permalink] [raw]
Subject: [PATCH] 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.


Signed-off-by: Michael Davidson <[email protected]>

---

Index: linux-2.6.26.2/arch/x86/ia32/ia32entry.S
===================================================================
--- linux-2.6.26.2.orig/arch/x86/ia32/ia32entry.S 2008-08-06 09:19:01.000000000 -0700
+++ linux-2.6.26.2/arch/x86/ia32/ia32entry.S 2008-08-06 13:34:54.566992000 -0700
@@ -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)
Index: linux-2.6.26.2/arch/x86/kernel/entry_64.S
===================================================================
--- linux-2.6.26.2.orig/arch/x86/kernel/entry_64.S 2008-08-06 09:19:01.000000000 -0700
+++ linux-2.6.26.2/arch/x86/kernel/entry_64.S 2008-08-06 13:26:28.771994000 -0700
@@ -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


2008-08-07 07:49:31

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH] 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.

I thought this was a feature?

> Index: linux-2.6.26.2/arch/x86/ia32/ia32entry.S
> ===================================================================
> --- linux-2.6.26.2.orig/arch/x86/ia32/ia32entry.S 2008-08-06 09:19:01.000000000 -0700
> +++ linux-2.6.26.2/arch/x86/ia32/ia32entry.S 2008-08-06 13:34:54.566992000 -0700
> @@ -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
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2008-08-07 07:50:57

by Mikael Pettersson

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

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.
>
> 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.

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].)

> --- linux-2.6.26.2.orig/arch/x86/ia32/ia32entry.S 2008-08-06 09:19:01.000000000 -0700
> +++ linux-2.6.26.2/arch/x86/ia32/ia32entry.S 2008-08-06 13:34:54.566992000 -0700
> @@ -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

Your patch slows down all compat-mode syscalls.

/Mikael

2008-08-07 13:16:14

by Alan

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

> 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 ?

> 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.

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

2008-08-07 14:14:43

by Arjan van de Ven

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

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.


--
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

2008-08-08 06:29:49

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

Michael Davidson wrote:
> 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.

> 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.

Or just have separate 32-compat vs 64 bit audit paths which can clearly
make the distinction.

J

2008-08-08 11:16:42

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

[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.

>
> 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.

audit is wrong to assume this and should be just fixed

-Andi

2008-08-08 16:09:55

by Michael Davidson

[permalink] [raw]
Subject: Re: [PATCH] x86: prevent binaries from making system calls using the wrong syscall interface

OK - I did not realize that this was a "feature".

I have already submitted a one line patch to fix the audit path.