[linux] 01/01: Add various security fixes

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Mar 30 15:47:09 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit ed9e01eda05f25cc602bd9f1f06357615fee370e
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Mar 30 16:33:45 2016 +0100

    Add various security fixes
---
 debian/changelog                                   |   9 ++
 ...linux-poison.h-fix-list_poison-1-2-offset.patch |  44 ++++++++
 .../s390-mm-four-page-table-levels-vs.-fork.patch  | 114 +++++++++++++++++++++
 ...compat-add-missing-clac-to-entry_int80_32.patch |  45 ++++++++
 ...64-properly-context-switch-iopl-on-xen-pv.patch |  97 ++++++++++++++++++
 debian/patches/series                              |   4 +
 6 files changed, 313 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 6eea6aa..60f413d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+linux (3.16.7-ckt20-1+deb8u5) UNRELEASED; urgency=medium
+
+  * include/linux/poison.h: fix LIST_POISON{1,2} offset (CVE-2016-0821)
+  * [s390*] mm: four page table levels vs. fork (CVE-2016-2143)
+  * [amd64] iopl: Properly context-switch IOPL on Xen PV (CVE-2016-3157)
+  * [amd64] entry/compat: Add missing CLAC to entry_INT80_32 (CVE-2016-XXXX)
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Wed, 30 Mar 2016 16:32:07 +0100
+
 linux (3.16.7-ckt20-1+deb8u4) jessie-security; urgency=high
 
   * fuse: break infinite loop in fuse_fill_write_pages() (CVE-2015-8785)
