From bb4f8348ab5ae293336defea0b2ba5177ab747ae Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 19 Jan 2020 12:46:15 -0500 Subject: [PATCH] fixes for 4.9 Signed-off-by: Sasha Levin --- .../scsi-fnic-fix-invalid-stack-access.patch | 126 ++++++++++++++++++ ...rnel-s-pm-format-option-to-print-mac.patch | 53 ++++++++ queue-4.9/series | 5 + ...geport-handle-unbound-ports-on-urb-c.patch | 49 +++++++ ...geport-use-irqsave-in-usb-s-complete.patch | 99 ++++++++++++++ ...-serial-keyspan-handle-unbound-ports.patch | 49 +++++++ 6 files changed, 381 insertions(+) create mode 100644 queue-4.9/scsi-fnic-fix-invalid-stack-access.patch create mode 100644 queue-4.9/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch create mode 100644 queue-4.9/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch create mode 100644 queue-4.9/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch create mode 100644 queue-4.9/usb-serial-keyspan-handle-unbound-ports.patch 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 index 00000000000..763309fbd51 --- /dev/null +++ b/queue-4.9/scsi-fnic-fix-invalid-stack-access.patch @@ -0,0 +1,126 @@ +From c4d9b6226f7de0eb685d3a25e42643eeffdecc78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jan 2020 21:15:49 +0100 +Subject: scsi: fnic: fix invalid stack access + +From: Arnd Bergmann + +[ 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 +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a1d95cb717d --- /dev/null +++ b/queue-4.9/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch @@ -0,0 +1,53 @@ +From 39473ad4da90dc08742a144025a1640560bed7d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2016 20:32:26 +0300 +Subject: scsi: fnic: use kernel's '%pM' format option to print MAC + +From: Andy Shevchenko + +[ Upstream commit 36fe90b0f0bdc9d030e88ba2153f3c8d6b6a5964 ] + +Instead of supplying each byte through stack let's use %pM specifier. + +Cc: Hiral Patel +Cc: Suma Ramars +Acked-by: Tom Tucker +Signed-off-by: Andy Shevchenko +Reviewed-by: Ewan D. Milne +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-4.9/series b/queue-4.9/series index 771f3d2f9ae..5b51123ce4c 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 index 00000000000..a1b214ca0b8 --- /dev/null +++ b/queue-4.9/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch @@ -0,0 +1,49 @@ +From c7f96779031da71e98aec162dfcd87212be8aa83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2020 10:50:23 +0100 +Subject: USB: serial: io_edgeport: handle unbound ports on URB completion + +From: Johan Hovold + +[ 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 +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..834452b17eb --- /dev/null +++ b/queue-4.9/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch @@ -0,0 +1,99 @@ +From 88a4be4a211f6a83f53c411cd81a693fb5ab4ffc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Jun 2018 00:32:06 +0200 +Subject: USB: serial: io_edgeport: use irqsave() in USB's complete callback + +From: John Ogness + +[ 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 +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2962201590b --- /dev/null +++ b/queue-4.9/usb-serial-keyspan-handle-unbound-ports.patch @@ -0,0 +1,49 @@ +From 5447abb1ee9133ff1af255dda88c795b80569e6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2020 10:50:25 +0100 +Subject: USB: serial: keyspan: handle unbound ports + +From: Johan Hovold + +[ 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 +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + 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 + -- 2.47.3