diff options
author | Andy Lutomirski <luto@amacapital.net> | 2015-01-22 14:27:58 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-01-22 15:11:06 -0500 |
commit | e30ab185c490e9a9381385529e0fd32f0a399495 (patch) | |
tree | cc5524baa777da7cc0b168f4d4649e0029fd4045 /arch | |
parent | e9d1b4f3c60997fe197bf0243cb4a41a44387a88 (diff) |
x86, tls, ldt: Stop checking lm in LDT_empty
32-bit programs don't have an lm bit in their ABI, so they can't
reliably cause LDT_empty to return true without resorting to memset.
They shouldn't need to do this.
This should fix a longstanding, if minor, issue in all 64-bit kernels
as well as a potential regression in the TLS hardening code.
Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix
Cc: stable@vger.kernel.org
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Cc: torvalds@linux-foundation.org
Link: http://lkml.kernel.org/r/72a059de55e86ad5e2935c80aa91880ddf19d07c.1421954363.git.luto@amacapital.net
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/desc.h | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 50d033a8947d..fc237fd0259a 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | |||
251 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; | 251 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
252 | } | 252 | } |
253 | 253 | ||
254 | #define _LDT_empty(info) \ | 254 | /* This intentionally ignores lm, since 32-bit apps don't have that field. */ |
255 | #define LDT_empty(info) \ | ||
255 | ((info)->base_addr == 0 && \ | 256 | ((info)->base_addr == 0 && \ |
256 | (info)->limit == 0 && \ | 257 | (info)->limit == 0 && \ |
257 | (info)->contents == 0 && \ | 258 | (info)->contents == 0 && \ |
@@ -261,12 +262,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | |||
261 | (info)->seg_not_present == 1 && \ | 262 | (info)->seg_not_present == 1 && \ |
262 | (info)->useable == 0) | 263 | (info)->useable == 0) |
263 | 264 | ||
264 | #ifdef CONFIG_X86_64 | ||
265 | #define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) | ||
266 | #else | ||
267 | #define LDT_empty(info) (_LDT_empty(info)) | ||
268 | #endif | ||
269 | |||
270 | static inline void clear_LDT(void) | 265 | static inline void clear_LDT(void) |
271 | { | 266 | { |
272 | set_ldt(NULL, 0); | 267 | set_ldt(NULL, 0); |