diff options
author | Andy Lutomirski <luto@amacapital.net> | 2015-01-22 11:27:58 -0800 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2015-05-24 10:10:34 +0200 |
commit | 598b6280c55ff1a105cf8cd0f6b95aee86ce9016 (patch) | |
tree | 67afa94db68e50d61d360c89790044810a43efcc | |
parent | 85e01300f68eba959288a79901419ff06457a895 (diff) | |
download | lwn-598b6280c55ff1a105cf8cd0f6b95aee86ce9016.tar.gz lwn-598b6280c55ff1a105cf8cd0f6b95aee86ce9016.zip |
x86, tls, ldt: Stop checking lm in LDT_empty
commit e30ab185c490e9a9381385529e0fd32f0a399495 upstream.
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
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>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
(cherry picked from commit f62570cbdcb6dd53d0e2361488f9ea2c4cf17ec9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
-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 617bd56b3070..66973a056262 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -250,7 +250,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#define _LDT_empty(info) \ +/* This intentionally ignores lm, since 32-bit apps don't have that field. */ +#define LDT_empty(info) \ ((info)->base_addr == 0 && \ (info)->limit == 0 && \ (info)->contents == 0 && \ @@ -260,12 +261,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) (info)->seg_not_present == 1 && \ (info)->useable == 0) -#ifdef CONFIG_X86_64 -#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) -#else -#define LDT_empty(info) (_LDT_empty(info)) -#endif - static inline void clear_LDT(void) { set_ldt(NULL, 0); |