From: Sasha Levin Date: Sun, 19 Jan 2020 17:46:16 +0000 (-0500) Subject: fixes for 4.4 X-Git-Tag: v4.4.211~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=79f7d3f57d6578d07a68e59839c06bc2497571d5;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 4.4 Signed-off-by: Sasha Levin --- diff --git a/queue-4.4/scsi-fnic-fix-invalid-stack-access.patch b/queue-4.4/scsi-fnic-fix-invalid-stack-access.patch new file mode 100644 index 00000000000..784d4d28cfd --- /dev/null +++ b/queue-4.4/scsi-fnic-fix-invalid-stack-access.patch @@ -0,0 +1,126 @@ +From 8f133b3e3dbc2417e46a78c424e607efb7f6715a 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.4/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch b/queue-4.4/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch new file mode 100644 index 00000000000..3e7193ab269 --- /dev/null +++ b/queue-4.4/scsi-fnic-use-kernel-s-pm-format-option-to-print-mac.patch @@ -0,0 +1,53 @@ +From 7e24fba51765cb12e751cc2d2e5a890c0eea648e 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.4/series b/queue-4.4/series index 55a6a55c3b3..3251e39cc55 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -52,3 +52,8 @@ x86-efistub-disable-paging-at-mixed-mode-entry.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.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch b/queue-4.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch new file mode 100644 index 00000000000..0b559c5bfb7 --- /dev/null +++ b/queue-4.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-c.patch @@ -0,0 +1,49 @@ +From a47e1745c2184ddb2d6bce4d324064dd94e5eb2b 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 1995e6306b88..75c60e74438d 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; +@@ -1780,7 +1780,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.4/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch b/queue-4.4/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch new file mode 100644 index 00000000000..1f22cbfaf54 --- /dev/null +++ b/queue-4.4/usb-serial-io_edgeport-use-irqsave-in-usb-s-complete.patch @@ -0,0 +1,99 @@ +From 6c5fbede40a79e44c6781136ee7014721fb0ca06 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 4db280e6fac9..1995e6306b88 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.4/usb-serial-keyspan-handle-unbound-ports.patch b/queue-4.4/usb-serial-keyspan-handle-unbound-ports.patch new file mode 100644 index 00000000000..0cd08011ed6 --- /dev/null +++ b/queue-4.4/usb-serial-keyspan-handle-unbound-ports.patch @@ -0,0 +1,49 @@ +From 6c33ed458eb723934deeb9a299b55375abef24c8 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 38112be0dbae..a79e9adf4e53 100644 +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -565,6 +565,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__); +@@ -962,6 +964,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 +