From: Greg Kroah-Hartman Date: Mon, 24 Jun 2019 15:40:51 +0000 (+0800) Subject: 5.1-stable patches X-Git-Tag: v5.1.15~8 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fkernel%2Fstable-queue.git;a=commitdiff_plain;h=b62a342d166f7922da6a6c8c40eb1dfc89dddef5 5.1-stable patches added patches: powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch --- diff --git a/queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch b/queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch deleted file mode 100644 index 7bab32590e..0000000000 --- a/queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 7f214592e69ae8ea788b0a1413191e9de05190d3 Mon Sep 17 00:00:00 2001 -From: Vincent Chen -Date: Mon, 20 May 2019 09:21:12 +0800 -Subject: nds32: Avoid IEX status being incorrectly modified - -[ Upstream commit ed32949e0acb73e7bc054bb02e0453d4d561ceda ] - -In order for kernel to capture each denormalized output, the UDF -trapping enable bit is always raised in $fpcsr. Because underflow case will -issue not an underflow exception but also an inexact exception, it causes -that the IEX, IEX cumulative exception, flag in $fpcsr to be raised in each -denormalized output handling. To make the emulation transparent to the -user, the emulator needs to clear the IEX flag in $fpcsr if the result is a -denormalized number. However, if the IEX flag has been raised before this -floating point emulation, this cleanup may be incorrect. To avoid the IEX -flags in $fpcsr be raised in each denormalized output handling, the IEX -trap shall be always enabled. - -Signed-off-by: Vincent Chen -Acked-by: Greentime Hu -Signed-off-by: Greentime Hu -Signed-off-by: Sasha Levin ---- - arch/nds32/include/asm/bitfield.h | 2 +- - arch/nds32/include/asm/fpu.h | 2 +- - arch/nds32/include/asm/syscalls.h | 2 +- - arch/nds32/include/uapi/asm/fp_udfiex_crtl.h | 16 ++++++++++++ - arch/nds32/include/uapi/asm/sigcontext.h | 24 ++++++++++++------ - arch/nds32/include/uapi/asm/udftrap.h | 13 ---------- - arch/nds32/include/uapi/asm/unistd.h | 4 +-- - arch/nds32/kernel/fpu.c | 15 +++++------ - arch/nds32/kernel/sys_nds32.c | 26 +++++++++++--------- - 9 files changed, 58 insertions(+), 46 deletions(-) - create mode 100644 arch/nds32/include/uapi/asm/fp_udfiex_crtl.h - delete mode 100644 arch/nds32/include/uapi/asm/udftrap.h - -diff --git a/arch/nds32/include/asm/bitfield.h b/arch/nds32/include/asm/bitfield.h -index 7414fcbbab4e..03bbb6d27828 100644 ---- a/arch/nds32/include/asm/bitfield.h -+++ b/arch/nds32/include/asm/bitfield.h -@@ -937,7 +937,7 @@ - #define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT ) - #define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT ) - #define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX) --#define FPCSR_mskALLE_NO_UDFE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskIEXE) -+#define FPCSR_mskALLE_NO_UDF_IEXE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE) - #define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE) - #define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT) - -diff --git a/arch/nds32/include/asm/fpu.h b/arch/nds32/include/asm/fpu.h -index 019f1bcfc5ee..8294ed4aaa2c 100644 ---- a/arch/nds32/include/asm/fpu.h -+++ b/arch/nds32/include/asm/fpu.h -@@ -36,7 +36,7 @@ extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu); - * enabled by default and kerenl will re-execute it by fpu emulator - * when getting underflow exception. - */ --#define FPCSR_INIT FPCSR_mskUDFE -+#define FPCSR_INIT (FPCSR_mskUDFE | FPCSR_mskIEXE) - #else - #define FPCSR_INIT 0x0UL - #endif -diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h -index da32101b455d..b9c9becce5d6 100644 ---- a/arch/nds32/include/asm/syscalls.h -+++ b/arch/nds32/include/asm/syscalls.h -@@ -7,7 +7,7 @@ - asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op); - asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len); - asmlinkage long sys_rt_sigreturn_wrapper(void); --asmlinkage long sys_udftrap(int option); -+asmlinkage long sys_fp_udfiex_crtl(int cmd, int act); - - #include - -diff --git a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h -new file mode 100644 -index 000000000000..d54a5d6c6538 ---- /dev/null -+++ b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright (C) 2005-2019 Andes Technology Corporation */ -+#ifndef _FP_UDF_IEX_CRTL_H -+#define _FP_UDF_IEX_CRTL_H -+ -+/* -+ * The cmd list of sys_fp_udfiex_crtl() -+ */ -+/* Disable UDF or IEX trap based on the content of parameter act */ -+#define DISABLE_UDF_IEX_TRAP 0 -+/* Enable UDF or IEX trap based on the content of parameter act */ -+#define ENABLE_UDF_IEX_TRAP 1 -+/* Get current status of UDF and IEX trap */ -+#define GET_UDF_IEX_TRAP 2 -+ -+#endif /* _FP_UDF_IEX_CRTL_H */ -diff --git a/arch/nds32/include/uapi/asm/sigcontext.h b/arch/nds32/include/uapi/asm/sigcontext.h -index 58afc416473e..b53634033e32 100644 ---- a/arch/nds32/include/uapi/asm/sigcontext.h -+++ b/arch/nds32/include/uapi/asm/sigcontext.h -@@ -13,14 +13,24 @@ struct fpu_struct { - unsigned long long fd_regs[32]; - unsigned long fpcsr; - /* -- * UDF_trap is used to recognize whether underflow trap is enabled -- * or not. When UDF_trap == 1, this process will be traped and then -- * get a SIGFPE signal when encountering an underflow exception. -- * UDF_trap is only modified through setfputrap syscall. Therefore, -- * UDF_trap needn't be saved or loaded to context in each context -- * switch. -+ * When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents -+ * hardware from treating the denormalized output as an underflow case -+ * and rounding it to a normal number. Hence kernel enables the UDF and -+ * IEX trap in the fpcsr register to step in the calculation. -+ * However, the UDF and IEX trap enable bit in $fpcsr also lose -+ * their use. -+ * -+ * UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in -+ * $fpcsr to control the trap of underflow and inexact. The bit filed -+ * of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF -+ * exception trapping and 11th bit is used to enable IEX exception -+ * trapping. -+ * -+ * UDF_IEX_trap is only modified through fp_udfiex_crtl syscall. -+ * Therefore, UDF_IEX_trap needn't be saved and restored in each -+ * context switch. - */ -- unsigned long UDF_trap; -+ unsigned long UDF_IEX_trap; - }; - - struct zol_struct { -diff --git a/arch/nds32/include/uapi/asm/udftrap.h b/arch/nds32/include/uapi/asm/udftrap.h -deleted file mode 100644 -index 433f79d679c0..000000000000 ---- a/arch/nds32/include/uapi/asm/udftrap.h -+++ /dev/null -@@ -1,13 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* Copyright (C) 2005-2018 Andes Technology Corporation */ --#ifndef _ASM_SETFPUTRAP --#define _ASM_SETFPUTRAP -- --/* -- * Options for setfputrap system call -- */ --#define DISABLE_UDFTRAP 0 /* disable underflow exception trap */ --#define ENABLE_UDFTRAP 1 /* enable undeflos exception trap */ --#define GET_UDFTRAP 2 /* only get undeflos exception trap status */ -- --#endif /* _ASM_CACHECTL */ -diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h -index 4ec8f543103f..6b9ff90e3ae5 100644 ---- a/arch/nds32/include/uapi/asm/unistd.h -+++ b/arch/nds32/include/uapi/asm/unistd.h -@@ -11,6 +11,6 @@ - - /* Additional NDS32 specific syscalls. */ - #define __NR_cacheflush (__NR_arch_specific_syscall) --#define __NR_udftrap (__NR_arch_specific_syscall + 1) -+#define __NR_fp_udfiex_crtl (__NR_arch_specific_syscall + 1) - __SYSCALL(__NR_cacheflush, sys_cacheflush) --__SYSCALL(__NR_udftrap, sys_udftrap) -+__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl) -diff --git a/arch/nds32/kernel/fpu.c b/arch/nds32/kernel/fpu.c -index fddd40c7a16f..cf0b8760f261 100644 ---- a/arch/nds32/kernel/fpu.c -+++ b/arch/nds32/kernel/fpu.c -@@ -14,7 +14,7 @@ const struct fpu_struct init_fpuregs = { - .fd_regs = {[0 ... 31] = sNAN64}, - .fpcsr = FPCSR_INIT, - #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -- .UDF_trap = 0 -+ .UDF_IEX_trap = 0 - #endif - }; - -@@ -178,7 +178,7 @@ inline void do_fpu_context_switch(struct pt_regs *regs) - /* First time FPU user. */ - load_fpu(&init_fpuregs); - #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -- current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap; -+ current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap; - #endif - set_used_math(); - } -@@ -206,7 +206,7 @@ inline void handle_fpu_exception(struct pt_regs *regs) - unsigned int fpcsr; - int si_code = 0, si_signo = SIGFPE; - #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -- unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT; -+ unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT; - #else - unsigned long redo_except = FPCSR_mskDNIT; - #endif -@@ -215,21 +215,18 @@ inline void handle_fpu_exception(struct pt_regs *regs) - fpcsr = current->thread.fpu.fpcsr; - - if (fpcsr & redo_except) { --#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -- if (fpcsr & FPCSR_mskUDFT) -- current->thread.fpu.fpcsr &= ~FPCSR_mskIEX; --#endif - si_signo = do_fpuemu(regs, ¤t->thread.fpu); - fpcsr = current->thread.fpu.fpcsr; -- if (!si_signo) -+ if (!si_signo) { -+ current->thread.fpu.fpcsr &= ~(redo_except); - goto done; -+ } - } else if (fpcsr & FPCSR_mskRIT) { - if (!user_mode(regs)) - do_exit(SIGILL); - si_signo = SIGILL; - } - -- - switch (si_signo) { - case SIGFPE: - fill_sigfpe_signo(fpcsr, &si_code); -diff --git a/arch/nds32/kernel/sys_nds32.c b/arch/nds32/kernel/sys_nds32.c -index 0835277636ce..cb2d1e219bb3 100644 ---- a/arch/nds32/kernel/sys_nds32.c -+++ b/arch/nds32/kernel/sys_nds32.c -@@ -6,8 +6,8 @@ - - #include - #include --#include - #include -+#include - - SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, -@@ -51,31 +51,33 @@ SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache) - return 0; - } - --SYSCALL_DEFINE1(udftrap, int, option) -+SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act) - { - #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -- int old_udftrap; -+ int old_udf_iex; - - if (!used_math()) { - load_fpu(&init_fpuregs); -- current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap; -+ current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap; - set_used_math(); - } - -- old_udftrap = current->thread.fpu.UDF_trap; -- switch (option) { -- case DISABLE_UDFTRAP: -- current->thread.fpu.UDF_trap = 0; -+ old_udf_iex = current->thread.fpu.UDF_IEX_trap; -+ act &= (FPCSR_mskUDFE | FPCSR_mskIEXE); -+ -+ switch (cmd) { -+ case DISABLE_UDF_IEX_TRAP: -+ current->thread.fpu.UDF_IEX_trap &= ~act; - break; -- case ENABLE_UDFTRAP: -- current->thread.fpu.UDF_trap = FPCSR_mskUDFE; -+ case ENABLE_UDF_IEX_TRAP: -+ current->thread.fpu.UDF_IEX_trap |= act; - break; -- case GET_UDFTRAP: -+ case GET_UDF_IEX_TRAP: - break; - default: - return -EINVAL; - } -- return old_udftrap; -+ return old_udf_iex; - #else - return -ENOTSUPP; - #endif --- -2.20.1 - diff --git a/queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch b/queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch new file mode 100644 index 0000000000..095578b21b --- /dev/null +++ b/queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch @@ -0,0 +1,140 @@ +From ca72d88378b2f2444d3ec145dd442d449d3fefbc Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 12 Jun 2019 23:35:07 +1000 +Subject: powerpc/mm/64s/hash: Reallocate context ids on fork + +From: Michael Ellerman + +commit ca72d88378b2f2444d3ec145dd442d449d3fefbc upstream. + +When using the Hash Page Table (HPT) MMU, userspace memory mappings +are managed at two levels. Firstly in the Linux page tables, much like +other architectures, and secondly in the SLB (Segment Lookaside +Buffer) and HPT. It's the SLB and HPT that are actually used by the +hardware to do translations. + +As part of the series adding support for 4PB user virtual address +space using the hash MMU, we added support for allocating multiple +"context ids" per process, one for each 512TB chunk of address space. +These are tracked in an array called extended_id in the mm_context_t +of a process that has done a mapping above 512TB. + +If such a process forks (ie. clone(2) without CLONE_VM set) it's mm is +copied, including the mm_context_t, and then init_new_context() is +called to reinitialise parts of the mm_context_t as appropriate to +separate the address spaces of the two processes. + +The key step in ensuring the two processes have separate address +spaces is to allocate a new context id for the process, this is done +at the beginning of hash__init_new_context(). If we didn't allocate a +new context id then the two processes would share mappings as far as +the SLB and HPT are concerned, even though their Linux page tables +would be separate. + +For mappings above 512TB, which use the extended_id array, we +neglected to allocate new context ids on fork, meaning the parent and +child use the same ids and therefore share those mappings even though +they're supposed to be separate. This can lead to the parent seeing +writes done by the child, which is essentially memory corruption. + +There is an additional exposure which is that if the child process +exits, all its context ids are freed, including the context ids that +are still in use by the parent for mappings above 512TB. One or more +of those ids can then be reallocated to a third process, that process +can then read/write to the parent's mappings above 512TB. Additionally +if the freed id is used for the third process's primary context id, +then the parent is able to read/write to the third process's mappings +*below* 512TB. + +All of these are fundamental failures to enforce separation between +processes. The only mitigating factor is that the bug only occurs if a +process creates mappings above 512TB, and most applications still do +not create such mappings. + +Only machines using the hash page table MMU are affected, eg. PowerPC +970 (G5), PA6T, Power5/6/7/8/9. By default Power9 bare metal machines +(powernv) use the Radix MMU and are not affected, unless the machine +has been explicitly booted in HPT mode (using disable_radix on the +kernel command line). KVM guests on Power9 may be affected if the host +or guest is configured to use the HPT MMU. LPARs under PowerVM on +Power9 are affected as they always use the HPT MMU. Kernels built with +PAGE_SIZE=4K are not affected. + +The fix is relatively simple, we need to reallocate context ids for +all extended mappings on fork. + +Fixes: f384796c40dc ("powerpc/mm: Add support for handling > 512TB address in SLB miss") +Cc: stable@vger.kernel.org # v4.17+ +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/mm/mmu_context_book3s64.c | 46 ++++++++++++++++++++++++++++++--- + 1 file changed, 42 insertions(+), 4 deletions(-) + +--- a/arch/powerpc/mm/mmu_context_book3s64.c ++++ b/arch/powerpc/mm/mmu_context_book3s64.c +@@ -55,14 +55,48 @@ EXPORT_SYMBOL_GPL(hash__alloc_context_id + + void slb_setup_new_exec(void); + ++static int realloc_context_ids(mm_context_t *ctx) ++{ ++ int i, id; ++ ++ /* ++ * id 0 (aka. ctx->id) is special, we always allocate a new one, even if ++ * there wasn't one allocated previously (which happens in the exec ++ * case where ctx is newly allocated). ++ * ++ * We have to be a bit careful here. We must keep the existing ids in ++ * the array, so that we can test if they're non-zero to decide if we ++ * need to allocate a new one. However in case of error we must free the ++ * ids we've allocated but *not* any of the existing ones (or risk a ++ * UAF). That's why we decrement i at the start of the error handling ++ * loop, to skip the id that we just tested but couldn't reallocate. ++ */ ++ for (i = 0; i < ARRAY_SIZE(ctx->extended_id); i++) { ++ if (i == 0 || ctx->extended_id[i]) { ++ id = hash__alloc_context_id(); ++ if (id < 0) ++ goto error; ++ ++ ctx->extended_id[i] = id; ++ } ++ } ++ ++ /* The caller expects us to return id */ ++ return ctx->id; ++ ++error: ++ for (i--; i >= 0; i--) { ++ if (ctx->extended_id[i]) ++ ida_free(&mmu_context_ida, ctx->extended_id[i]); ++ } ++ ++ return id; ++} ++ + static int hash__init_new_context(struct mm_struct *mm) + { + int index; + +- index = hash__alloc_context_id(); +- if (index < 0) +- return index; +- + /* + * The old code would re-promote on fork, we don't do that when using + * slices as it could cause problem promoting slices that have been +@@ -80,6 +114,10 @@ static int hash__init_new_context(struct + if (mm->context.id == 0) + slice_init_new_context_exec(mm); + ++ index = realloc_context_ids(&mm->context); ++ if (index < 0) ++ return index; ++ + subpage_prot_init_new_context(mm); + + pkey_mm_init(mm); diff --git a/queue-5.1/series b/queue-5.1/series index 626dccf738..d8c2a8ebc9 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -59,7 +59,6 @@ kselftest-cgroup-fix-unexpected-testing-failure-on-t.patch-32330 kselftest-cgroup-fix-incorrect-test_core-skip.patch userfaultfd-selftest-fix-compiler-warning.patch selftests-vm-install-test_vmalloc.sh-for-run_vmtests.patch -nds32-avoid-iex-status-being-incorrectly-modified.patch net-dsa-mv88e6xxx-avoid-error-message-on-remove-from.patch net-hns-fix-loopback-test-failed-at-copper-ports.patch mdesc-fix-a-missing-check-bug-in-get_vdev_port_node_.patch @@ -119,3 +118,4 @@ mac80211-handle-deauthentication-disassociation-from-tdls-peer.patch nl80211-fix-station_info-pertid-memory-leak.patch mac80211-do-not-use-stack-memory-with-scatterlist-for-gmac.patch x86-resctrl-don-t-stop-walking-closids-when-a-locksetup-group-is-found.patch +powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch