powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts (CVE-2019-15031) / powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction (CVE-2019-15030)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
The Ubuntu-power-systems project |
Fix Released
|
High
|
Canonical Kernel Team | ||
linux (Ubuntu) |
Fix Released
|
High
|
Canonical Kernel Team | ||
Bionic |
Fix Released
|
High
|
Canonical Kernel Team | ||
Disco |
Fix Released
|
High
|
Canonical Kernel Team |
Bug Description
SRU Justification:
==================
[Impact]
* Fix FP/VMX vulerabilities - CVE-2019-15030 and CVE-2019-15031
[Fix]
* a8318c13e79badb
* 8205d5d98ef7f15
[Test Case]
* the commits point to a simple test case in tools/testing/
[Regression Potential]
* The regression potential can be considered as moderate
[Other Info]
* a8318c1 fixes CVE-2019-15031
* 8205d5d fixes CVE-2019-15030
* the commits are in 5.3, hence already in Eoan
* simple cherry-pick (on bionic master-next with '--strategy=
__________
== Comment: #0 - Michael Ranweiler <email address hidden> - 2019-09-11 00:49:28 ==
There are two problems/CVEs for power that we'd appreciate adding:
powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts
When in userspace and MSR FP=0 the hardware FP state is unrelated to
the current process. This is extended for transactions where if tbegin
is run with FP=0, the hardware checkpoint FP state will also be
unrelated to the current process. Due to this, we need to ensure this
hardware checkpoint is updated with the correct state before we enable
FP for this process.
Unfortunately we get this wrong when returning to a process from a
hardware interrupt. A process that starts a transaction with FP=0 can
take an interrupt. When the kernel returns back to that process, we
change to FP=1 but with hardware checkpoint FP state not updated. If
this transaction is then rolled back, the FP registers now contain the
wrong state.
The process looks like this:
Userspace: Kernel
< -----
...
tbegin
bne
/* sees FP=0 */
/* sees FP=1 (Incorrect) */
< -----
TM rollback
reads FP junk
When returning from the hardware exception, tm_active_with_fp() is
incorrectly making restore_fp() call load_fp_state() which is setting
FP=1.
The fix is to remove tm_active_
tm_active_with_fp() is attempting to handle the case where FP state
has been changed inside a transaction. In this case the checkpointed
and transactional FP state is different and hence we must restore the
FP state (ie. we can't do lazy FP restore inside a transaction that's
used FP). It's safe to remove tm_active_with_fp() as this case is
handled by restore_tm_state(). restore_tm_state() detects if FP has
been using inside a transaction and will set load_fp and call
restore_math() to ensure the FP state (checkpoint and transaction) is
restored.
This is a data integrity problem for the current process as the FP
registers are corrupted. It's also a security problem as the FP
registers from one process may be leaked to another.
Similarly for VMX.
A simple testcase to replicate this will be posted to
tools/testing/
This fixes CVE-2019-15031.
Fixes: a7771176b439 ("powerpc: Don't enable FP/Altivec if not checkpointed")
Cc: <email address hidden> # 4.15+
Signed-off-by: Gustavo Romero <email address hidden>
Signed-off-by: Michael Neuling <email address hidden>
Signed-off-by: Michael Ellerman <email address hidden>
Link: https://<email address hidden>
.
2.
https:/
powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction
When we take an FP unavailable exception in a transaction we have to
account for the hardware FP TM checkpointed registers being
incorrect. In this case for this process we know the current and
checkpointed FP registers must be the same (since FP wasn't used
inside the transaction) hence in the thread_struct we copy the current
FP registers to the checkpointed ones.
This copy is done in tm_reclaim_
to determine if FP was on when in userspace. thread-
represents the state of the MSR when exiting userspace. This is setup
by check_if_
Unfortunatley there is an optimisation in giveup_all() which returns
early if tsk->thread.
FP=VEC=VSX=SPE=0. This optimisation means that
check_if_
thread-
This can happen if due to load_fp=255 we start a userspace process
with MSR FP=1 and then we are context switched out. In this case
thread-
context switched in and load_fp overflows, MSR will have FP=0. If that
process now enters a transaction and does an FP instruction, the FP
unavailable will not update thread-
FP=1 will be retained in thread-
will then not perform the required memcpy and the checkpointed FP regs
in the thread struct will contain the wrong values.
The code path for this happening is:
Userspace: Kernel
...
tbegin
bne
fp instruction
return early since FP/VMX/VSX=0
/* ckpt MSR not updated (Incorrect) */
/* thread_struct ckpt FP regs contain junk (OK) */
no memcpy() performed
/* thread_struct ckpt FP regs not fixed (Incorrect) */
/* Put junk in hardware checkpoint FP regs */
TM rollback
reads FP junk
This is a data integrity problem for the current process as the FP
registers are corrupted. It's also a security problem as the FP
registers from one process may be leaked to another.
This patch moves up check_if_
ensure thread-
A simple testcase to replicate this will be posted to
tools/testing/
Similarly for VMX.
This fixes CVE-2019-15030.
Fixes: f48e91e87e67 ("powerpc/tm: Fix FP and VMX register corruption")
Cc: <email address hidden> # 4.12+
Signed-off-by: Gustavo Romero <email address hidden>
Signed-off-by: Michael Neuling <email address hidden>
Signed-off-by: Michael Ellerman <email address hidden>
Link: https://<email address hidden>
CVE References
tags: | added: architecture-ppc64le bugnameltc-181414 severity-high targetmilestone-inin18044 |
Changed in ubuntu: | |
assignee: | nobody → Ubuntu on IBM Power Systems Bug Triage (ubuntu-power-triage) |
affects: | ubuntu → linux (Ubuntu) |
Changed in ubuntu-power-systems: | |
importance: | Undecided → High |
assignee: | nobody → Canonical Kernel Team (canonical-kernel-team) |
status: | New → Triaged |
Changed in linux (Ubuntu): | |
assignee: | Ubuntu on IBM Power Systems Bug Triage (ubuntu-power-triage) → Canonical Kernel Team (canonical-kernel-team) |
importance: | Undecided → High |
Changed in linux (Ubuntu): | |
status: | New → In Progress |
Changed in linux (Ubuntu Bionic): | |
importance: | Undecided → High |
Changed in linux (Ubuntu Disco): | |
importance: | Undecided → Critical |
importance: | Critical → High |
Changed in linux (Ubuntu Bionic): | |
assignee: | nobody → Canonical Kernel Team (canonical-kernel-team) |
Changed in linux (Ubuntu Disco): | |
assignee: | nobody → Canonical Kernel Team (canonical-kernel-team) |
Changed in linux (Ubuntu Disco): | |
status: | New → Fix Released |
Changed in linux (Ubuntu Bionic): | |
status: | New → Confirmed |
Changed in ubuntu-power-systems: | |
status: | In Progress → Fix Released |
The commits are already incl. in Eoan master-next,
and with that they are already in eoan-proposed:
linux-generic | 5.3.0.10.11 | eoan-proposed | s390x
Hence SRU for Disco and Bionic is now needed.