diff --git a/debian/patches/bugfix/all/include-linux-poison.h-fix-list_poison-1-2-offset.patch b/debian/patches/bugfix/all/include-linux-poison.h-fix-list_poison-1-2-offset.patch
new file mode 100644
index 0000000..a6b6b0f
--- /dev/null
+++ b/debian/patches/bugfix/all/include-linux-poison.h-fix-list_poison-1-2-offset.patch
@@ -0,0 +1,44 @@
+From: Vasily Kulikov <segoon at openwall.com>
+Date: Wed, 9 Sep 2015 15:36:00 -0700
+Subject: include/linux/poison.h: fix LIST_POISON{1,2} offset
+Origin: https://git.kernel.org/linus/8a5e5e02fc83aaf67053ab53b359af08c6c49aaf
+
+Poison pointer values should be small enough to find a room in
+non-mmap'able/hardly-mmap'able space.  E.g.  on x86 "poison pointer space"
+is located starting from 0x0.  Given unprivileged users cannot mmap
+anything below mmap_min_addr, it should be safe to use poison pointers
+lower than mmap_min_addr.
+
+The current poison pointer values of LIST_POISON{1,2} might be too big for
+mmap_min_addr values equal or less than 1 MB (common case, e.g.  Ubuntu
+uses only 0x10000).  There is little point to use such a big value given
+the "poison pointer space" below 1 MB is not yet exhausted.  Changing it
+to a smaller value solves the problem for small mmap_min_addr setups.
+
+The values are suggested by Solar Designer:
+http://www.openwall.com/lists/oss-security/2015/05/02/6
+
+Signed-off-by: Vasily Kulikov <segoon at openwall.com>
+Cc: Solar Designer <solar at openwall.com>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Cc: "Kirill A. Shutemov" <kirill.shutemov at linux.intel.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ include/linux/poison.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/include/linux/poison.h
++++ b/include/linux/poison.h
+@@ -19,8 +19,8 @@
+  * under normal circumstances, used to verify that nobody uses
+  * non-initialized list entries.
+  */
+-#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
+-#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
++#define LIST_POISON1  ((void *) 0x100 + POISON_POINTER_DELTA)
++#define LIST_POISON2  ((void *) 0x200 + POISON_POINTER_DELTA)
+ 
+ /********** include/linux/timer.h **********/
+ /*
diff --git a/debian/patches/bugfix/s390/s390-mm-four-page-table-levels-vs.-fork.patch b/debian/patches/bugfix/s390/s390-mm-four-page-table-levels-vs.-fork.patch
new file mode 100644
index 0000000..6ea1f7b
--- /dev/null
+++ b/debian/patches/bugfix/s390/s390-mm-four-page-table-levels-vs.-fork.patch
@@ -0,0 +1,114 @@
+From: Martin Schwidefsky <schwidefsky at de.ibm.com>
+Date: Mon, 15 Feb 2016 14:46:49 +0100
+Subject: s390/mm: four page table levels vs. fork
+Origin: https://git.kernel.org/linus/3446c13b268af86391d06611327006b059b8bab1
+
+The fork of a process with four page table levels is broken since
+git commit 6252d702c5311ce9 "[S390] dynamic page tables."
+
+All new mm contexts are created with three page table levels and
+an asce limit of 4TB. If the parent has four levels dup_mmap will
+add vmas to the new context which are outside of the asce limit.
+The subsequent call to copy_page_range will walk the three level
+page table structure of the new process with non-zero pgd and pud
+indexes. This leads to memory clobbers as the pgd_index *and* the
+pud_index is added to the mm->pgd pointer without a pgd_deref
+in between.
+
+The init_new_context() function is selecting the number of page
+table levels for a new context. The function is used by mm_init()
+which in turn is called by dup_mm() and mm_alloc(). These two are
+used by fork() and exec(). The init_new_context() function can
+distinguish the two cases by looking at mm->context.asce_limit,
+for fork() the mm struct has been copied and the number of page
+table levels may not change. For exec() the mm_alloc() function
+set the new mm structure to zero, in this case a three-level page
+table is created as the temporary stack space is located at
+STACK_TOP_MAX = 4TB.
+
+This fixes CVE-2016-2143.
+
+Reported-by: Marcin Kościelnicki <koriakin at 0x04.net>
+Reviewed-by: Heiko Carstens <heiko.carstens at de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+[bwh: Backported to 3.16:
+ - 31-bit s390 is still supported so keep the #ifdef CONFIG_64BIT conditions
+ - PMDs are not accounted so don't call mm_inc_nr_pmds()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/arch/s390/include/asm/mmu_context.h
++++ b/arch/s390/include/asm/mmu_context.h
+@@ -15,16 +15,22 @@
+ static inline int init_new_context(struct task_struct *tsk,
+ 				   struct mm_struct *mm)
+ {
++	spin_lock_init(&mm->context.list_lock);
++	INIT_LIST_HEAD(&mm->context.pgtable_list);
++	INIT_LIST_HEAD(&mm->context.gmap_list);
+ 	cpumask_clear(&mm->context.cpu_attach_mask);
+ 	atomic_set(&mm->context.attach_count, 0);
+ 	mm->context.flush_mm = 0;
+-	mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+-#ifdef CONFIG_64BIT
+-	mm->context.asce_bits |= _ASCE_TYPE_REGION3;
+-#endif
+ 	mm->context.has_pgste = 0;
+ 	mm->context.use_skey = 0;
+-	mm->context.asce_limit = STACK_TOP_MAX;
++	if (mm->context.asce_limit == 0) {
++		/* context created by exec, set asce limit to 4TB */
++		mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
++#ifdef CONFIG_64BIT
++		mm->context.asce_bits |= _ASCE_TYPE_REGION3;
++#endif
++		mm->context.asce_limit = STACK_TOP_MAX;
++	}
+ 	crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
+ 	return 0;
+ }
+@@ -110,10 +116,6 @@ static inline void activate_mm(struct mm
+ static inline void arch_dup_mmap(struct mm_struct *oldmm,
+ 				 struct mm_struct *mm)
+ {
+-#ifdef CONFIG_64BIT
+-	if (oldmm->context.asce_limit < mm->context.asce_limit)
+-		crst_table_downgrade(mm, oldmm->context.asce_limit);
+-#endif
+ }
+ 
+ static inline void arch_exit_mmap(struct mm_struct *mm)
+--- a/arch/s390/include/asm/pgalloc.h
++++ b/arch/s390/include/asm/pgalloc.h
+@@ -124,12 +124,26 @@ static inline void pud_populate(struct m
+ 
+ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+-	spin_lock_init(&mm->context.list_lock);
+-	INIT_LIST_HEAD(&mm->context.pgtable_list);
+-	INIT_LIST_HEAD(&mm->context.gmap_list);
+-	return (pgd_t *) crst_table_alloc(mm);
++	unsigned long *table = crst_table_alloc(mm);
++
++	if (!table)
++		return NULL;
++	if (mm->context.asce_limit == (1UL << 31)) {
++		/* Forking a compat process with 2 page table levels */
++		if (!pgtable_pmd_page_ctor(virt_to_page(table))) {
++			crst_table_free(mm, table);
++			return NULL;
++		}
++	}
++	return (pgd_t *) table;
++}
++
++static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
++{
++	if (mm->context.asce_limit == (1UL << 31))
++		pgtable_pmd_page_dtor(virt_to_page(pgd));
++	crst_table_free(mm, (unsigned long *) pgd);
+ }
+-#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
+ 
+ static inline void pmd_populate(struct mm_struct *mm,
+ 				pmd_t *pmd, pgtable_t pte)
diff --git a/debian/patches/bugfix/x86/x86-entry-compat-add-missing-clac-to-entry_int80_32.patch b/debian/patches/bugfix/x86/x86-entry-compat-add-missing-clac-to-entry_int80_32.patch
new file mode 100644
index 0000000..6de1326
--- /dev/null
+++ b/debian/patches/bugfix/x86/x86-entry-compat-add-missing-clac-to-entry_int80_32.patch
@@ -0,0 +1,45 @@
+From: Andy Lutomirski <luto at kernel.org>
+Date: Wed, 24 Feb 2016 12:18:49 -0800
+Subject: x86/entry/compat: Add missing CLAC to entry_INT80_32
+Origin: https://git.kernel.org/linus/3d44d51bd339766f0178f0cf2e8d048b4a4872aa
+
+This doesn't seem to fix a regression -- I don't think the CLAC was
+ever there.
+
+I double-checked in a debugger: entries through the int80 gate do
+not automatically clear AC.
+
+Stable maintainers: I can provide a backport to 4.3 and earlier if
+needed.  This needs to be backported all the way to 3.10.
+
+Reported-by: Brian Gerst <brgerst at gmail.com>
+Signed-off-by: Andy Lutomirski <luto at kernel.org>
+Cc: Andy Lutomirski <luto at amacapital.net>
+Cc: Borislav Petkov <bp at alien8.de>
+Cc: Denys Vlasenko <dvlasenk at redhat.com>
+Cc: H. Peter Anvin <hpa at zytor.com>
+Cc: Linus Torvalds <torvalds at linux-foundation.org>
+Cc: Peter Zijlstra <peterz at infradead.org>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Fixes: 63bcff2a307b ("x86, smap: Add STAC and CLAC instructions to control user space access")
+Link: http://lkml.kernel.org/r/b02b7e71ae54074be01fc171cbd4b72517055c0e.1456345086.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo at kernel.org>
+[ kamal: backport to 3.10 through 3.19-stable: file rename; context ]
+Signed-off-by: Kamal Mostafa <kamal at canonical.com>
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+---
+ arch/x86/ia32/ia32entry.S | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 92a2e9333620..b74ac9c5710b 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -422,6 +422,7 @@ ENTRY(ia32_syscall)
+ 	/*CFI_REL_OFFSET	cs,CS-RIP*/
+ 	CFI_REL_OFFSET	rip,RIP-RIP
+ 	PARAVIRT_ADJUST_EXCEPTION_FRAME
++	ASM_CLAC			/* Do this early to minimize exposure */
+ 	SWAPGS
+ 	/*
+ 	 * No need to follow this irqs on/off section: the syscall
diff --git a/debian/patches/bugfix/x86/x86-iopl-64-properly-context-switch-iopl-on-xen-pv.patch b/debian/patches/bugfix/x86/x86-iopl-64-properly-context-switch-iopl-on-xen-pv.patch
new file mode 100644
index 0000000..b712912
--- /dev/null
+++ b/debian/patches/bugfix/x86/x86-iopl-64-properly-context-switch-iopl-on-xen-pv.patch
@@ -0,0 +1,97 @@
+From: Andy Lutomirski <luto at kernel.org>
+Date: Wed, 16 Mar 2016 14:14:21 -0700
+Subject: x86/iopl/64: Properly context-switch IOPL on Xen PV
+Origin: https://git.kernel.org/linus/b7a584598aea7ca73140cb87b40319944dd3393f
+
+On Xen PV, regs->flags doesn't reliably reflect IOPL and the
+exit-to-userspace code doesn't change IOPL.  We need to context
+switch it manually.
+
+I'm doing this without going through paravirt because this is
+specific to Xen PV.  After the dust settles, we can merge this with
+the 32-bit code, tidy up the iopl syscall implementation, and remove
+the set_iopl pvop entirely.
+
+Fixes XSA-171.
+
+Reviewewd-by: Jan Beulich <JBeulich at suse.com>
+Signed-off-by: Andy Lutomirski <luto at kernel.org>
+Cc: Andrew Cooper <andrew.cooper3 at citrix.com>
+Cc: Andy Lutomirski <luto at amacapital.net>
+Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
+Cc: Borislav Petkov <bp at alien8.de>
+Cc: Brian Gerst <brgerst at gmail.com>
+Cc: David Vrabel <david.vrabel at citrix.com>
+Cc: Denys Vlasenko <dvlasenk at redhat.com>
+Cc: H. Peter Anvin <hpa at zytor.com>
+Cc: Jan Beulich <JBeulich at suse.com>
+Cc: Linus Torvalds <torvalds at linux-foundation.org>
+Cc: Peter Zijlstra <peterz at infradead.org>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Cc: stable at vger.kernel.org
+Link: http://lkml.kernel.org/r/693c3bd7aeb4d3c27c92c622b7d0f554a458173c.1458162709.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo at kernel.org>
+[bwh: Backported to 3.16:
+ - Use xen_pv_domain() directly as X86_FEATURE_XENPV is not defined
+ - Adjust context]
+---
+ arch/x86/include/asm/xen/hypervisor.h |  2 ++
+ arch/x86/kernel/process_64.c          | 12 ++++++++++++
+ arch/x86/xen/enlighten.c              |  2 +-
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/xen/hypervisor.h
++++ b/arch/x86/include/asm/xen/hypervisor.h
+@@ -57,4 +57,6 @@ static inline bool xen_x2apic_para_avail
+ }
+ #endif
+ 
++extern void xen_set_iopl_mask(unsigned mask);
++
+ #endif /* _ASM_X86_XEN_HYPERVISOR_H */
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -35,6 +35,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/io.h>
+ #include <linux/ftrace.h>
++#include <xen/xen.h>
+ 
+ #include <asm/pgtable.h>
+ #include <asm/processor.h>
+@@ -49,6 +50,7 @@
+ #include <asm/syscalls.h>
+ #include <asm/debugreg.h>
+ #include <asm/switch_to.h>
++#include <asm/xen/hypervisor.h>
+ 
+ asmlinkage extern void ret_from_fork(void);
+ 
+@@ -427,6 +429,16 @@ __switch_to(struct task_struct *prev_p,
+ 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
+ 		__switch_to_xtra(prev_p, next_p, tss);
+ 
++#ifdef CONFIG_XEN
++	/*
++	 * On Xen PV, IOPL bits in pt_regs->flags have no effect, and
++	 * current_pt_regs()->flags may not match the current task's
++	 * intended IOPL.  We need to switch it manually.
++	 */
++	if (unlikely(xen_pv_domain() && prev->iopl != next->iopl))
++		xen_set_iopl_mask(next->iopl);
++#endif
++
+ 	return prev_p;
+ }
+ 
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -956,7 +956,7 @@ static void xen_load_sp0(struct tss_stru
+ 	xen_mc_issue(PARAVIRT_LAZY_CPU);
+ }
+ 
+-static void xen_set_iopl_mask(unsigned mask)
++void xen_set_iopl_mask(unsigned mask)
+ {
+ 	struct physdev_set_iopl set_iopl;
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 3e8728d..10ac448 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -695,3 +695,7 @@ bugfix/all/alsa-timer-fix-race-among-timer-ioctls.patch
 bugfix/all/alsa-timer-harden-slave-timer-list-handling.patch
 bugfix/all/alsa-hrtimer-fix-stall-by-hrtimer_cancel.patch
 bugfix/all/aio-properly-check-iovec-sizes.patch
+bugfix/all/include-linux-poison.h-fix-list_poison-1-2-offset.patch
+bugfix/s390/s390-mm-four-page-table-levels-vs.-fork.patch
+bugfix/x86/x86-iopl-64-properly-context-switch-iopl-on-xen-pv.patch
+bugfix/x86/x86-entry-compat-add-missing-clac-to-entry_int80_32.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list