diff --git a/kernel.spec b/kernel.spec index 25e337239..215c64e2d 100644 --- a/kernel.spec +++ b/kernel.spec @@ -627,6 +627,9 @@ Patch26096: cfg80211-don-t-WARN-about-two-consecutive-Country-IE.patch Patch26098: move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch Patch26099: deal-with-deadlock-in-d_walk.patch +#CVE-2014-8133 rhbz 1172797 1174374 +Patch26100: x86-tls-Validate-TLS-entries-to-protect-espfix.patch + # git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel Patch30000: kernel-arm64.patch @@ -1363,6 +1366,9 @@ ApplyPatch cfg80211-don-t-WARN-about-two-consecutive-Country-IE.patch ApplyPatch move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch ApplyPatch deal-with-deadlock-in-d_walk.patch +#CVE-2014-8133 rhbz 1172797 1174374 +ApplyPatch x86-tls-Validate-TLS-entries-to-protect-espfix.patch + %if 0%{?aarch64patches} ApplyPatch kernel-arm64.patch %ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does. @@ -2232,6 +2238,7 @@ fi # || || %changelog * Mon Dec 15 2014 Josh Boyer +- CVE-2014-8133 x86: espfix(64) bypass via set_thread_area and CLONE_SETTLS (rhbz 1172797 1174374) - CVE-2014-8559 deadlock due to incorrect usage of rename_lock (rhbz 1159313 1173814) * Fri Dec 12 2014 Kyle McMartin diff --git a/x86-tls-Validate-TLS-entries-to-protect-espfix.patch b/x86-tls-Validate-TLS-entries-to-protect-espfix.patch new file mode 100644 index 000000000..52c049767 --- /dev/null +++ b/x86-tls-Validate-TLS-entries-to-protect-espfix.patch @@ -0,0 +1,77 @@ +From: Andy Lutomirski +Date: Thu, 4 Dec 2014 16:48:16 -0800 +Subject: [PATCH] x86/tls: Validate TLS entries to protect espfix + +Installing a 16-bit RW data segment into the GDT defeats espfix. +AFAICT this will not affect glibc, Wine, or dosemu at all. + +Signed-off-by: Andy Lutomirski +Acked-by: H. Peter Anvin +Cc: stable@vger.kernel.org +Cc: Konrad Rzeszutek Wilk +Cc: Linus Torvalds +Cc: security@kernel.org +Cc: Willy Tarreau +Signed-off-by: Ingo Molnar +--- + arch/x86/kernel/tls.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c +index f7fec09e3e3a..e7650bd71109 100644 +--- a/arch/x86/kernel/tls.c ++++ b/arch/x86/kernel/tls.c +@@ -27,6 +27,21 @@ static int get_free_idx(void) + return -ESRCH; + } + ++static bool tls_desc_okay(const struct user_desc *info) ++{ ++ if (LDT_empty(info)) ++ return true; ++ ++ /* ++ * espfix is required for 16-bit data segments, but espfix ++ * only works for LDT segments. ++ */ ++ if (!info->seg_32bit) ++ return false; ++ ++ return true; ++} ++ + static void set_tls_desc(struct task_struct *p, int idx, + const struct user_desc *info, int n) + { +@@ -66,6 +81,9 @@ int do_set_thread_area(struct task_struct *p, int idx, + if (copy_from_user(&info, u_info, sizeof(info))) + return -EFAULT; + ++ if (!tls_desc_okay(&info)) ++ return -EINVAL; ++ + if (idx == -1) + idx = info.entry_number; + +@@ -192,6 +210,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, + { + struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; + const struct user_desc *info; ++ int i; + + if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || + (pos % sizeof(struct user_desc)) != 0 || +@@ -205,6 +224,10 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, + else + info = infobuf; + ++ for (i = 0; i < count / sizeof(struct user_desc); i++) ++ if (!tls_desc_okay(info + i)) ++ return -EINVAL; ++ + set_tls_desc(target, + GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)), + info, count / sizeof(struct user_desc)); +-- +2.1.0 +