** Also affects: ubuntu-power-systems
   Importance: Undecided
       Status: New

** Changed in: ubuntu-power-systems
   Importance: Undecided => High

** Changed in: ubuntu-power-systems
     Assignee: (unassigned) => Canonical Kernel Team (canonical-kernel-team)

** Changed in: ubuntu-power-systems
       Status: New => Triaged

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1843533

Title:
  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)

Status in The Ubuntu-power-systems project:
  Triaged
Status in linux package in Ubuntu:
  New

Bug description:
  == Comment: #0 - Michael Ranweiler <mranw...@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: sta...@vger.kernel.org # 4.15+
  Signed-off-by: Gustavo Romero <grom...@linux.ibm.com>
  Signed-off-by: Michael Neuling <mi...@neuling.org>
  Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
  Link: 
https://lore.kernel.org/r/20190904045529.23002-2-grom...@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: sta...@vger.kernel.org # 4.12+
  Signed-off-by: Gustavo Romero <grom...@linux.vnet.ibm.com>
  Signed-off-by: Michael Neuling <mi...@neuling.org>
  Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
  Link: 
https://lore.kernel.org/r/20190904045529.23002-1-grom...@linux.vnet.ibm.com

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu-power-systems/+bug/1843533/+subscriptions

-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : kernel-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to