]> git.hungrycats.org Git - linux/commitdiff
x86, tls, ldt: Stop checking lm in LDT_empty
authorAndy Lutomirski <luto@amacapital.net>
Thu, 22 Jan 2015 19:27:58 +0000 (11:27 -0800)
committerWilly Tarreau <w@1wt.eu>
Sun, 24 May 2015 08:10:34 +0000 (10:10 +0200)
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>
arch/x86/include/asm/desc.h

index 617bd56b3070d0ac570b752c73f52311e2fb68d1..66973a0562625b7b1debf5965b3de45066932ac5 100644 (file)
@@ -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);