diff --git a/debian/changelog b/debian/changelog index 6090a53f4..36742be6f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,9 @@ linux (3.16.7-ckt4-3) UNRELEASED; urgency=medium * [sh4] ftrace: Remove -m32 option from recordmcount.pl (Closes: #775611) * [x86] Revert "KVM: Fix of previously incomplete fix for CVE-2014-8480" as that issue does not affect 3.16 + * [amd64] tls, ldt: Stop checking lm in LDT_empty (regression in 3.16.7-ckt4) + * [x86] tls: Interpret an all-zero struct user_desc as "no segment" + (regression in 3.16.7-ckt4) [ Ian Campbell ] * [xen] cancel ballooning if adding new memory failed (Closes: #776448) diff --git a/debian/patches/bugfix/x86/x86-tls-interpret-an-all-zero-struct-user_desc-as-no.patch b/debian/patches/bugfix/x86/x86-tls-interpret-an-all-zero-struct-user_desc-as-no.patch new file mode 100644 index 000000000..dfb9b68e6 --- /dev/null +++ b/debian/patches/bugfix/x86/x86-tls-interpret-an-all-zero-struct-user_desc-as-no.patch @@ -0,0 +1,112 @@ +From: Andy Lutomirski +Date: Thu, 22 Jan 2015 11:27:59 -0800 +Subject: x86, tls: Interpret an all-zero struct user_desc as "no segment" +Origin: https://git.kernel.org/linus/3669ef9fa7d35f573ec9c0e0341b29251c2734a7 + +The Witcher 2 did something like this to allocate a TLS segment index: + + struct user_desc u_info; + bzero(&u_info, sizeof(u_info)); + u_info.entry_number = (uint32_t)-1; + + syscall(SYS_set_thread_area, &u_info); + +Strictly speaking, this code was never correct. It should have set +read_exec_only and seg_not_present to 1 to indicate that it wanted +to find a free slot without putting anything there, or it should +have put something sensible in the TLS slot if it wanted to allocate +a TLS entry for real. The actual effect of this code was to +allocate a bogus segment that could be used to exploit espfix. + +The set_thread_area hardening patches changed the behavior, causing +set_thread_area to return -EINVAL and crashing the game. + +This changes set_thread_area to interpret this as a request to find +a free slot and to leave it empty, which isn't *quite* what the game +expects but should be close enough to keep it working. In +particular, using the code above to allocate two segments will +allocate the same segment both times. + +According to FrostbittenKing on Github, this fixes The Witcher 2. + +If this somehow still causes problems, we could instead allocate +a limit==0 32-bit data segment, but that seems rather ugly to me. + +Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix +Signed-off-by: Andy Lutomirski +Cc: stable@vger.kernel.org +Cc: torvalds@linux-foundation.org +Link: http://lkml.kernel.org/r/0cb251abe1ff0958b8e468a9a9a905b80ae3a746.1421954363.git.luto@amacapital.net +Signed-off-by: Thomas Gleixner +--- + arch/x86/include/asm/desc.h | 13 +++++++++++++ + arch/x86/kernel/tls.c | 25 +++++++++++++++++++++++-- + 2 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h +index fc237fd..a94b82e 100644 +--- a/arch/x86/include/asm/desc.h ++++ b/arch/x86/include/asm/desc.h +@@ -262,6 +262,19 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) + (info)->seg_not_present == 1 && \ + (info)->useable == 0) + ++/* Lots of programs expect an all-zero user_desc to mean "no segment at all". */ ++static inline bool LDT_zero(const struct user_desc *info) ++{ ++ return (info->base_addr == 0 && ++ info->limit == 0 && ++ info->contents == 0 && ++ info->read_exec_only == 0 && ++ info->seg_32bit == 0 && ++ info->limit_in_pages == 0 && ++ info->seg_not_present == 0 && ++ info->useable == 0); ++} ++ + static inline void clear_LDT(void) + { + set_ldt(NULL, 0); +diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c +index 4e942f3..7fc5e84 100644 +--- a/arch/x86/kernel/tls.c ++++ b/arch/x86/kernel/tls.c +@@ -29,7 +29,28 @@ static int get_free_idx(void) + + static bool tls_desc_okay(const struct user_desc *info) + { +- if (LDT_empty(info)) ++ /* ++ * For historical reasons (i.e. no one ever documented how any ++ * of the segmentation APIs work), user programs can and do ++ * assume that a struct user_desc that's all zeros except for ++ * entry_number means "no segment at all". This never actually ++ * worked. In fact, up to Linux 3.19, a struct user_desc like ++ * this would create a 16-bit read-write segment with base and ++ * limit both equal to zero. ++ * ++ * That was close enough to "no segment at all" until we ++ * hardened this function to disallow 16-bit TLS segments. Fix ++ * it up by interpreting these zeroed segments the way that they ++ * were almost certainly intended to be interpreted. ++ * ++ * The correct way to ask for "no segment at all" is to specify ++ * a user_desc that satisfies LDT_empty. To keep everything ++ * working, we accept both. ++ * ++ * Note that there's a similar kludge in modify_ldt -- look at ++ * the distinction between modes 1 and 0x11. ++ */ ++ if (LDT_empty(info) || LDT_zero(info)) + return true; + + /* +@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, + cpu = get_cpu(); + + while (n-- > 0) { +- if (LDT_empty(info)) ++ if (LDT_empty(info) || LDT_zero(info)) + desc->a = desc->b = 0; + else + fill_ldt(desc, info); diff --git a/debian/patches/bugfix/x86/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch b/debian/patches/bugfix/x86/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch new file mode 100644 index 000000000..c543a87fc --- /dev/null +++ b/debian/patches/bugfix/x86/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch @@ -0,0 +1,49 @@ +From: Andy Lutomirski +Date: Thu, 22 Jan 2015 11:27:58 -0800 +Subject: x86, tls, ldt: Stop checking lm in LDT_empty +Origin: https://git.kernel.org/linus/e30ab185c490e9a9381385529e0fd32f0a399495 + +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 +Cc: torvalds@linux-foundation.org +Link: http://lkml.kernel.org/r/72a059de55e86ad5e2935c80aa91880ddf19d07c.1421954363.git.luto@amacapital.net +Signed-off-by: Thomas Gleixner +--- + arch/x86/include/asm/desc.h | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h +index 50d033a..fc237fd 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) + 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 && \ +@@ -261,12 +262,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); diff --git a/debian/patches/series b/debian/patches/series index 634ebf5d3..63b3bfd40 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -497,3 +497,5 @@ bugfix/all/crypto-include-crypto-module-prefix-in-template.patch bugfix/all/crypto-add-missing-crypto-module-aliases.patch bugfix/x86/kvm-x86-sysenter-emulation-is-broken.patch bugfix/sh4/scripts-recordmcount.pl-there-is-no-m32-option-on-super-h.patch +bugfix/x86/x86-tls-ldt-stop-checking-lm-in-ldt_empty.patch +bugfix/x86/x86-tls-interpret-an-all-zero-struct-user_desc-as-no.patch