Activity log for bug #1843533

Date Who What changed Old value New value Message
2019-09-11 06:29:13 bugproxy bug added bug
2019-09-11 06:29:16 bugproxy tags architecture-ppc64le bugnameltc-181414 severity-high targetmilestone-inin18044
2019-09-11 06:29:17 bugproxy ubuntu: assignee Ubuntu on IBM Power Systems Bug Triage (ubuntu-power-triage)
2019-09-11 06:29:23 bugproxy affects ubuntu linux (Ubuntu)
2019-09-11 06:30:40 Frank Heimes bug task added ubuntu-power-systems
2019-09-11 06:30:51 Frank Heimes ubuntu-power-systems: importance Undecided High
2019-09-11 06:31:09 Frank Heimes ubuntu-power-systems: assignee Canonical Kernel Team (canonical-kernel-team)
2019-09-11 06:31:15 Frank Heimes ubuntu-power-systems: status New Triaged
2019-09-11 14:01:33 Frank Heimes description == Comment: #0 - Michael Ranweiler <mranweil@us.ibm.com> - 2019-09-11 00:49:28 == There are two problems/CVEs for power that we'd appreciate adding: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a8318c13e79badb92bc6640704a64cc022a6eb97 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. Fixes: a7771176b439 ("powerpc: Don't enable FP/Altivec if not checkpointed") Cc: stable@vger.kernel.org # 4.15+ Signed-off-by: Gustavo Romero <gromero@linux.ibm.com> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190904045529.23002-2-gromero@linux.vnet.ibm.com . 2. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8205d5d98ef7f155de211f5e2eb6ca03d95a5a60 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_thread(). We use thread->ckpt_regs.msr to determine if FP was on when in userspace. thread->ckpt_regs.msr represents the state of the MSR when exiting userspace. This is setup by check_if_tm_restore_required(). Unfortunatley there is an optimisation in giveup_all() which returns early if tsk->thread.regs->msr (via local variable `usermsr`) has FP=VEC=VSX=SPE=0. This optimisation means that check_if_tm_restore_required() is not called and hence thread->ckpt_regs.msr is not updated and will contain an old value. 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->ckpt_regs.msr will contain FP=1. If that same process is then 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->ckpt_regs.msr (the bug) and MSR FP=1 will be retained in thread->ckpt_regs.msr. tm_reclaim_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 Start userspace with MSR FP/VEC/VSX/SPE=0 TM=1 < ----- ... tbegin bne fp instruction FP unavailable ---- > fp_unavailable_tm() tm_reclaim_current() tm_reclaim_thread() giveup_all() return early since FP/VMX/VSX=0 /* ckpt MSR not updated (Incorrect) */ tm_reclaim() /* thread_struct ckpt FP regs contain junk (OK) */ /* Sees ckpt MSR FP=1 (Incorrect) */ no memcpy() performed /* thread_struct ckpt FP regs not fixed (Incorrect) */ tm_recheckpoint() /* Put junk in hardware checkpoint FP regs */ .... < ----- Return to userspace with MSR TM=1 FP=1 with junk in the FP TM checkpoint 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_tm_restore_required() in giveup_all() to ensure thread->ckpt_regs.msr is updated correctly. A simple testcase to replicate this will be posted to tools/testing/selftests/powerpc/tm/tm-poison.c Similarly for VMX. This fixes CVE-2019-15030. Fixes: f48e91e87e67 ("powerpc/tm: Fix FP and VMX register corruption") Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190904045529.23002-1-gromero@linux.vnet.ibm.com SRU Justification: ================== [Impact] * Fix FP/VMX vulerabilities - CVE-2019-15030 and CVE-2019-15031 [Fix] * a8318c13e79badb92bc6640704a64cc022a6eb97 a8318c1 "powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts" * 8205d5d98ef7f155de211f5e2eb6ca03d95a5a60 8205d5d "powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction" [Test Case] * the commits point to a simple test case in tools/testing/selftests/powerpc/tm/tm-poison.c [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=recursive -X theirs -s -e -x') could be done __________ == Comment: #0 - Michael Ranweiler <mranweil@us.ibm.com> - 2019-09-11 00:49:28 == There are two problems/CVEs for power that we'd appreciate adding: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a8318c13e79badb92bc6640704a64cc022a6eb97 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. Fixes: a7771176b439 ("powerpc: Don't enable FP/Altivec if not checkpointed") Cc: stable@vger.kernel.org # 4.15+ Signed-off-by: Gustavo Romero <gromero@linux.ibm.com> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190904045529.23002-2-gromero@linux.vnet.ibm.com . 2. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8205d5d98ef7f155de211f5e2eb6ca03d95a5a60 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_thread(). We use thread->ckpt_regs.msr to determine if FP was on when in userspace. thread->ckpt_regs.msr represents the state of the MSR when exiting userspace. This is setup by check_if_tm_restore_required(). Unfortunatley there is an optimisation in giveup_all() which returns early if tsk->thread.regs->msr (via local variable `usermsr`) has FP=VEC=VSX=SPE=0. This optimisation means that check_if_tm_restore_required() is not called and hence thread->ckpt_regs.msr is not updated and will contain an old value. 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->ckpt_regs.msr will contain FP=1. If that same process is then 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->ckpt_regs.msr (the bug) and MSR FP=1 will be retained in thread->ckpt_regs.msr. tm_reclaim_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                    Start userspace                     with MSR FP/VEC/VSX/SPE=0 TM=1                       < -----        ...        tbegin        bne        fp instruction                    FP unavailable                        ---- >                                         fp_unavailable_tm()        tm_reclaim_current()          tm_reclaim_thread()            giveup_all()              return early since FP/VMX/VSX=0       /* ckpt MSR not updated (Incorrect) */            tm_reclaim()              /* thread_struct ckpt FP regs contain junk (OK) */                                               /* Sees ckpt MSR FP=1 (Incorrect) */            no memcpy() performed              /* thread_struct ckpt FP regs not fixed (Incorrect) */        tm_recheckpoint()           /* Put junk in hardware checkpoint FP regs */                                          ....                       < -----                    Return to userspace                      with MSR TM=1 FP=1                      with junk in the FP TM checkpoint        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_tm_restore_required() in giveup_all() to ensure thread->ckpt_regs.msr is updated correctly. A simple testcase to replicate this will be posted to tools/testing/selftests/powerpc/tm/tm-poison.c Similarly for VMX. This fixes CVE-2019-15030. Fixes: f48e91e87e67 ("powerpc/tm: Fix FP and VMX register corruption") Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190904045529.23002-1-gromero@linux.vnet.ibm.com
2019-09-11 14:03:57 Frank Heimes ubuntu-power-systems: status Triaged In Progress
2019-09-16 09:50:36 Manoj Iyer linux (Ubuntu): assignee Ubuntu on IBM Power Systems Bug Triage (ubuntu-power-triage) Canonical Kernel Team (canonical-kernel-team)
2019-09-16 09:50:41 Manoj Iyer linux (Ubuntu): importance Undecided High
2019-09-16 09:50:43 Andrew Cloke linux (Ubuntu): status New In Progress
2019-09-17 20:56:27 Launchpad Janitor linux (Ubuntu): status In Progress Fix Released
2019-09-17 20:56:27 Launchpad Janitor cve linked 2019-14835
2019-09-17 20:56:27 Launchpad Janitor cve linked 2019-15030
2019-09-17 20:56:27 Launchpad Janitor cve linked 2019-15031
2019-09-18 07:49:26 Manoj Iyer nominated for series Ubuntu Bionic
2019-09-18 07:49:26 Manoj Iyer bug task added linux (Ubuntu Bionic)
2019-09-18 07:50:41 Manoj Iyer nominated for series Ubuntu Disco
2019-09-18 07:50:41 Manoj Iyer bug task added linux (Ubuntu Disco)
2019-09-18 07:50:52 Manoj Iyer linux (Ubuntu Bionic): importance Undecided High
2019-09-18 07:50:56 Manoj Iyer linux (Ubuntu Disco): importance Undecided Critical
2019-09-18 07:50:59 Manoj Iyer linux (Ubuntu Disco): importance Critical High
2019-09-18 07:51:14 Manoj Iyer linux (Ubuntu Bionic): assignee Canonical Kernel Team (canonical-kernel-team)
2019-09-18 07:51:27 Manoj Iyer linux (Ubuntu Disco): assignee Canonical Kernel Team (canonical-kernel-team)
2019-09-18 07:52:09 Frank Heimes linux (Ubuntu Disco): status New Fix Released
2019-09-18 07:52:22 Frank Heimes linux (Ubuntu Bionic): status New Confirmed
2019-09-18 08:28:27 Tyler Hicks linux (Ubuntu Bionic): status Confirmed Fix Released
2019-09-18 08:43:59 Frank Heimes ubuntu-power-systems: status In Progress Fix Released