]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Feb 2022 11:40:08 +0000 (12:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Feb 2022 11:40:08 +0000 (12:40 +0100)
added patches:
parisc-unaligned-fix-fldd-and-fstd-unaligned-handlers-on-32-bit-kernel.patch
parisc-unaligned-fix-ldw-and-stw-unalignment-handlers.patch
vhost-vsock-don-t-check-owner-in-vhost_vsock_stop-while-releasing.patch

queue-4.9/parisc-unaligned-fix-fldd-and-fstd-unaligned-handlers-on-32-bit-kernel.patch [new file with mode: 0644]
queue-4.9/parisc-unaligned-fix-ldw-and-stw-unalignment-handlers.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/vhost-vsock-don-t-check-owner-in-vhost_vsock_stop-while-releasing.patch [new file with mode: 0644]

diff --git a/queue-4.9/parisc-unaligned-fix-fldd-and-fstd-unaligned-handlers-on-32-bit-kernel.patch b/queue-4.9/parisc-unaligned-fix-fldd-and-fstd-unaligned-handlers-on-32-bit-kernel.patch
new file mode 100644 (file)
index 0000000..67ea84a
--- /dev/null
@@ -0,0 +1,80 @@
+From dd2288f4a020d693360e3e8d72f8b9d9c25f5ef6 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Fri, 18 Feb 2022 09:25:20 +0100
+Subject: parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel
+
+From: Helge Deller <deller@gmx.de>
+
+commit dd2288f4a020d693360e3e8d72f8b9d9c25f5ef6 upstream.
+
+Usually the kernel provides fixup routines to emulate the fldd and fstd
+floating-point instructions if they load or store 8-byte from/to a not
+natuarally aligned memory location.
+
+On a 32-bit kernel I noticed that those unaligned handlers didn't worked and
+instead the application got a SEGV.
+While checking the code I found two problems:
+
+First, the OPCODE_FLDD_L and OPCODE_FSTD_L cases were ifdef'ed out by the
+CONFIG_PA20 option, and as such those weren't built on a pure 32-bit kernel.
+This is now fixed by moving the CONFIG_PA20 #ifdef to prevent the compilation
+of OPCODE_LDD_L and OPCODE_FSTD_L only, and handling the fldd and fstd
+instructions.
+
+The second problem are two bugs in the 32-bit inline assembly code, where the
+wrong registers where used. The calculation of the natural alignment used %2
+(vall) instead of %3 (ior), and the first word was stored back to address %1
+(valh) instead of %3 (ior).
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/kernel/unaligned.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/parisc/kernel/unaligned.c
++++ b/arch/parisc/kernel/unaligned.c
+@@ -410,7 +410,7 @@ static int emulate_std(struct pt_regs *r
+       __asm__ __volatile__ (
+ "     mtsp    %4, %%sr1\n"
+ "     zdep    %2, 29, 2, %%r19\n"
+-"     dep     %%r0, 31, 2, %2\n"
++"     dep     %%r0, 31, 2, %3\n"
+ "     mtsar   %%r19\n"
+ "     zvdepi  -2, 32, %%r19\n"
+ "1:   ldw     0(%%sr1,%3),%%r20\n"
+@@ -422,7 +422,7 @@ static int emulate_std(struct pt_regs *r
+ "     andcm   %%r21, %%r19, %%r21\n"
+ "     or      %1, %%r20, %1\n"
+ "     or      %2, %%r21, %2\n"
+-"3:   stw     %1,0(%%sr1,%1)\n"
++"3:   stw     %1,0(%%sr1,%3)\n"
+ "4:   stw     %%r1,4(%%sr1,%3)\n"
+ "5:   stw     %2,8(%%sr1,%3)\n"
+ "     copy    %%r0, %0\n"
+@@ -610,7 +610,6 @@ void handle_unaligned(struct pt_regs *re
+               ret = ERR_NOTHANDLED;   /* "undefined", but lets kill them. */
+               break;
+       }
+-#ifdef CONFIG_PA20
+       switch (regs->iir & OPCODE2_MASK)
+       {
+       case OPCODE_FLDD_L:
+@@ -621,14 +620,15 @@ void handle_unaligned(struct pt_regs *re
+               flop=1;
+               ret = emulate_std(regs, R2(regs->iir),1);
+               break;
++#ifdef CONFIG_PA20
+       case OPCODE_LDD_L:
+               ret = emulate_ldd(regs, R2(regs->iir),0);
+               break;
+       case OPCODE_STD_L:
+               ret = emulate_std(regs, R2(regs->iir),0);
+               break;
+-      }
+ #endif
++      }
+       switch (regs->iir & OPCODE3_MASK)
+       {
+       case OPCODE_FLDW_L:
diff --git a/queue-4.9/parisc-unaligned-fix-ldw-and-stw-unalignment-handlers.patch b/queue-4.9/parisc-unaligned-fix-ldw-and-stw-unalignment-handlers.patch
new file mode 100644 (file)
index 0000000..d9a5661
--- /dev/null
@@ -0,0 +1,49 @@
+From a97279836867b1cb50a3d4f0b1bf60e0abe6d46c Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Fri, 18 Feb 2022 23:40:14 +0100
+Subject: parisc/unaligned: Fix ldw() and stw() unalignment handlers
+
+From: Helge Deller <deller@gmx.de>
+
+commit a97279836867b1cb50a3d4f0b1bf60e0abe6d46c upstream.
+
+Fix 3 bugs:
+
+a) emulate_stw() doesn't return the error code value, so faulting
+instructions are not reported and aborted.
+
+b) Tell emulate_ldw() to handle fldw_l as floating point instruction
+
+c) Tell emulate_ldw() to handle ldw_m as integer instruction
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/kernel/unaligned.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/parisc/kernel/unaligned.c
++++ b/arch/parisc/kernel/unaligned.c
+@@ -353,7 +353,7 @@ static int emulate_stw(struct pt_regs *r
+       : "r" (val), "r" (regs->ior), "r" (regs->isr)
+       : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+-      return 0;
++      return ret;
+ }
+ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
+ {
+@@ -633,10 +633,10 @@ void handle_unaligned(struct pt_regs *re
+       {
+       case OPCODE_FLDW_L:
+               flop=1;
+-              ret = emulate_ldw(regs, R2(regs->iir),0);
++              ret = emulate_ldw(regs, R2(regs->iir), 1);
+               break;
+       case OPCODE_LDW_M:
+-              ret = emulate_ldw(regs, R2(regs->iir),1);
++              ret = emulate_ldw(regs, R2(regs->iir), 0);
+               break;
+       case OPCODE_FSTW_L:
index e8e53aabba7f558dab207a18072d5bd6ae1f50f7..521cb2e3f7ebf84ed68bbbfc9a00e0107749dd1c 100644 (file)
@@ -1 +1,4 @@
 mtd-rawnand-brcmnand-fixed-incorrect-sub-page-ecc-status.patch
+vhost-vsock-don-t-check-owner-in-vhost_vsock_stop-while-releasing.patch
+parisc-unaligned-fix-fldd-and-fstd-unaligned-handlers-on-32-bit-kernel.patch
+parisc-unaligned-fix-ldw-and-stw-unalignment-handlers.patch
diff --git a/queue-4.9/vhost-vsock-don-t-check-owner-in-vhost_vsock_stop-while-releasing.patch b/queue-4.9/vhost-vsock-don-t-check-owner-in-vhost_vsock_stop-while-releasing.patch
new file mode 100644 (file)
index 0000000..600e27e
--- /dev/null
@@ -0,0 +1,85 @@
+From a58da53ffd70294ebea8ecd0eb45fd0d74add9f9 Mon Sep 17 00:00:00 2001
+From: Stefano Garzarella <sgarzare@redhat.com>
+Date: Tue, 22 Feb 2022 10:47:42 +0100
+Subject: vhost/vsock: don't check owner in vhost_vsock_stop() while releasing
+
+From: Stefano Garzarella <sgarzare@redhat.com>
+
+commit a58da53ffd70294ebea8ecd0eb45fd0d74add9f9 upstream.
+
+vhost_vsock_stop() calls vhost_dev_check_owner() to check the device
+ownership. It expects current->mm to be valid.
+
+vhost_vsock_stop() is also called by vhost_vsock_dev_release() when
+the user has not done close(), so when we are in do_exit(). In this
+case current->mm is invalid and we're releasing the device, so we
+should clean it anyway.
+
+Let's check the owner only when vhost_vsock_stop() is called
+by an ioctl.
+
+When invoked from release we can not fail so we don't check return
+code of vhost_vsock_stop(). We need to stop vsock even if it's not
+the owner.
+
+Fixes: 433fc58e6bf2 ("VSOCK: Introduce vhost_vsock.ko")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+1e3ea63db39f2b4440e0@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+3140b17cb44a7b174008@syzkaller.appspotmail.com
+Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vsock.c |   21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -484,16 +484,18 @@ err:
+       return ret;
+ }
+-static int vhost_vsock_stop(struct vhost_vsock *vsock)
++static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
+ {
+       size_t i;
+-      int ret;
++      int ret = 0;
+       mutex_lock(&vsock->dev.mutex);
+-      ret = vhost_dev_check_owner(&vsock->dev);
+-      if (ret)
+-              goto err;
++      if (check_owner) {
++              ret = vhost_dev_check_owner(&vsock->dev);
++              if (ret)
++                      goto err;
++      }
+       for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
+               struct vhost_virtqueue *vq = &vsock->vqs[i];
+@@ -611,7 +613,12 @@ static int vhost_vsock_dev_release(struc
+        * inefficient.  Room for improvement here. */
+       vsock_for_each_connected_socket(vhost_vsock_reset_orphans);
+-      vhost_vsock_stop(vsock);
++      /* Don't check the owner, because we are in the release path, so we
++       * need to stop the vsock device in any case.
++       * vhost_vsock_stop() can not fail in this case, so we don't need to
++       * check the return code.
++       */
++      vhost_vsock_stop(vsock, false);
+       vhost_vsock_flush(vsock);
+       vhost_dev_stop(&vsock->dev);
+@@ -709,7 +716,7 @@ static long vhost_vsock_dev_ioctl(struct
+               if (start)
+                       return vhost_vsock_start(vsock);
+               else
+-                      return vhost_vsock_stop(vsock);
++                      return vhost_vsock_stop(vsock, true);
+       case VHOST_GET_FEATURES:
+               features = VHOST_VSOCK_FEATURES;
+               if (copy_to_user(argp, &features, sizeof(features)))