android_kernel_samsung_sm8650/arch
Dave Martin 071b6d4a5d arm64: fpsimd: Prevent registers leaking from dead tasks
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.

Cc: <stable@vger.kernel.org>
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>
2017-12-06 18:02:21 +00:00
..
alpha treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
arc ARC updates for 4.15-rc1 2017-11-25 08:21:54 -10:00
arm Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm 2017-12-03 10:51:08 -05:00
arm64 arm64: fpsimd: Prevent registers leaking from dead tasks 2017-12-06 18:02:21 +00:00
blackfin treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
c6x Kbuild updates for v4.15 2017-11-17 17:45:29 -08:00
cris pci-v4.15-changes 2017-11-15 15:01:28 -08:00
frv Kbuild updates for v4.15 2017-11-17 17:45:29 -08:00
h8300 mm, arch: remove empty_bad_page* 2017-11-15 18:21:03 -08:00
hexagon Kbuild updates for v4.15 2017-11-17 17:45:29 -08:00
ia64 arch/ia64/include/asm/topology.h: remove unused parent_node() macro 2017-11-17 16:10:04 -08:00
m32r m32r: fix endianness constraints 2017-11-15 18:21:00 -08:00
m68k m68k/macboing: Fix missed timer callback assignment 2017-11-24 16:19:40 +01:00
metag DeviceTree for 4.15: 2017-11-14 18:25:40 -08:00
microblaze Microblaze patch for 4.15-rc2 2017-11-29 14:19:22 -08:00
mips * x86 bugfixes: APIC, nested virtualization, IOAPIC 2017-11-30 08:15:19 -08:00
mn10300 bug: define the "cut here" string in a single place 2017-11-17 16:10:01 -08:00
nios2 DeviceTree for 4.15: 2017-11-14 18:25:40 -08:00
openrisc kmemcheck: remove annotations 2017-11-15 18:21:04 -08:00
parisc treewide: Switch DEFINE_TIMER callbacks to struct timer_list * 2017-11-21 15:57:05 -08:00
powerpc powerpc fixes for 4.15 #3 2017-12-01 08:40:17 -05:00
riscv RISC-V: Fixes for clean allmodconfig build 2017-12-01 13:31:31 -08:00
s390 * x86 bugfixes: APIC, nested virtualization, IOAPIC 2017-11-30 08:15:19 -08:00
score License cleanup: add SPDX license identifier to uapi header files with no license 2017-11-02 11:19:54 +01:00
sh treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
sparc Merge branch 'akpm' (patches from Andrew) 2017-11-29 19:12:44 -08:00
tile mm: switch to 'define pmd_write' instead of __HAVE_ARCH_PMD_WRITE 2017-11-29 18:40:42 -08:00
um This pull request contains the following core changes: 2017-11-22 20:46:06 -10:00
unicore32 kmemcheck: stop using GFP_NOTRACK and SLAB_NOTRACK 2017-11-15 18:21:04 -08:00
x86 * x86 bugfixes: APIC, nested virtualization, IOAPIC 2017-11-30 08:15:19 -08:00
xtensa libnvdimm for 4.15 2017-11-17 09:51:57 -08:00
.gitignore
Kconfig bpf: Revert bpf_overrid_function() helper changes. 2017-11-11 18:24:55 +09:00