diff options
author | Andy Lutomirski <luto@MIT.EDU> | 2011-06-05 13:50:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-06-07 04:02:35 -0400 |
commit | 5cec93c216db77c45f7ce970d46283bcb1933884 (patch) | |
tree | 1dffa866471cd3f4ad1a342e389d3a14cb87d05f /include/linux | |
parent | 5dfcea629a08b4684a019cd0cb59d0c9129a6c02 (diff) |
x86-64: Emulate legacy vsyscalls
There's a fair amount of code in the vsyscall page. It contains
a syscall instruction (in the gettimeofday fallback) and who
knows what will happen if an exploit jumps into the middle of
some other code.
Reduce the risk by replacing the vsyscalls with short magic
incantations that cause the kernel to emulate the real
vsyscalls. These incantations are useless if entered in the
middle.
This causes vsyscalls to be a little more expensive than real
syscalls. Fortunately sensible programs don't use them.
The only exception is time() which is still called by glibc
through the vsyscall - but calling time() millions of times
per second is not sensible. glibc has this fixed in the
development tree.
This patch is not perfect: the vread_tsc and vread_hpet
functions are still at a fixed address. Fixing that might
involve making alternative patching work in the vDSO.
Signed-off-by: Andy Lutomirski <luto@mit.edu>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jesper Juhl <jj@chaosbits.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Jan Beulich <JBeulich@novell.com>
Cc: richard -rw- weinberger <richard.weinberger@gmail.com>
Cc: Mikael Pettersson <mikpe@it.uu.se>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Louis Rilling <Louis.Rilling@kerlabs.com>
Cc: Valdis.Kletnieks@vt.edu
Cc: pageexec@freemail.hu
Link: http://lkml.kernel.org/r/e64e1b3c64858820d12c48fa739efbd1485e79d5.1307292171.git.luto@mit.edu
[ Removed the CONFIG option - it's simpler to just do it unconditionally. Tidied up the code as well. ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/seccomp.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 167c33361d9c..cc7a4e9cc7ad 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h | |||
@@ -19,6 +19,11 @@ static inline void secure_computing(int this_syscall) | |||
19 | extern long prctl_get_seccomp(void); | 19 | extern long prctl_get_seccomp(void); |
20 | extern long prctl_set_seccomp(unsigned long); | 20 | extern long prctl_set_seccomp(unsigned long); |
21 | 21 | ||
22 | static inline int seccomp_mode(seccomp_t *s) | ||
23 | { | ||
24 | return s->mode; | ||
25 | } | ||
26 | |||
22 | #else /* CONFIG_SECCOMP */ | 27 | #else /* CONFIG_SECCOMP */ |
23 | 28 | ||
24 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
@@ -37,6 +42,11 @@ static inline long prctl_set_seccomp(unsigned long arg2) | |||
37 | return -EINVAL; | 42 | return -EINVAL; |
38 | } | 43 | } |
39 | 44 | ||
45 | static inline int seccomp_mode(seccomp_t *s) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | |||
40 | #endif /* CONFIG_SECCOMP */ | 50 | #endif /* CONFIG_SECCOMP */ |
41 | 51 | ||
42 | #endif /* _LINUX_SECCOMP_H */ | 52 | #endif /* _LINUX_SECCOMP_H */ |