]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 4.9
authorSasha Levin <sashal@kernel.org>
Sun, 19 Jan 2020 17:46:15 +0000 (12:46 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 19 Jan 2020 17:48:25 +0000 (12:48 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.9/scsi-fnic-fix-invalid-stack-access.patch [new file with mode: 0644]
queue-4.9/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch [new file with mode: 0644]
queue-4.9/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch [new file with mode: 0644]
queue-4.9/usb-serial-keyspan-handle-unbound-ports.patch [new file with mode: 0644]

diff --git a/queue-4.9/scsi-fnic-fix-invalid-stack-access.patch b/queue-4.9/scsi-fnic-fix-invalid-stack-access.patch
new file mode 100644 (file)
index 0000000..763309f
--- /dev/null
@@ -0,0 +1,126 @@
+From c4d9b6226f7de0eb685d3a25e42643eeffdecc78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jan 2020 21:15:49 +0100
+Subject: scsi: fnic: fix invalid stack access
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 42ec15ceaea74b5f7a621fc6686cbf69ca66c4cf ]
+
+gcc -O3 warns that some local variables are not properly initialized:
+
+drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_hang_notify':
+drivers/scsi/fnic/vnic_dev.c:511:16: error: 'a0' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[0] = *a0;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:691:6: note: 'a0' was declared here
+  u64 a0, a1;
+      ^~
+drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[1] = *a1;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:691:10: note: 'a1' was declared here
+  u64 a0, a1;
+          ^~
+drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_mac_addr':
+drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[1] = *a1;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:698:10: note: 'a1' was declared here
+  u64 a0, a1;
+          ^~
+
+Apparently the code relies on the local variables occupying adjacent memory
+locations in the same order, but this is of course not guaranteed.
+
+Use an array of two u64 variables where needed to make it work correctly.
+
+I suspect there is also an endianness bug here, but have not digged in deep
+enough to be sure.
+
+Fixes: 5df6d737dd4b ("[SCSI] fnic: Add new Cisco PCI-Express FCoE HBA")
+Fixes: mmtom ("init/Kconfig: enable -O3 for all arches")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200107201602.4096790-1-arnd@arndb.de
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/fnic/vnic_dev.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c
+index ba69d6112fa1..c5b89a003d2a 100644
+--- a/drivers/scsi/fnic/vnic_dev.c
++++ b/drivers/scsi/fnic/vnic_dev.c
+@@ -445,26 +445,26 @@ int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
+ int vnic_dev_hang_notify(struct vnic_dev *vdev)
+ {
+-      u64 a0, a1;
++      u64 a0 = 0, a1 = 0;
+       int wait = 1000;
+       return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
+ }
+ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+ {
+-      u64 a0, a1;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err, i;
+       for (i = 0; i < ETH_ALEN; i++)
+               mac_addr[i] = 0;
+-      err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a[0], &a[1], wait);
+       if (err)
+               return err;
+       for (i = 0; i < ETH_ALEN; i++)
+-              mac_addr[i] = ((u8 *)&a0)[i];
++              mac_addr[i] = ((u8 *)&a)[i];
+       return 0;
+ }
+@@ -489,30 +489,30 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
+ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
+ {
+-      u64 a0 = 0, a1 = 0;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err;
+       int i;
+       for (i = 0; i < ETH_ALEN; i++)
+-              ((u8 *)&a0)[i] = addr[i];
++              ((u8 *)&a)[i] = addr[i];
+-      err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a[0], &a[1], wait);
+       if (err)
+               pr_err("Can't add addr [%pM], %d\n", addr, err);
+ }
+ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+ {
+-      u64 a0 = 0, a1 = 0;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err;
+       int i;
+       for (i = 0; i < ETH_ALEN; i++)
+-              ((u8 *)&a0)[i] = addr[i];
++              ((u8 *)&a)[i] = addr[i];
+-      err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a[0], &a[1], wait);
+       if (err)
+               pr_err("Can't del addr [%pM], %d\n", addr, err);
+ }
+-- 
+2.20.1
+
diff --git a/queue-4.9/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch b/queue-4.9/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch
new file mode 100644 (file)
index 0000000..a1d95cb
--- /dev/null
@@ -0,0 +1,53 @@
+From 39473ad4da90dc08742a144025a1640560bed7d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Oct 2016 20:32:26 +0300
+Subject: scsi: fnic: use kernel's '%pM' format option to print MAC
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 36fe90b0f0bdc9d030e88ba2153f3c8d6b6a5964 ]
+
+Instead of supplying each byte through stack let's use %pM specifier.
+
+Cc: Hiral Patel <hiralpat@cisco.com>
+Cc: Suma Ramars <sramars@cisco.com>
+Acked-by: Tom Tucker <tom@opengridcomputing.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/fnic/vnic_dev.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c
+index 9795d6f3e197..ba69d6112fa1 100644
+--- a/drivers/scsi/fnic/vnic_dev.c
++++ b/drivers/scsi/fnic/vnic_dev.c
+@@ -499,10 +499,7 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
+       err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
+       if (err)
+-              printk(KERN_ERR
+-                      "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
+-                      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
+-                      err);
++              pr_err("Can't add addr [%pM], %d\n", addr, err);
+ }
+ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+@@ -517,10 +514,7 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+       err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
+       if (err)
+-              printk(KERN_ERR
+-                      "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
+-                      addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
+-                      err);
++              pr_err("Can't del addr [%pM], %d\n", addr, err);
+ }
+ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
+-- 
+2.20.1
+
index 771f3d2f9aecdb79e1dcf340c359911b9b9d7728..5b51123ce4cce13ba82b0bd745ed62c0342b68f6 100644 (file)
@@ -68,3 +68,8 @@ perf-report-fix-incorrectly-added-dimensions-as-switch-perf-data-file.patch
 mm-page-writeback.c-avoid-potential-division-by-zero-in-wb_min_max_ratio.patch
 net-stmmac-16kb-buffer-must-be-16-byte-aligned.patch
 net-stmmac-enable-16kb-buffer-size.patch
+usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch
+usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch
+usb-serial-keyspan-handle-unbound-ports.patch
+scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch
+scsi-fnic-fix-invalid-stack-access.patch
diff --git a/queue-4.9/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch b/queue-4.9/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch
new file mode 100644 (file)
index 0000000..a1b214c
--- /dev/null
@@ -0,0 +1,49 @@
+From c7f96779031da71e98aec162dfcd87212be8aa83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:23 +0100
+Subject: USB: serial: io_edgeport: handle unbound ports on URB completion
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit e37d1aeda737a20b1846a91a3da3f8b0f00cf690 ]
+
+Check for NULL port data in the shared interrupt and bulk completion
+callbacks to avoid dereferencing a NULL pointer in case a device sends
+data for a port device which isn't bound to a driver (e.g. due to a
+malicious device having unexpected endpoints or after an allocation
+failure on port probe).
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/io_edgeport.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index b9b56ec6ff24..191588006e0e 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -640,7 +640,7 @@ static void edge_interrupt_callback(struct urb *urb)
+                       if (txCredits) {
+                               port = edge_serial->serial->port[portNumber];
+                               edge_port = usb_get_serial_port_data(port);
+-                              if (edge_port->open) {
++                              if (edge_port && edge_port->open) {
+                                       spin_lock_irqsave(&edge_port->ep_lock,
+                                                         flags);
+                                       edge_port->txCredits += txCredits;
+@@ -1776,7 +1776,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
+                       if (rxLen && edge_serial->rxPort < serial->num_ports) {
+                               port = serial->port[edge_serial->rxPort];
+                               edge_port = usb_get_serial_port_data(port);
+-                              if (edge_port->open) {
++                              if (edge_port && edge_port->open) {
+                                       dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
+                                               __func__, rxLen,
+                                               edge_serial->rxPort);
+-- 
+2.20.1
+
diff --git a/queue-4.9/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch b/queue-4.9/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch
new file mode 100644 (file)
index 0000000..834452b
--- /dev/null
@@ -0,0 +1,99 @@
+From 88a4be4a211f6a83f53c411cd81a693fb5ab4ffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Jun 2018 00:32:06 +0200
+Subject: USB: serial: io_edgeport: use irqsave() in USB's complete callback
+
+From: John Ogness <john.ogness@linutronix.de>
+
+[ Upstream commit dd1fae527612543e560e84f2eba4f6ef2006ac55 ]
+
+The USB completion callback does not disable interrupts while acquiring
+the lock. We want to remove the local_irq_disable() invocation from
+__usb_hcd_giveback_urb() and therefore it is required for the callback
+handler to disable the interrupts while acquiring the lock.
+The callback may be invoked either in IRQ or BH context depending on the
+USB host controller.
+Use the _irqsave() variant of the locking primitives.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/io_edgeport.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index 61671e277bb4..b9b56ec6ff24 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -572,6 +572,7 @@ static void edge_interrupt_callback(struct urb *urb)
+       struct usb_serial_port *port;
+       unsigned char *data = urb->transfer_buffer;
+       int length = urb->actual_length;
++      unsigned long flags;
+       int bytes_avail;
+       int position;
+       int txCredits;
+@@ -603,7 +604,7 @@ static void edge_interrupt_callback(struct urb *urb)
+               if (length > 1) {
+                       bytes_avail = data[0] | (data[1] << 8);
+                       if (bytes_avail) {
+-                              spin_lock(&edge_serial->es_lock);
++                              spin_lock_irqsave(&edge_serial->es_lock, flags);
+                               edge_serial->rxBytesAvail += bytes_avail;
+                               dev_dbg(dev,
+                                       "%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d\n",
+@@ -626,7 +627,8 @@ static void edge_interrupt_callback(struct urb *urb)
+                                               edge_serial->read_in_progress = false;
+                                       }
+                               }
+-                              spin_unlock(&edge_serial->es_lock);
++                              spin_unlock_irqrestore(&edge_serial->es_lock,
++                                                     flags);
+                       }
+               }
+               /* grab the txcredits for the ports if available */
+@@ -639,9 +641,11 @@ static void edge_interrupt_callback(struct urb *urb)
+                               port = edge_serial->serial->port[portNumber];
+                               edge_port = usb_get_serial_port_data(port);
+                               if (edge_port->open) {
+-                                      spin_lock(&edge_port->ep_lock);
++                                      spin_lock_irqsave(&edge_port->ep_lock,
++                                                        flags);
+                                       edge_port->txCredits += txCredits;
+-                                      spin_unlock(&edge_port->ep_lock);
++                                      spin_unlock_irqrestore(&edge_port->ep_lock,
++                                                             flags);
+                                       dev_dbg(dev, "%s - txcredits for port%d = %d\n",
+                                               __func__, portNumber,
+                                               edge_port->txCredits);
+@@ -682,6 +686,7 @@ static void edge_bulk_in_callback(struct urb *urb)
+       int                     retval;
+       __u16                   raw_data_length;
+       int status = urb->status;
++      unsigned long flags;
+       if (status) {
+               dev_dbg(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n",
+@@ -701,7 +706,7 @@ static void edge_bulk_in_callback(struct urb *urb)
+       usb_serial_debug_data(dev, __func__, raw_data_length, data);
+-      spin_lock(&edge_serial->es_lock);
++      spin_lock_irqsave(&edge_serial->es_lock, flags);
+       /* decrement our rxBytes available by the number that we just got */
+       edge_serial->rxBytesAvail -= raw_data_length;
+@@ -725,7 +730,7 @@ static void edge_bulk_in_callback(struct urb *urb)
+               edge_serial->read_in_progress = false;
+       }
+-      spin_unlock(&edge_serial->es_lock);
++      spin_unlock_irqrestore(&edge_serial->es_lock, flags);
+ }
+-- 
+2.20.1
+
diff --git a/queue-4.9/usb-serial-keyspan-handle-unbound-ports.patch b/queue-4.9/usb-serial-keyspan-handle-unbound-ports.patch
new file mode 100644 (file)
index 0000000..2962201
--- /dev/null
@@ -0,0 +1,49 @@
+From 5447abb1ee9133ff1af255dda88c795b80569e6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:25 +0100
+Subject: USB: serial: keyspan: handle unbound ports
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 3018dd3fa114b13261e9599ddb5656ef97a1fa17 ]
+
+Check for NULL port data in the control URB completion handlers to avoid
+dereferencing a NULL pointer in the unlikely case where a port device
+isn't bound to a driver (e.g. after an allocation failure on port
+probe()).
+
+Fixes: 0ca1268e109a ("USB Serial Keyspan: add support for USA-49WG & USA-28XG")
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/keyspan.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index 185ef1d8c6cd..e08755e9b612 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -567,6 +567,8 @@ static void        usa49_glocont_callback(struct urb *urb)
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               p_priv = usb_get_serial_port_data(port);
++              if (!p_priv)
++                      continue;
+               if (p_priv->resend_cont) {
+                       dev_dbg(&port->dev, "%s - sending setup\n", __func__);
+@@ -968,6 +970,8 @@ static void usa67_glocont_callback(struct urb *urb)
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               p_priv = usb_get_serial_port_data(port);
++              if (!p_priv)
++                      continue;
+               if (p_priv->resend_cont) {
+                       dev_dbg(&port->dev, "%s - sending setup\n", __func__);
+-- 
+2.20.1
+