]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 23 Jun 2021 15:05:43 +0000 (17:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 23 Jun 2021 15:05:43 +0000 (17:05 +0200)
added patches:
x86-fpu-reset-state-for-all-signal-restore-failures.patch

queue-4.19/series
queue-4.19/x86-fpu-reset-state-for-all-signal-restore-failures.patch [new file with mode: 0644]

index 55620858a67911bc7766379ef5921aa322468e0b..036051e8c30ebc97c7719286367ca2e1359f3d60 100644 (file)
@@ -79,3 +79,4 @@ can-bcm-raw-isotp-use-per-module-netdevice-notifier.patch
 inet-use-bigger-hash-table-for-ip-id-generation.patch
 usb-dwc3-debugfs-add-and-remove-endpoint-dirs-dynamically.patch
 usb-dwc3-core-fix-kernel-panic-when-do-reboot.patch
+x86-fpu-reset-state-for-all-signal-restore-failures.patch
diff --git a/queue-4.19/x86-fpu-reset-state-for-all-signal-restore-failures.patch b/queue-4.19/x86-fpu-reset-state-for-all-signal-restore-failures.patch
new file mode 100644 (file)
index 0000000..08fedf4
--- /dev/null
@@ -0,0 +1,91 @@
+From efa165504943f2128d50f63de0c02faf6dcceb0d Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 9 Jun 2021 21:18:00 +0200
+Subject: x86/fpu: Reset state for all signal restore failures
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit efa165504943f2128d50f63de0c02faf6dcceb0d upstream.
+
+If access_ok() or fpregs_soft_set() fails in __fpu__restore_sig() then the
+function just returns but does not clear the FPU state as it does for all
+other fatal failures.
+
+Clear the FPU state for these failures as well.
+
+Fixes: 72a671ced66d ("x86, fpu: Unify signal handling code paths for x86 and x86_64 kernels")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/87mtryyhhz.ffs@nanos.tec.linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/fpu/signal.c |   31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/kernel/fpu/signal.c
++++ b/arch/x86/kernel/fpu/signal.c
+@@ -272,6 +272,7 @@ static int __fpu__restore_sig(void __use
+       int state_size = fpu_kernel_xstate_size;
+       u64 xfeatures = 0;
+       int fx_only = 0;
++      int ret = 0;
+       ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||
+                        IS_ENABLED(CONFIG_IA32_EMULATION));
+@@ -281,15 +282,21 @@ static int __fpu__restore_sig(void __use
+               return 0;
+       }
+-      if (!access_ok(VERIFY_READ, buf, size))
+-              return -EACCES;
++      if (!access_ok(VERIFY_READ, buf, size)) {
++              ret = -EACCES;
++              goto out_err;
++      }
+       fpu__initialize(fpu);
+-      if (!static_cpu_has(X86_FEATURE_FPU))
+-              return fpregs_soft_set(current, NULL,
+-                                     0, sizeof(struct user_i387_ia32_struct),
+-                                     NULL, buf) != 0;
++      if (!static_cpu_has(X86_FEATURE_FPU)) {
++              ret = fpregs_soft_set(current, NULL,
++                                    0, sizeof(struct user_i387_ia32_struct),
++                                    NULL, buf) != 0;
++              if (ret)
++                      goto out_err;
++              return 0;
++      }
+       if (use_xsave()) {
+               struct _fpx_sw_bytes fx_sw_user;
+@@ -349,6 +356,7 @@ static int __fpu__restore_sig(void __use
+               fpu__restore(fpu);
+               local_bh_enable();
++              /* Failure is already handled */
+               return err;
+       } else {
+               /*
+@@ -356,13 +364,14 @@ static int __fpu__restore_sig(void __use
+                * state to the registers directly (with exceptions handled).
+                */
+               user_fpu_begin();
+-              if (copy_user_to_fpregs_zeroing(buf_fx, xfeatures, fx_only)) {
+-                      fpu__clear(fpu);
+-                      return -1;
+-              }
++              if (!copy_user_to_fpregs_zeroing(buf_fx, xfeatures, fx_only))
++                      return 0;
++              ret = -1;
+       }
+-      return 0;
++out_err:
++      fpu__clear(fpu);
++      return ret;
+ }
+ static inline int xstate_sigframe_size(void)