]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Aug 2022 15:33:41 +0000 (17:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Aug 2022 15:33:41 +0000 (17:33 +0200)
added patches:
revert-net-usb-ax88179_178a-needs-flag_send_zlp.patch
scsi-sg-allow-waiting-for-commands-to-complete-on-removed-device.patch

queue-4.14/revert-net-usb-ax88179_178a-needs-flag_send_zlp.patch [new file with mode: 0644]
queue-4.14/scsi-sg-allow-waiting-for-commands-to-complete-on-removed-device.patch [new file with mode: 0644]

diff --git a/queue-4.14/revert-net-usb-ax88179_178a-needs-flag_send_zlp.patch b/queue-4.14/revert-net-usb-ax88179_178a-needs-flag_send_zlp.patch
new file mode 100644 (file)
index 0000000..d5c2bde
--- /dev/null
@@ -0,0 +1,105 @@
+From 6fd2c17fb6e02a8c0ab51df1cfec82ce96b8e83d Mon Sep 17 00:00:00 2001
+From: Jose Alonso <joalonsof@gmail.com>
+Date: Mon, 8 Aug 2022 08:35:04 -0300
+Subject: Revert "net: usb: ax88179_178a needs FLAG_SEND_ZLP"
+
+From: Jose Alonso <joalonsof@gmail.com>
+
+commit 6fd2c17fb6e02a8c0ab51df1cfec82ce96b8e83d upstream.
+
+This reverts commit 36a15e1cb134c0395261ba1940762703f778438c.
+
+The usage of FLAG_SEND_ZLP causes problems to other firmware/hardware
+versions that have no issues.
+
+The FLAG_SEND_ZLP is not safe to use in this context.
+See:
+https://patchwork.ozlabs.org/project/netdev/patch/1270599787.8900.8.camel@Linuxdev4-laptop/#118378
+The original problem needs another way to solve.
+
+Fixes: 36a15e1cb134 ("net: usb: ax88179_178a needs FLAG_SEND_ZLP")
+Cc: stable@vger.kernel.org
+Reported-by: Ronald Wahl <ronald.wahl@raritan.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216327
+Link: https://bugs.archlinux.org/task/75491
+Signed-off-by: Jose Alonso <joalonsof@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/ax88179_178a.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -1707,7 +1707,7 @@ static const struct driver_info ax88179_
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1720,7 +1720,7 @@ static const struct driver_info ax88178a
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1733,7 +1733,7 @@ static const struct driver_info cypress_
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1746,7 +1746,7 @@ static const struct driver_info dlink_du
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1759,7 +1759,7 @@ static const struct driver_info sitecom_
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1772,7 +1772,7 @@ static const struct driver_info samsung_
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1785,7 +1785,7 @@ static const struct driver_info lenovo_i
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+-      .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1798,7 +1798,7 @@ static const struct driver_info belkin_i
+       .link_reset = ax88179_link_reset,
+       .reset  = ax88179_reset,
+       .stop   = ax88179_stop,
+-      .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
++      .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+ };
diff --git a/queue-4.14/scsi-sg-allow-waiting-for-commands-to-complete-on-removed-device.patch b/queue-4.14/scsi-sg-allow-waiting-for-commands-to-complete-on-removed-device.patch
new file mode 100644 (file)
index 0000000..debbe77
--- /dev/null
@@ -0,0 +1,148 @@
+From 3455607fd7be10b449f5135c00dc306b85dc0d21 Mon Sep 17 00:00:00 2001
+From: Tony Battersby <tonyb@cybernetics.com>
+Date: Mon, 11 Jul 2022 10:51:32 -0400
+Subject: scsi: sg: Allow waiting for commands to complete on removed device
+
+From: Tony Battersby <tonyb@cybernetics.com>
+
+commit 3455607fd7be10b449f5135c00dc306b85dc0d21 upstream.
+
+When a SCSI device is removed while in active use, currently sg will
+immediately return -ENODEV on any attempt to wait for active commands that
+were sent before the removal.  This is problematic for commands that use
+SG_FLAG_DIRECT_IO since the data buffer may still be in use by the kernel
+when userspace frees or reuses it after getting ENODEV, leading to
+corrupted userspace memory (in the case of READ-type commands) or corrupted
+data being sent to the device (in the case of WRITE-type commands).  This
+has been seen in practice when logging out of a iscsi_tcp session, where
+the iSCSI driver may still be processing commands after the device has been
+marked for removal.
+
+Change the policy to allow userspace to wait for active sg commands even
+when the device is being removed.  Return -ENODEV only when there are no
+more responses to read.
+
+Link: https://lore.kernel.org/r/5ebea46f-fe83-2d0b-233d-d0dcb362dd0a@cybernetics.com
+Cc: <stable@vger.kernel.org>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/sg.c |   57 ++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 34 insertions(+), 23 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -196,7 +196,7 @@ static void sg_link_reserve(Sg_fd * sfp,
+ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
+ static Sg_fd *sg_add_sfp(Sg_device * sdp);
+ static void sg_remove_sfp(struct kref *);
+-static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
++static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy);
+ static Sg_request *sg_add_request(Sg_fd * sfp);
+ static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
+ static Sg_device *sg_get_dev(int dev);
+@@ -418,6 +418,7 @@ sg_read(struct file *filp, char __user *
+       Sg_fd *sfp;
+       Sg_request *srp;
+       int req_pack_id = -1;
++      bool busy;
+       sg_io_hdr_t *hp;
+       struct sg_header *old_hdr = NULL;
+       int retval = 0;
+@@ -465,25 +466,19 @@ sg_read(struct file *filp, char __user *
+               } else
+                       req_pack_id = old_hdr->pack_id;
+       }
+-      srp = sg_get_rq_mark(sfp, req_pack_id);
++      srp = sg_get_rq_mark(sfp, req_pack_id, &busy);
+       if (!srp) {             /* now wait on packet to arrive */
+-              if (atomic_read(&sdp->detaching)) {
+-                      retval = -ENODEV;
+-                      goto free_old_hdr;
+-              }
+               if (filp->f_flags & O_NONBLOCK) {
+                       retval = -EAGAIN;
+                       goto free_old_hdr;
+               }
+               retval = wait_event_interruptible(sfp->read_wait,
+-                      (atomic_read(&sdp->detaching) ||
+-                      (srp = sg_get_rq_mark(sfp, req_pack_id))));
+-              if (atomic_read(&sdp->detaching)) {
+-                      retval = -ENODEV;
+-                      goto free_old_hdr;
+-              }
+-              if (retval) {
+-                      /* -ERESTARTSYS as signal hit process */
++                      ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) ||
++                      (!busy && atomic_read(&sdp->detaching))));
++              if (!srp) {
++                      /* signal or detaching */
++                      if (!retval)
++                              retval = -ENODEV;
+                       goto free_old_hdr;
+               }
+       }
+@@ -934,9 +929,7 @@ sg_ioctl(struct file *filp, unsigned int
+               if (result < 0)
+                       return result;
+               result = wait_event_interruptible(sfp->read_wait,
+-                      (srp_done(sfp, srp) || atomic_read(&sdp->detaching)));
+-              if (atomic_read(&sdp->detaching))
+-                      return -ENODEV;
++                      srp_done(sfp, srp));
+               write_lock_irq(&sfp->rq_list_lock);
+               if (srp->done) {
+                       srp->done = 2;
+@@ -2096,19 +2089,28 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_reques
+ }
+ static Sg_request *
+-sg_get_rq_mark(Sg_fd * sfp, int pack_id)
++sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy)
+ {
+       Sg_request *resp;
+       unsigned long iflags;
++      *busy = false;
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+       list_for_each_entry(resp, &sfp->rq_list, entry) {
+-              /* look for requests that are ready + not SG_IO owned */
+-              if ((1 == resp->done) && (!resp->sg_io_owned) &&
++              /* look for requests that are not SG_IO owned */
++              if ((!resp->sg_io_owned) &&
+                   ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
+-                      resp->done = 2; /* guard against other readers */
+-                      write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-                      return resp;
++                      switch (resp->done) {
++                      case 0: /* request active */
++                              *busy = true;
++                              break;
++                      case 1: /* request done; response ready to return */
++                              resp->done = 2; /* guard against other readers */
++                              write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++                              return resp;
++                      case 2: /* response already being returned */
++                              break;
++                      }
+               }
+       }
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+@@ -2162,6 +2164,15 @@ sg_remove_request(Sg_fd * sfp, Sg_reques
+               res = 1;
+       }
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++
++      /*
++       * If the device is detaching, wakeup any readers in case we just
++       * removed the last response, which would leave nothing for them to
++       * return other than -ENODEV.
++       */
++      if (unlikely(atomic_read(&sfp->parentdp->detaching)))
++              wake_up_interruptible_all(&sfp->read_wait);
++
+       return res;
+ }