FAILED: patch "[PATCH] powerpc/tm: Fix restoring FP/VMX facility incorrectly on" failed to apply to 4.19-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a8318c13e79badb92bc6640704a64cc022a6eb97 Mon Sep 17 00:00:00 2001
From: Gustavo Romero <[email protected]>
Date: Wed, 4 Sep 2019 00:55:28 -0400
Subject: [PATCH] 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
Start userspace
with MSR FP=0 TM=1
< -----
...
tbegin
bne
Hardware interrupt
---- >
<do_IRQ...>
....
ret_from_except
restore_math()
/* sees FP=0 */
restore_fp()
tm_active_with_fp()
/* sees FP=1 (Incorrect) */
load_fp_state()
FP = 0 -> 1
< -----
Return to userspace
with MSR TM=1 FP=1
with junk in the FP TM checkpoint 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_with_fp().
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/selftests/powerpc/tm/tm-poison.c
This fixes CVE-2019-15031.
arch/powerpc/kernel/process.c +2 -16
@@ -101,21 +101,8 @@ static void check_if_tm_restore_required(struct task_struct *tsk) } } -static bool tm_active_with_fp (struct task_struct *tsk) -{ -return MSR_TM_ACTIVE (tsk->thread.regs->msr) && - (tsk->thread.ckpt_regs.msr &MSR_FP ); -} - -static bool tm_active_with_altivec (struct task_struct *tsk) -{ -return MSR_TM_ACTIVE (tsk->thread.regs->msr) && - (tsk->thread.ckpt_regs.msr &MSR_VEC ); -}#else static inline void check_if_tm_restore_required (struct task_struct *tsk) { } -static inline bool tm_active_with_fp (struct task_struct *tsk) {return false; } -static inline bool tm_active_with_altivec (struct task_struct *tsk) {return false; }#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ bool strict_msr_control;
@@ -252,7 +239,7 @@ EXPORT_SYMBOL(enable_kernel_fp);static int restore_fp (struct task_struct *tsk) { -if (tsk->thread.load_fp ||tm_active_with_fp (tsk)) { +if (tsk->thread.load_fp) {load_fp_state (¤t->thread.fp_state); current->thread.load_fp++;return 1 ;
@@ -334,8 +321,7 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread);static int restore_altivec (struct task_struct *tsk) { -if (cpu_has_feature (CPU_FTR_ALTIVEC ) && - (tsk->thread.load_vec ||tm_active_with_altivec (tsk))) { +if (cpu_has_feature (CPU_FTR_ALTIVEC ) && (tsk->thread.load_vec)) {load_vr_state (&tsk->thread.vr_state); tsk->thread.used_vr =1 ; tsk->thread.load_vec++;
PATCH 1/1 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
Start userspace
with MSR FP=0 TM=1
< -----
...
tbegin
bne
Hardware interrupt
---- >
<do_IRQ...>
....
ret_from_except
restore_math()
/* sees FP=0 */
restore_fp()
tm_active_with_fp()
/* sees FP=1 (Incorrect) */
load_fp_state()
FP = 0 -> 1
< -----
Return to userspace
with MSR TM=1 FP=1
with junk in the FP TM checkpoint 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_with_fp().
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/selftests/powerpc/tm/tm-poison.c
This fixes CVE-2019-15031.
---
Greg, This is a backport for v4.19 only since the original patch didn't apply.
Commit a8318c13e79badb92bc6640704a64cc022a6eb97 upstream.
arch/powerpc/kernel/process.c | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
arch/powerpc/kernel/process.c +2 -17
@@ -106,23 +106,9 @@ static inline bool msr_tm_active(unsigned long msr) {return MSR_TM_ACTIVE (msr); } - -static bool tm_active_with_fp (struct task_struct *tsk) -{ -return msr_tm_active (tsk->thread.regs->msr) && - (tsk->thread.ckpt_regs.msr &MSR_FP ); -} - -static bool tm_active_with_altivec (struct task_struct *tsk) -{ -return msr_tm_active (tsk->thread.regs->msr) && - (tsk->thread.ckpt_regs.msr &MSR_VEC ); -}#else static inline bool msr_tm_active (unsigned long msr) {return false; }static inline void check_if_tm_restore_required (struct task_struct *tsk) { } -static inline bool tm_active_with_fp (struct task_struct *tsk) {return false; } -static inline bool tm_active_with_altivec (struct task_struct *tsk) {return false; }#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ bool strict_msr_control;
@@ -256,7 +242,7 @@ EXPORT_SYMBOL(enable_kernel_fp);static int restore_fp (struct task_struct *tsk) { -if (tsk->thread.load_fp ||tm_active_with_fp (tsk)) { +if (tsk->thread.load_fp) {load_fp_state (¤t->thread.fp_state); current->thread.load_fp++;return 1 ;
@@ -337,8 +323,7 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread);static int restore_altivec (struct task_struct *tsk) { -if (cpu_has_feature (CPU_FTR_ALTIVEC ) && - (tsk->thread.load_vec ||tm_active_with_altivec (tsk))) { +if (cpu_has_feature (CPU_FTR_ALTIVEC ) && (tsk->thread.load_vec)) {load_vr_state (&tsk->thread.vr_state); tsk->thread.used_vr =1 ; tsk->thread.load_vec++;
Signature · 1 line
2.21.0
Greg KH
maintainerRe: [PATCH 4.19] powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts
Quoted 75 lines · Michael Neuling
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 Start userspace with MSR FP=0 TM=1 < ----- ... tbegin bne Hardware interrupt ---- > <do_IRQ...> .... ret_from_except restore_math() /* sees FP=0 */ restore_fp() tm_active_with_fp() /* sees FP=1 (Incorrect) */ load_fp_state() FP = 0 -> 1 < ----- Return to userspace with MSR TM=1 FP=1 with junk in the FP TM checkpoint TM rollback reads FP junkWhen returning from the hardware exception,
tm_active_with_fp()is incorrectly makingrestore_fp()callload_fp_state()which is setting FP=1.The fix is to remove
tm_active_with_fp().
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 removetm_active_with_fp()as this case is handled byrestore_tm_state().restore_tm_state()detects if FP has been using inside a transaction and will setload_fpand callrestore_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/selftests/powerpc/tm/tm-poison.cThis fixes CVE-2019-15031.
Fixes a7771176b439 ("powerpc: Don't enable FP/Altivec if not checkpointed")Cc [email protected] # 4.15+Signed-off-by Gustavo Romero <[email protected]>Signed-off-by Michael Neuling <[email protected]>Signed-off-by Michael Ellerman <[email protected]>
Quoted 5 lines
---
Greg, This is a backport for v4.19 only since the original patch didn't apply.Commit
a8318c13e79badb92bc6640704a64cc022a6eb97upstream.
Now queued up, thanks.
greg k-h
Sasha Levin
maintainerRe: [PATCH 4.19] powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts
Quoted 80 lines · Greg KH
Quoted 79 lines · Michael Neuling
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 Start userspace with MSR FP=0 TM=1 < ----- ... tbegin bne Hardware interrupt ---- > <do_IRQ...> .... ret_from_except restore_math() /* sees FP=0 */ restore_fp() tm_active_with_fp() /* sees FP=1 (Incorrect) */ load_fp_state() FP = 0 -> 1 < ----- Return to userspace with MSR TM=1 FP=1 with junk in the FP TM checkpoint TM rollback reads FP junkWhen returning from the hardware exception,
tm_active_with_fp()is incorrectly makingrestore_fp()callload_fp_state()which is setting FP=1.The fix is to remove
tm_active_with_fp().
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 removetm_active_with_fp()as this case is handled byrestore_tm_state().restore_tm_state()detects if FP has been using inside a transaction and will setload_fpand callrestore_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/selftests/powerpc/tm/tm-poison.cThis fixes CVE-2019-15031.
Fixes a7771176b439 ("powerpc: Don't enable FP/Altivec if not checkpointed")Cc [email protected] # 4.15+Signed-off-by Gustavo Romero <[email protected]>Signed-off-by Michael Neuling <[email protected]>Signed-off-by Michael Ellerman <[email protected]>---
Greg, This is a backport for v4.19 only since the original patch didn't apply.
Quoted 3 lines
Quoted 1 line
Commit
a8318c13e79badb92bc6640704a64cc022a6eb97upstream.Now queued up, thanks.
Michael,
Thank you for the backport. Would you have an objection if instead I'd just take 5c784c8414fba ("powerpc/tm: Remove msr_tm_active()") as well?
--
Thanks,
Sasha
Re: [PATCH 4.19] powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Fixes a7771176b439 ("powerpc: Don't enable FP/Altivec if notcheckpointed")
Cc [email protected] # 4.15+Signed-off-by Gustavo Romero <[email protected]>Signed-off-by Michael Neuling <[email protected]>Signed-off-by Michael Ellerman <[email protected]>Link:
https://lore.kernel.org/r/[email protected]
---
Greg, This is a backport for v4.19 only since the original patch didn't apply.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Commit
a8318c13e79badb92bc6640704a64cc022a6eb97upstream.Now queued up, thanks.
Michael,
Thank you for the backport. Would you have an objection if instead I'd just take
5c784c8414fba("powerpc/tm: Removemsr_tm_active()") as well?
Yep that works.
Thanks,
Mikey