From: Greg Kroah-Hartman Date: Fri, 22 Nov 2019 09:57:44 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v5.3.13~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af3309580f57e8c3e980566a9b359a533936bb8b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm64-uaccess-ensure-pan-is-re-enabled-after-unhandled-uaccess-fault.patch --- diff --git a/queue-4.4/arm64-uaccess-ensure-pan-is-re-enabled-after-unhandled-uaccess-fault.patch b/queue-4.4/arm64-uaccess-ensure-pan-is-re-enabled-after-unhandled-uaccess-fault.patch new file mode 100644 index 00000000000..20dd81c678a --- /dev/null +++ b/queue-4.4/arm64-uaccess-ensure-pan-is-re-enabled-after-unhandled-uaccess-fault.patch @@ -0,0 +1,120 @@ +From 94bb804e1e6f0a9a77acf20d7c70ea141c6c821e Mon Sep 17 00:00:00 2001 +From: Pavel Tatashin +Date: Tue, 19 Nov 2019 17:10:06 -0500 +Subject: arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault + +From: Pavel Tatashin + +commit 94bb804e1e6f0a9a77acf20d7c70ea141c6c821e upstream. + +A number of our uaccess routines ('__arch_clear_user()' and +'__arch_copy_{in,from,to}_user()') fail to re-enable PAN if they +encounter an unhandled fault whilst accessing userspace. + +For CPUs implementing both hardware PAN and UAO, this bug has no effect +when both extensions are in use by the kernel. + +For CPUs implementing hardware PAN but not UAO, this means that a kernel +using hardware PAN may execute portions of code with PAN inadvertently +disabled, opening us up to potential security vulnerabilities that rely +on userspace access from within the kernel which would usually be +prevented by this mechanism. In other words, parts of the kernel run the +same way as they would on a CPU without PAN implemented/emulated at all. + +For CPUs not implementing hardware PAN and instead relying on software +emulation via 'CONFIG_ARM64_SW_TTBR0_PAN=y', the impact is unfortunately +much worse. Calling 'schedule()' with software PAN disabled means that +the next task will execute in the kernel using the page-table and ASID +of the previous process even after 'switch_mm()', since the actual +hardware switch is deferred until return to userspace. At this point, or +if there is a intermediate call to 'uaccess_enable()', the page-table +and ASID of the new process are installed. Sadly, due to the changes +introduced by KPTI, this is not an atomic operation and there is a very +small window (two instructions) where the CPU is configured with the +page-table of the old task and the ASID of the new task; a speculative +access in this state is disastrous because it would corrupt the TLB +entries for the new task with mappings from the previous address space. + +As Pavel explains: + + | I was able to reproduce memory corruption problem on Broadcom's SoC + | ARMv8-A like this: + | + | Enable software perf-events with PERF_SAMPLE_CALLCHAIN so userland's + | stack is accessed and copied. + | + | The test program performed the following on every CPU and forking + | many processes: + | + | unsigned long *map = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, + | MAP_SHARED | MAP_ANONYMOUS, -1, 0); + | map[0] = getpid(); + | sched_yield(); + | if (map[0] != getpid()) { + | fprintf(stderr, "Corruption detected!"); + | } + | munmap(map, PAGE_SIZE); + | + | From time to time I was getting map[0] to contain pid for a + | different process. + +Ensure that PAN is re-enabled when returning after an unhandled user +fault from our uaccess routines. + +Cc: Catalin Marinas +Reviewed-by: Mark Rutland +Tested-by: Mark Rutland +Cc: +Fixes: 338d4f49d6f7 ("arm64: kernel: Add support for Privileged Access Never") +Signed-off-by: Pavel Tatashin +[will: rewrote commit message] +[will: backport for 4.4.y stable kernels] +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/lib/clear_user.S | 2 ++ + arch/arm64/lib/copy_from_user.S | 2 ++ + arch/arm64/lib/copy_in_user.S | 2 ++ + arch/arm64/lib/copy_to_user.S | 2 ++ + 4 files changed, 8 insertions(+) + +--- a/arch/arm64/lib/clear_user.S ++++ b/arch/arm64/lib/clear_user.S +@@ -62,5 +62,7 @@ ENDPROC(__clear_user) + .section .fixup,"ax" + .align 2 + 9: mov x0, x2 // return the original size ++ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ ++ CONFIG_ARM64_PAN) + ret + .previous +--- a/arch/arm64/lib/copy_from_user.S ++++ b/arch/arm64/lib/copy_from_user.S +@@ -85,5 +85,7 @@ ENDPROC(__copy_from_user) + strb wzr, [dst], #1 // zero remaining buffer space + cmp dst, end + b.lo 9999b ++ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ ++ CONFIG_ARM64_PAN) + ret + .previous +--- a/arch/arm64/lib/copy_in_user.S ++++ b/arch/arm64/lib/copy_in_user.S +@@ -81,5 +81,7 @@ ENDPROC(__copy_in_user) + .section .fixup,"ax" + .align 2 + 9998: sub x0, end, dst // bytes not copied ++ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ ++ CONFIG_ARM64_PAN) + ret + .previous +--- a/arch/arm64/lib/copy_to_user.S ++++ b/arch/arm64/lib/copy_to_user.S +@@ -79,5 +79,7 @@ ENDPROC(__copy_to_user) + .section .fixup,"ax" + .align 2 + 9998: sub x0, end, dst // bytes not copied ++ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ ++ CONFIG_ARM64_PAN) + ret + .previous diff --git a/queue-4.4/series b/queue-4.4/series index 397beda9e6f..865e3756db3 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -156,3 +156,4 @@ hwmon-pwm-fan-silence-error-on-probe-deferral.patch mac80211-minstrel-fix-cck-rate-group-streams-value.patch spi-rockchip-initialize-dma_slave_config-properly.patch arm-dts-omap5-fix-dual-role-mode-on-super-speed-port.patch +arm64-uaccess-ensure-pan-is-re-enabled-after-unhandled-uaccess-fault.patch