android_kernel_oneplus_msm8998/arch
Pavel Tatashin f811dcf49a arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault
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 <catalin.marinas@arm.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Cc: <stable@vger.kernel.org>
Fixes: 338d4f49d6 ("arm64: kernel: Add support for Privileged Access Never")
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
[will: rewrote commit message]
[will: backport for 4.4.y stable kernels]
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-11-25 15:54:52 +01:00
..
alpha alpha: Fix Eiger NR_IRQS to 128 2019-02-20 10:13:22 +01:00
arc ARC: export "abort" for modules 2019-09-21 07:12:54 +02:00
arm ARM: 8802/1: Call syscall_trace_exit even when system call skipped 2019-11-25 15:54:51 +01:00
arm64 arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault 2019-11-25 15:54:52 +01:00
avr32
blackfin pinctrl: adi2: Fix Kconfig build problem 2017-12-20 10:05:00 +01:00
c6x
cris mm: replace get_user_pages() write/force parameters with gup_flags 2018-12-17 21:55:16 +01:00
frv futex: Remove duplicated code and fix undefined behaviour 2018-05-26 08:48:50 +02:00
h8300 h8300: use cc-cross-prefix instead of hardcoding h8300-unknown-linux- 2019-04-27 09:33:48 +02:00
hexagon hexagon: modify ffs() and fls() to return int 2018-10-10 08:52:12 +02:00
ia64 ia64:unwind: fix double free for mod->arch.init_unw_table 2019-10-05 12:27:47 +02:00
m32r
m68k bug.h: work around GCC PR82365 in BUG() 2019-07-10 09:56:42 +02:00
metag metag/uaccess: Check access_ok in strncpy_from_user 2017-05-25 14:30:16 +02:00
microblaze microblaze: Fix simpleImage format generation 2018-08-06 16:24:39 +02:00
mips MIPS: kexec: Relax memory restriction 2019-11-25 15:54:08 +01:00
mn10300 mn10300/misalignment: Use SIGSEGV SEGV_MAPERR to report a failed user copy 2018-02-16 20:09:47 +01:00
nios2 nios2: reserve boot memory for device tree 2017-04-12 12:38:34 +02:00
openrisc kthread: fix boot hang (regression) on MIPS/OpenRISC 2018-09-19 22:48:55 +02:00
parisc parisc: Fix vmap memory leak in ioremap()/iounmap() 2019-10-29 09:13:29 +01:00
powerpc KVM: PPC: Book3S PR: Exiting split hack mode needs to fixup both PC and LR 2019-11-25 15:54:39 +01:00
s390 s390/cmm: fix information leak in cmm_timeout_handler() 2019-11-06 12:09:21 +01:00
score
sh sh: kernel: hw_breakpoint: Fix missing break in switch statement 2019-08-25 10:52:55 +02:00
sparc bug.h: work around GCC PR82365 in BUG() 2019-07-10 09:56:42 +02:00
tile futex: Remove duplicated code and fix undefined behaviour 2018-05-26 08:48:50 +02:00
um um: Silence lockdep complaint about mmap_sem 2019-08-04 09:34:58 +02:00
unicore32
x86 x86/kexec: Correct KEXEC_BACKUP_SRC_END off-by-one error 2019-11-25 15:54:49 +01:00
xtensa xtensa: drop EXPORT_SYMBOL for outs*/ins* 2019-10-29 09:13:29 +01:00
.gitignore
Kconfig