linux/arch/powerpc
Michael Ellerman 8e12784444 powerpc/32: Fix overread/overwrite of thread_struct via ptrace
The ptrace PEEKUSR/POKEUSR (aka PEEKUSER/POKEUSER) API allows a process
to read/write registers of another process.

To get/set a register, the API takes an index into an imaginary address
space called the "USER area", where the registers of the process are
laid out in some fashion.

The kernel then maps that index to a particular register in its own data
structures and gets/sets the value.

The API only allows a single machine-word to be read/written at a time.
So 4 bytes on 32-bit kernels and 8 bytes on 64-bit kernels.

The way floating point registers (FPRs) are addressed is somewhat
complicated, because double precision float values are 64-bit even on
32-bit CPUs. That means on 32-bit kernels each FPR occupies two
word-sized locations in the USER area. On 64-bit kernels each FPR
occupies one word-sized location in the USER area.

Internally the kernel stores the FPRs in an array of u64s, or if VSX is
enabled, an array of pairs of u64s where one half of each pair stores
the FPR. Which half of the pair stores the FPR depends on the kernel's
endianness.

To handle the different layouts of the FPRs depending on VSX/no-VSX and
big/little endian, the TS_FPR() macro was introduced.

Unfortunately the TS_FPR() macro does not take into account the fact
that the addressing of each FPR differs between 32-bit and 64-bit
kernels. It just takes the index into the "USER area" passed from
userspace and indexes into the fp_state.fpr array.

On 32-bit there are 64 indexes that address FPRs, but only 32 entries in
the fp_state.fpr array, meaning the user can read/write 256 bytes past
the end of the array. Because the fp_state sits in the middle of the
thread_struct there are various fields than can be overwritten,
including some pointers. As such it may be exploitable.

It has also been observed to cause systems to hang or otherwise
misbehave when using gdbserver, and is probably the root cause of this
report which could not be easily reproduced:
  https://lore.kernel.org/linuxppc-dev/dc38afe9-6b78-f3f5-666b-986939e40fc6@keymile.com/

Rather than trying to make the TS_FPR() macro even more complicated to
fix the bug, or add more macros, instead add a special-case for 32-bit
kernels. This is more obvious and hopefully avoids a similar bug
happening again in future.

Note that because 32-bit kernels never have VSX enabled the code doesn't
need to consider TS_FPRWIDTH/OFFSET at all. Add a BUILD_BUG_ON() to
ensure that 32-bit && VSX is never enabled.

Fixes: 87fec0514f ("powerpc: PTRACE_PEEKUSR/PTRACE_POKEUSER of FPR registers in little endian builds")
Cc: stable@vger.kernel.org # v3.13+
Reported-by: Ariel Miculas <ariel.miculas@belden.com>
Tested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220609133245.573565-1-mpe@ellerman.id.au
2022-06-09 23:32:56 +10:00
..
boot powerpc updates for 5.19 2022-05-28 11:27:17 -07:00
configs eth: de4x5: remove support for Generic DECchip & DIGITAL EtherWORKS PCI/EISA 2022-05-23 11:43:51 +01:00
crypto powerpc: fix typos in comments 2022-05-05 22:12:44 +10:00
include powerpc/kasan: Force thread size increase with KASAN 2022-06-02 22:56:47 +10:00
kernel powerpc/32: Fix overread/overwrite of thread_struct via ptrace 2022-06-09 23:32:56 +10:00
kexec powerpc/kasan: Mark more real-mode code as not to be instrumented 2022-05-29 10:30:42 +10:00
kvm powerpc: Fix all occurences of "the the" 2022-05-22 15:59:43 +10:00
lib powerpc updates for 5.19 2022-05-28 11:27:17 -07:00
math-emu
mm powerpc/book3e: get rid of #include <generated/compile.h> 2022-06-06 10:23:33 +10:00
net powerpc/inst: Remove PPC_INST_BL 2022-05-22 15:58:27 +10:00
perf powerpc/perf: Fix the threshold compare group constraint for power9 2022-05-22 15:58:30 +10:00
platforms powerpc/papr_scm: don't requests stats with '0' sized stats buffer 2022-05-31 10:18:52 +10:00
purgatory
sysdev powerpc/xics: Include missing header 2022-05-24 20:44:30 +10:00
tools powerpc/64: Add UADDR64 relocation support 2022-03-09 21:47:53 +11:00
xmon powerpc: Fix all occurences of "the the" 2022-05-22 15:59:43 +10:00
Kbuild kbuild: use more subdir- for visiting subdirectories while cleaning 2021-10-24 13:49:46 +09:00
Kconfig powerpc/kasan: Force thread size increase with KASAN 2022-06-02 22:56:47 +10:00
Kconfig.debug powerpc: Book3S 64-bit outline-only KASAN support 2022-05-22 15:58:29 +10:00
Makefile powerpc updates for 5.19 2022-05-28 11:27:17 -07:00
Makefile.postlink