android_kernel_oneplus_msm8998/arch
Dave Martin 750f60edeb arm64: fpsimd: Prevent registers leaking from dead tasks
commit 071b6d4a5d343046f253a5a8835d477d93992002 upstream.

Currently, loading of a task's fpsimd state into the CPU registers
is skipped if that task's state is already present in the registers
of that CPU.

However, the code relies on the struct fpsimd_state * (and by
extension struct task_struct *) to unambiguously identify a task.

There is a particular case in which this doesn't work reliably:
when a task exits, its task_struct may be recycled to describe a
new task.

Consider the following scenario:

 1) Task P loads its fpsimd state onto cpu C.
        per_cpu(fpsimd_last_state, C) := P;
        P->thread.fpsimd_state.cpu := C;

 2) Task X is scheduled onto C and loads its fpsimd state on C.
        per_cpu(fpsimd_last_state, C) := X;
        X->thread.fpsimd_state.cpu := C;

 3) X exits, causing X's task_struct to be freed.

 4) P forks a new child T, which obtains X's recycled task_struct.
	T == X.
	T->thread.fpsimd_state.cpu == C (inherited from P).

 5) T is scheduled on C.
	T's fpsimd state is not loaded, because
	per_cpu(fpsimd_last_state, C) == T (== X) &&
	T->thread.fpsimd_state.cpu == C.

        (This is the check performed by fpsimd_thread_switch().)

So, T gets X's registers because the last registers loaded onto C
were those of X, in (2).

This patch fixes the problem by ensuring that the sched-in check
fails in (5): fpsimd_flush_task_state(T) is called when T is
forked, so that T->thread.fpsimd_state.cpu == C cannot be true.
This relies on the fact that T is not schedulable until after
copy_thread() completes.

Once T's fpsimd state has been loaded on some CPU C there may still
be other cpus D for which per_cpu(fpsimd_last_state, D) ==
&X->thread.fpsimd_state.  But D is necessarily != C in this case,
and the check in (5) must fail.

An alternative fix would be to do refcounting on task_struct.  This
would result in each CPU holding a reference to the last task whose
fpsimd state was loaded there.  It's not clear whether this is
preferable, and it involves higher overhead than the fix proposed
in this patch.  It would also move all the task_struct freeing
work into the context switch critical section, or otherwise some
deferred cleanup mechanism would need to be introduced, neither of
which seems obviously justified.

Fixes: 005f78cd88 ("arm64: defer reloading a task's FPSIMD state to userland resume")
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
[will: word-smithed the comment so it makes more sense]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-12-16 10:33:50 +01:00
..
alpha alpha: uapi: Add support for __SANE_USERSPACE_TYPES__ 2017-09-07 08:34:09 +02:00
arc ARC: Re-enable MMU upon Machine Check exception 2017-09-27 11:00:16 +02:00
arm ARM: OMAP1: DMA: Correct the number of logical channels 2017-12-09 18:42:41 +01:00
arm64 arm64: fpsimd: Prevent registers leaking from dead tasks 2017-12-16 10:33:50 +01:00
avr32 avr32: off by one in at32_init_pio() 2016-10-07 15:23:45 +02:00
blackfin net: smc91x: fix SMC accesses 2016-09-30 10:18:37 +02:00
c6x c6x/ptrace: Remove useless PTRACE_SETREGSET implementation 2017-03-31 09:49:53 +02:00
cris cris: Only build flash rescue image if CONFIG_ETRAX_AXISFLASHMAP is selected 2017-01-12 11:22:48 +01:00
frv mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
h8300 h8300/ptrace: Fix incorrect register transfer count 2017-03-31 09:49:53 +02:00
hexagon hexagon: fix strncpy_from_user() error return 2016-09-24 10:07:44 +02:00
ia64 ia64: copy_from_user() should zero the destination on access_ok() failure 2016-09-24 10:07:46 +02:00
m32r m32r: fix __get_user() 2016-09-24 10:07:43 +02:00
m68k m68k: Fix ndelay() macro 2016-12-15 08:49:23 -08:00
metag metag/uaccess: Check access_ok in strncpy_from_user 2017-05-25 14:30:16 +02:00
microblaze microblaze: fix copy_from_user() 2016-09-24 10:07:43 +02:00
mips MIPS: BCM47XX: Fix LED inversion for WRT54GSv1 2017-11-30 08:37:20 +00:00
mn10300 mn10300: copy_from_user() should zero on access_ok() failure... 2016-09-24 10:07:45 +02:00
nios2 nios2: reserve boot memory for device tree 2017-04-12 12:38:34 +02:00
openrisc openrisc: Add _text symbol to fix ksym build error 2017-08-06 19:19:45 -07:00
parisc parisc: Fix validity check of pointer size argument in new CAS implementation 2017-11-30 08:37:24 +00:00
powerpc powerpc/signal: Properly handle return value from uprobe_deny_signal() 2017-11-30 08:37:24 +00:00
s390 s390: fix compat system call table 2017-12-16 10:33:49 +01:00
score score: fix copy_from_user() and friends 2016-09-24 10:07:44 +02:00
sh serial: sh-sci: Fix register offsets for the IRDA serial port 2017-11-15 17:13:10 +01:00
sparc security/keys: add CONFIG_KEYS_COMPAT to Kconfig 2017-11-18 11:11:07 +01:00
tile mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
um um: Don't discard .text.exit section 2016-09-07 08:32:38 +02:00
unicore32 pwm: Changes for v4.4-rc1 2015-11-11 09:16:10 -08:00
x86 KVM: VMX: remove I/O port 0x80 bypass on Intel hosts 2017-12-16 10:33:50 +01:00
xtensa mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
.gitignore
Kconfig