Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 7403/1: tls: remove covert channel via TPIDRURW

TPIDRURW is a user read/write register forming part of the group of
thread registers in more recent versions of the ARM architecture (~v6+).

Currently, the kernel does not touch this register, which allows tasks
to communicate covertly by reading and writing to the register without
context-switching affecting its contents.

This patch clears TPIDRURW when TPIDRURO is updated via the set_tls
macro, which is called directly from __switch_to. Since the current
behaviour makes the register useless to userspace as far as thread
pointers are concerned, simply clearing the register (rather than saving
and restoring it) will not cause any problems to userspace.

Cc: stable@vger.kernel.org
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Will Deacon and committed by
Russell King
6a1c5312 14904927

+4
+4
arch/arm/include/asm/tls.h
··· 7 7 8 8 .macro set_tls_v6k, tp, tmp1, tmp2 9 9 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register 10 + mov \tmp1, #0 11 + mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register 10 12 .endm 11 13 12 14 .macro set_tls_v6, tp, tmp1, tmp2 ··· 17 15 mov \tmp2, #0xffff0fff 18 16 tst \tmp1, #HWCAP_TLS @ hardware TLS available? 19 17 mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register 18 + movne \tmp1, #0 19 + mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register 20 20 streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 21 21 .endm 22 22