From: Greg Kroah-Hartman Date: Thu, 3 Aug 2017 22:43:56 +0000 (-0700) Subject: 3.18-stable patches X-Git-Tag: v4.12.5~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57d425744b1bb4de61ea4811e6d675b5761c2199;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch ipv6-fix-possible-deadlock-in-ip6_fl_purge-ip6_fl_gc.patch isdn-fix-a-sleep-in-atomic-bug.patch isdn-i4l-fix-buffer-overflow.patch kaweth-fix-firmware-download.patch kaweth-fix-oops-upon-failed-memory-allocation.patch mailbox-always-wait-in-mbox_send_message-for-blocking-tx-mode.patch mailbox-handle-empty-message-in-tx_tick.patch mailbox-skip-complete-wait-event-if-timer-expired.patch mpt3sas-don-t-overreach-ioc-reply_post-during-initialization.patch net-sched-fix-soft-lockup-in-tc_classify.patch net-sctp-fix-race-for-one-to-many-sockets-in-sendmsg-s-auto-associate.patch sh_eth-fix-ethtool-operation-crash-when-net-device-is-down.patch string-provide-strscpy.patch strscpy-zero-any-trailing-garbage-bytes-in-the-destination.patch wil6210-fix-deadlock-when-using-fw_no_recovery-option.patch --- diff --git a/queue-3.18/ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch b/queue-3.18/ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch new file mode 100644 index 00000000000..23206c70ec5 --- /dev/null +++ b/queue-3.18/ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch @@ -0,0 +1,43 @@ +From 860f01e96981a68553f3ca49f574ff14fe955e72 Mon Sep 17 00:00:00 2001 +From: Valentin Vidic +Date: Fri, 5 May 2017 21:07:33 +0200 +Subject: ipmi/watchdog: fix watchdog timeout set on reboot + +From: Valentin Vidic + +commit 860f01e96981a68553f3ca49f574ff14fe955e72 upstream. + +systemd by default starts watchdog on reboot and sets the timer to +ShutdownWatchdogSec=10min. Reboot handler in ipmi_watchdog than reduces +the timer to 120s which is not enough time to boot a Xen machine with +a lot of RAM. As a result the machine is rebooted the second time +during the long run of (XEN) Scrubbing Free RAM..... + +Fix this by setting the timer to 120s only if it was previously +set to a low value. + +Signed-off-by: Valentin Vidic +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_watchdog.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/char/ipmi/ipmi_watchdog.c ++++ b/drivers/char/ipmi/ipmi_watchdog.c +@@ -1156,10 +1156,11 @@ static int wdog_reboot_handler(struct no + ipmi_watchdog_state = WDOG_TIMEOUT_NONE; + ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); + } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { +- /* Set a long timer to let the reboot happens, but +- reboot if it hangs, but only if the watchdog ++ /* Set a long timer to let the reboot happen or ++ reset if it hangs, but only if the watchdog + timer was already running. */ +- timeout = 120; ++ if (timeout < 120) ++ timeout = 120; + pretimeout = 0; + ipmi_watchdog_state = WDOG_TIMEOUT_RESET; + ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); diff --git a/queue-3.18/ipv6-fix-possible-deadlock-in-ip6_fl_purge-ip6_fl_gc.patch b/queue-3.18/ipv6-fix-possible-deadlock-in-ip6_fl_purge-ip6_fl_gc.patch new file mode 100644 index 00000000000..32e1c8c9674 --- /dev/null +++ b/queue-3.18/ipv6-fix-possible-deadlock-in-ip6_fl_purge-ip6_fl_gc.patch @@ -0,0 +1,76 @@ +From 4762fb980465463734f02c67c67f40beb8903f73 Mon Sep 17 00:00:00 2001 +From: Jan Stancek +Date: Wed, 11 Feb 2015 14:06:23 +0100 +Subject: ipv6: fix possible deadlock in ip6_fl_purge / ip6_fl_gc + +From: Jan Stancek + +commit 4762fb980465463734f02c67c67f40beb8903f73 upstream. + +Use spin_lock_bh in ip6_fl_purge() to prevent following potentially +deadlock scenario between ip6_fl_purge() and ip6_fl_gc() timer. + + ================================= + [ INFO: inconsistent lock state ] + 3.19.0 #1 Not tainted + --------------------------------- + inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. + swapper/5/0 [HC0[0]:SC1[1]:HE1:SE0] takes: + (ip6_fl_lock){+.?...}, at: [] ip6_fl_gc+0x2d/0x180 + {SOFTIRQ-ON-W} state was registered at: + [] __lock_acquire+0x4a0/0x10b0 + [] lock_acquire+0xc4/0x2b0 + [] _raw_spin_lock+0x3d/0x80 + [] ip6_flowlabel_net_exit+0x28/0x110 + [] ops_exit_list.isra.1+0x39/0x60 + [] cleanup_net+0x100/0x1e0 + [] process_one_work+0x20a/0x830 + [] worker_thread+0x11b/0x460 + [] kthread+0x104/0x120 + [] ret_from_fork+0x7c/0xb0 + irq event stamp: 84640 + hardirqs last enabled at (84640): [] _raw_spin_unlock_irq+0x30/0x50 + hardirqs last disabled at (84639): [] _raw_spin_lock_irq+0x1f/0x80 + softirqs last enabled at (84628): [] _local_bh_enable+0x21/0x50 + softirqs last disabled at (84629): [] irq_exit+0x12d/0x150 + + other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(ip6_fl_lock); + + lock(ip6_fl_lock); + + *** DEADLOCK *** + +Signed-off-by: Jan Stancek +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/ip6_flowlabel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_flowlabel.c ++++ b/net/ipv6/ip6_flowlabel.c +@@ -172,7 +172,7 @@ static void __net_exit ip6_fl_purge(stru + { + int i; + +- spin_lock(&ip6_fl_lock); ++ spin_lock_bh(&ip6_fl_lock); + for (i = 0; i <= FL_HASH_MASK; i++) { + struct ip6_flowlabel *fl; + struct ip6_flowlabel __rcu **flp; +@@ -190,7 +190,7 @@ static void __net_exit ip6_fl_purge(stru + flp = &fl->next; + } + } +- spin_unlock(&ip6_fl_lock); ++ spin_unlock_bh(&ip6_fl_lock); + } + + static struct ip6_flowlabel *fl_intern(struct net *net, diff --git a/queue-3.18/isdn-fix-a-sleep-in-atomic-bug.patch b/queue-3.18/isdn-fix-a-sleep-in-atomic-bug.patch new file mode 100644 index 00000000000..307b7194c84 --- /dev/null +++ b/queue-3.18/isdn-fix-a-sleep-in-atomic-bug.patch @@ -0,0 +1,40 @@ +From e8f4ae85439f34bec3b0ab69223a41809dab28c9 Mon Sep 17 00:00:00 2001 +From: Jia-Ju Bai +Date: Wed, 31 May 2017 09:40:11 +0800 +Subject: isdn: Fix a sleep-in-atomic bug + +From: Jia-Ju Bai + +commit e8f4ae85439f34bec3b0ab69223a41809dab28c9 upstream. + +The driver may sleep under a spin lock, the function call path is: +isdn_ppp_mp_receive (acquire the lock) + isdn_ppp_mp_reassembly + isdn_ppp_push_higher + isdn_ppp_decompress + isdn_ppp_ccp_reset_trans + isdn_ppp_ccp_reset_alloc_state + kzalloc(GFP_KERNEL) --> may sleep + +To fixed it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". + +Signed-off-by: Jia-Ju Bai +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/isdn/i4l/isdn_ppp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/isdn/i4l/isdn_ppp.c ++++ b/drivers/isdn/i4l/isdn_ppp.c +@@ -2364,7 +2364,7 @@ static struct ippp_ccp_reset_state *isdn + id); + return NULL; + } else { +- rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL); ++ rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_ATOMIC); + if (!rs) + return NULL; + rs->state = CCPResetIdle; diff --git a/queue-3.18/isdn-i4l-fix-buffer-overflow.patch b/queue-3.18/isdn-i4l-fix-buffer-overflow.patch new file mode 100644 index 00000000000..0a9d0b080eb --- /dev/null +++ b/queue-3.18/isdn-i4l-fix-buffer-overflow.patch @@ -0,0 +1,53 @@ +From 9f5af546e6acc30f075828cb58c7f09665033967 Mon Sep 17 00:00:00 2001 +From: Annie Cherkaev +Date: Sat, 15 Jul 2017 15:08:58 -0600 +Subject: isdn/i4l: fix buffer overflow + +From: Annie Cherkaev + +commit 9f5af546e6acc30f075828cb58c7f09665033967 upstream. + +This fixes a potential buffer overflow in isdn_net.c caused by an +unbounded strcpy. + +[ ISDN seems to be effectively unmaintained, and the I4L driver in + particular is long deprecated, but in case somebody uses this.. + - Linus ] + +Signed-off-by: Jiten Thakkar +Signed-off-by: Annie Cherkaev +Cc: Karsten Keil +Cc: Kees Cook +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/isdn/i4l/isdn_common.c | 1 + + drivers/isdn/i4l/isdn_net.c | 5 ++--- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/isdn/i4l/isdn_common.c ++++ b/drivers/isdn/i4l/isdn_common.c +@@ -1379,6 +1379,7 @@ isdn_ioctl(struct file *file, uint cmd, + if (arg) { + if (copy_from_user(bname, argp, sizeof(bname) - 1)) + return -EFAULT; ++ bname[sizeof(bname)-1] = 0; + } else + return -EINVAL; + ret = mutex_lock_interruptible(&dev->mtx); +--- a/drivers/isdn/i4l/isdn_net.c ++++ b/drivers/isdn/i4l/isdn_net.c +@@ -2644,10 +2644,9 @@ isdn_net_newslave(char *parm) + char newname[10]; + + if (p) { +- /* Slave-Name MUST not be empty */ +- if (!strlen(p + 1)) ++ /* Slave-Name MUST not be empty or overflow 'newname' */ ++ if (strscpy(newname, p + 1, sizeof(newname)) <= 0) + return NULL; +- strcpy(newname, p + 1); + *p = 0; + /* Master must already exist */ + if (!(n = isdn_net_findif(parm))) diff --git a/queue-3.18/kaweth-fix-firmware-download.patch b/queue-3.18/kaweth-fix-firmware-download.patch new file mode 100644 index 00000000000..39bd30c4977 --- /dev/null +++ b/queue-3.18/kaweth-fix-firmware-download.patch @@ -0,0 +1,40 @@ +From 60bcabd080f53561efa9288be45c128feda1a8bb Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 17 Aug 2016 15:51:55 +0200 +Subject: kaweth: fix firmware download + +From: Oliver Neukum + +commit 60bcabd080f53561efa9288be45c128feda1a8bb upstream. + +This fixes the oops discovered by the Umap2 project and Alan Stern. +The intf member needs to be set before the firmware is downloaded. + +Signed-off-by: Oliver Neukum +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/kaweth.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -1029,6 +1029,7 @@ static int kaweth_probe( + kaweth = netdev_priv(netdev); + kaweth->dev = udev; + kaweth->net = netdev; ++ kaweth->intf = intf; + + spin_lock_init(&kaweth->device_lock); + init_waitqueue_head(&kaweth->term_wait); +@@ -1139,8 +1140,6 @@ err_fw: + + dev_dbg(dev, "Initializing net device.\n"); + +- kaweth->intf = intf; +- + kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!kaweth->tx_urb) + goto err_free_netdev; diff --git a/queue-3.18/kaweth-fix-oops-upon-failed-memory-allocation.patch b/queue-3.18/kaweth-fix-oops-upon-failed-memory-allocation.patch new file mode 100644 index 00000000000..f9d1518040d --- /dev/null +++ b/queue-3.18/kaweth-fix-oops-upon-failed-memory-allocation.patch @@ -0,0 +1,50 @@ +From 575ced7f8090c1a4e91e2daf8da9352a6a1fc7a7 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 17 Aug 2016 15:51:56 +0200 +Subject: kaweth: fix oops upon failed memory allocation + +From: Oliver Neukum + +commit 575ced7f8090c1a4e91e2daf8da9352a6a1fc7a7 upstream. + +Just return an error upon failure. + +Signed-off-by: Oliver Neukum +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/kaweth.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -1009,6 +1009,7 @@ static int kaweth_probe( + struct net_device *netdev; + const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + int result = 0; ++ int rv = -EIO; + + dev_dbg(dev, + "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n", +@@ -1049,6 +1050,10 @@ static int kaweth_probe( + /* Download the firmware */ + dev_info(dev, "Downloading firmware...\n"); + kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); ++ if (!kaweth->firmware_buf) { ++ rv = -ENOMEM; ++ goto err_free_netdev; ++ } + if ((result = kaweth_download_firmware(kaweth, + "kaweth/new_code.bin", + 100, +@@ -1209,7 +1214,7 @@ err_only_tx: + err_free_netdev: + free_netdev(netdev); + +- return -EIO; ++ return rv; + } + + /**************************************************************** diff --git a/queue-3.18/mailbox-always-wait-in-mbox_send_message-for-blocking-tx-mode.patch b/queue-3.18/mailbox-always-wait-in-mbox_send_message-for-blocking-tx-mode.patch new file mode 100644 index 00000000000..d6178461593 --- /dev/null +++ b/queue-3.18/mailbox-always-wait-in-mbox_send_message-for-blocking-tx-mode.patch @@ -0,0 +1,40 @@ +From c61b781ee084e69855477d23dd33e7e6caad652c Mon Sep 17 00:00:00 2001 +From: Sudeep Holla +Date: Tue, 21 Mar 2017 11:30:14 +0000 +Subject: mailbox: always wait in mbox_send_message for blocking Tx mode + +From: Sudeep Holla + +commit c61b781ee084e69855477d23dd33e7e6caad652c upstream. + +There exists a race when msg_submit return immediately as there was an +active request being processed which may have completed just before it's +checked again in mbox_send_message. This will result in return to the +caller without waiting in mbox_send_message even when it's blocking Tx. + +This patch fixes the issue by waiting for the completion always if Tx +is in blocking mode. + +Fixes: 2b6d83e2b8b7 ("mailbox: Introduce framework for mailbox") +Reported-by: Alexey Klimov +Signed-off-by: Sudeep Holla +Reviewed-by: Alexey Klimov +Signed-off-by: Jassi Brar +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mailbox/mailbox.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -255,7 +255,7 @@ int mbox_send_message(struct mbox_chan * + if (chan->txdone_method == TXDONE_BY_POLL) + poll_txdone((unsigned long)chan->mbox); + +- if (chan->cl->tx_block && chan->active_req) { ++ if (chan->cl->tx_block) { + unsigned long wait; + int ret; + diff --git a/queue-3.18/mailbox-handle-empty-message-in-tx_tick.patch b/queue-3.18/mailbox-handle-empty-message-in-tx_tick.patch new file mode 100644 index 00000000000..c4204e5397a --- /dev/null +++ b/queue-3.18/mailbox-handle-empty-message-in-tx_tick.patch @@ -0,0 +1,40 @@ +From cb710ab1d8a23f68ff8f45aedf3e552bb90e70de Mon Sep 17 00:00:00 2001 +From: Sudeep Holla +Date: Tue, 21 Mar 2017 11:30:16 +0000 +Subject: mailbox: handle empty message in tx_tick + +From: Sudeep Holla + +commit cb710ab1d8a23f68ff8f45aedf3e552bb90e70de upstream. + +We already check if the message is empty before calling the client +tx_done callback. Calling completion on a wait event is also invalid +if the message is empty. + +This patch moves the existing empty message check earlier. + +Fixes: 2b6d83e2b8b7 ("mailbox: Introduce framework for mailbox") +Signed-off-by: Sudeep Holla +Signed-off-by: Jassi Brar +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mailbox/mailbox.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -99,8 +99,11 @@ static void tx_tick(struct mbox_chan *ch + /* Submit next message */ + msg_submit(chan); + ++ if (!mssg) ++ return; ++ + /* Notify the client */ +- if (mssg && chan->cl->tx_done) ++ if (chan->cl->tx_done) + chan->cl->tx_done(chan->cl, mssg, r); + + if (r != -ETIME && chan->cl->tx_block) diff --git a/queue-3.18/mailbox-skip-complete-wait-event-if-timer-expired.patch b/queue-3.18/mailbox-skip-complete-wait-event-if-timer-expired.patch new file mode 100644 index 00000000000..9448731fee4 --- /dev/null +++ b/queue-3.18/mailbox-skip-complete-wait-event-if-timer-expired.patch @@ -0,0 +1,53 @@ +From cc6eeaa3029a6dbcb4ad41b1f92876483bd88965 Mon Sep 17 00:00:00 2001 +From: Sudeep Holla +Date: Tue, 21 Mar 2017 11:30:15 +0000 +Subject: mailbox: skip complete wait event if timer expired + +From: Sudeep Holla + +commit cc6eeaa3029a6dbcb4ad41b1f92876483bd88965 upstream. + +If a wait_for_completion_timeout() call returns due to a timeout, +complete() can get called after returning from the wait which is +incorrect and can cause subsequent transmissions on a channel to fail. +Since the wait_for_completion_timeout() sees the completion variable +is non-zero caused by the erroneous/spurious complete() call, and +it immediately returns without waiting for the time as expected by the +client. + +This patch fixes the issue by skipping complete() call for the timer +expiry. + +Fixes: 2b6d83e2b8b7 ("mailbox: Introduce framework for mailbox") +Reported-by: Alexey Klimov +Signed-off-by: Sudeep Holla +Signed-off-by: Jassi Brar +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mailbox/mailbox.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -103,7 +103,7 @@ static void tx_tick(struct mbox_chan *ch + if (mssg && chan->cl->tx_done) + chan->cl->tx_done(chan->cl, mssg, r); + +- if (chan->cl->tx_block) ++ if (r != -ETIME && chan->cl->tx_block) + complete(&chan->tx_complete); + } + +@@ -266,8 +266,8 @@ int mbox_send_message(struct mbox_chan * + + ret = wait_for_completion_timeout(&chan->tx_complete, wait); + if (ret == 0) { +- t = -EIO; +- tx_tick(chan, -EIO); ++ t = -ETIME; ++ tx_tick(chan, t); + } + } + diff --git a/queue-3.18/mpt3sas-don-t-overreach-ioc-reply_post-during-initialization.patch b/queue-3.18/mpt3sas-don-t-overreach-ioc-reply_post-during-initialization.patch new file mode 100644 index 00000000000..2b7795523b6 --- /dev/null +++ b/queue-3.18/mpt3sas-don-t-overreach-ioc-reply_post-during-initialization.patch @@ -0,0 +1,120 @@ +From 5ec8a1753bc29efa7e4b1391d691c9c719b30257 Mon Sep 17 00:00:00 2001 +From: Calvin Owens +Date: Fri, 18 Mar 2016 12:45:42 -0700 +Subject: mpt3sas: Don't overreach ioc->reply_post[] during initialization + +From: Calvin Owens + +commit 5ec8a1753bc29efa7e4b1391d691c9c719b30257 upstream. + +In _base_make_ioc_operational(), we walk ioc->reply_queue_list and pull +a pointer out of successive elements of ioc->reply_post[] for each entry +in that list if RDPQ is enabled. + +Since the code pulls the pointer for the next iteration at the bottom of +the loop, it triggers the a KASAN dump on the final iteration: + + BUG: KASAN: slab-out-of-bounds in _base_make_ioc_operational+0x47b7/0x47e0 [mpt3sas] at addr ffff880754816ab0 + Read of size 8 by task modprobe/305 + + Call Trace: + [] dump_stack+0x4d/0x6c + [] print_trailer+0xf9/0x150 + [] object_err+0x34/0x40 + [] kasan_report_error+0x221/0x530 + [] __asan_report_load8_noabort+0x43/0x50 + [] _base_make_ioc_operational+0x47b7/0x47e0 [mpt3sas] + [] mpt3sas_base_attach+0x1991/0x2120 [mpt3sas] + [] _scsih_probe+0xeb3/0x16b0 [mpt3sas] + [] local_pci_probe+0xc7/0x170 + [] pci_device_probe+0x20f/0x290 + [] really_probe+0x17d/0x600 + [] __driver_attach+0x153/0x190 + [] bus_for_each_dev+0x11c/0x1a0 + [] driver_attach+0x3d/0x50 + [] bus_add_driver+0x44a/0x5f0 + [] driver_register+0x18c/0x3b0 + [] __pci_register_driver+0x156/0x200 + [] _mpt3sas_init+0x135/0x1000 [mpt3sas] + [] do_one_initcall+0x113/0x2b0 + [] do_init_module+0x1d0/0x4d8 + [] load_module+0x6729/0x8dc0 + [] SYSC_init_module+0x183/0x1a0 + [] SyS_init_module+0xe/0x10 + [] entry_SYSCALL_64_fastpath+0x12/0x6a + +Fix this by pulling the value at the beginning of the loop. + +Signed-off-by: Calvin Owens +Reviewed-by: Johannes Thumshirn +Reviewed-by: Jens Axboe +Acked-by: Chaitra Basappa +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 33 ++++++++++++++++----------------- + 1 file changed, 16 insertions(+), 17 deletions(-) + +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -4378,14 +4378,13 @@ _base_make_ioc_ready(struct MPT3SAS_ADAP + static int + _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) + { +- int r, i; ++ int r, i, index; + unsigned long flags; + u32 reply_address; + u16 smid; + struct _tr_list *delayed_tr, *delayed_tr_next; + struct adapter_reply_queue *reply_q; +- long reply_post_free; +- u32 reply_post_free_sz, index = 0; ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free_contig; + + dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, + __func__)); +@@ -4456,27 +4455,27 @@ _base_make_ioc_operational(struct MPT3SA + _base_assign_reply_queues(ioc); + + /* initialize Reply Post Free Queue */ +- reply_post_free_sz = ioc->reply_post_queue_depth * +- sizeof(Mpi2DefaultReplyDescriptor_t); +- reply_post_free = (long)ioc->reply_post[index].reply_post_free; ++ index = 0; ++ reply_post_free_contig = ioc->reply_post[0].reply_post_free; + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ /* ++ * If RDPQ is enabled, switch to the next allocation. ++ * Otherwise advance within the contiguous region. ++ */ ++ if (ioc->rdpq_array_enable) { ++ reply_q->reply_post_free = ++ ioc->reply_post[index++].reply_post_free; ++ } else { ++ reply_q->reply_post_free = reply_post_free_contig; ++ reply_post_free_contig += ioc->reply_post_queue_depth; ++ } ++ + reply_q->reply_post_host_index = 0; +- reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) +- reply_post_free; + for (i = 0; i < ioc->reply_post_queue_depth; i++) + reply_q->reply_post_free[i].Words = + cpu_to_le64(ULLONG_MAX); + if (!_base_is_controller_msix_enabled(ioc)) + goto skip_init_reply_post_free_queue; +- /* +- * If RDPQ is enabled, switch to the next allocation. +- * Otherwise advance within the contiguous region. +- */ +- if (ioc->rdpq_array_enable) +- reply_post_free = (long) +- ioc->reply_post[++index].reply_post_free; +- else +- reply_post_free += reply_post_free_sz; + } + skip_init_reply_post_free_queue: + diff --git a/queue-3.18/net-sched-fix-soft-lockup-in-tc_classify.patch b/queue-3.18/net-sched-fix-soft-lockup-in-tc_classify.patch new file mode 100644 index 00000000000..f4f8260e6a7 --- /dev/null +++ b/queue-3.18/net-sched-fix-soft-lockup-in-tc_classify.patch @@ -0,0 +1,82 @@ +From 628185cfddf1dfb701c4efe2cfd72cf5b09f5702 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 21 Dec 2016 18:04:11 +0100 +Subject: net, sched: fix soft lockup in tc_classify + +From: Daniel Borkmann + +commit 628185cfddf1dfb701c4efe2cfd72cf5b09f5702 upstream. + +Shahar reported a soft lockup in tc_classify(), where we run into an +endless loop when walking the classifier chain due to tp->next == tp +which is a state we should never run into. The issue only seems to +trigger under load in the tc control path. + +What happens is that in tc_ctl_tfilter(), thread A allocates a new +tp, initializes it, sets tp_created to 1, and calls into tp->ops->change() +with it. In that classifier callback we had to unlock/lock the rtnl +mutex and returned with -EAGAIN. One reason why we need to drop there +is, for example, that we need to request an action module to be loaded. + +This happens via tcf_exts_validate() -> tcf_action_init/_1() meaning +after we loaded and found the requested action, we need to redo the +whole request so we don't race against others. While we had to unlock +rtnl in that time, thread B's request was processed next on that CPU. +Thread B added a new tp instance successfully to the classifier chain. +When thread A returned grabbing the rtnl mutex again, propagating -EAGAIN +and destroying its tp instance which never got linked, we goto replay +and redo A's request. + +This time when walking the classifier chain in tc_ctl_tfilter() for +checking for existing tp instances we had a priority match and found +the tp instance that was created and linked by thread B. Now calling +again into tp->ops->change() with that tp was successful and returned +without error. + +tp_created was never cleared in the second round, thus kernel thinks +that we need to link it into the classifier chain (once again). tp and +*back point to the same object due to the match we had earlier on. Thus +for thread B's already public tp, we reset tp->next to tp itself and +link it into the chain, which eventually causes the mentioned endless +loop in tc_classify() once a packet hits the data path. + +Fix is to clear tp_created at the beginning of each request, also when +we replay it. On the paths that can cause -EAGAIN we already destroy +the original tp instance we had and on replay we really need to start +from scratch. It seems that this issue was first introduced in commit +12186be7d2e1 ("net_cls: fix unconfigured struct tcf_proto keeps chaining +and avoid kernel panic when we use cls_cgroup"). + +Fixes: 12186be7d2e1 ("net_cls: fix unconfigured struct tcf_proto keeps chaining and avoid kernel panic when we use cls_cgroup") +Reported-by: Shahar Klein +Signed-off-by: Daniel Borkmann +Cc: Cong Wang +Acked-by: Eric Dumazet +Tested-by: Shahar Klein +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/cls_api.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -137,13 +137,15 @@ static int tc_ctl_tfilter(struct sk_buff + unsigned long cl; + unsigned long fh; + int err; +- int tp_created = 0; ++ int tp_created; + + if ((n->nlmsg_type != RTM_GETTFILTER) && + !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + + replay: ++ tp_created = 0; ++ + err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL); + if (err < 0) + return err; diff --git a/queue-3.18/net-sctp-fix-race-for-one-to-many-sockets-in-sendmsg-s-auto-associate.patch b/queue-3.18/net-sctp-fix-race-for-one-to-many-sockets-in-sendmsg-s-auto-associate.patch new file mode 100644 index 00000000000..19ed416db9b --- /dev/null +++ b/queue-3.18/net-sctp-fix-race-for-one-to-many-sockets-in-sendmsg-s-auto-associate.patch @@ -0,0 +1,118 @@ +From 2061dcd6bff8b774b4fac8b0739b6be3f87bc9f2 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Thu, 15 Jan 2015 16:34:35 +0100 +Subject: net: sctp: fix race for one-to-many sockets in sendmsg's auto associate + +From: Daniel Borkmann + +commit 2061dcd6bff8b774b4fac8b0739b6be3f87bc9f2 upstream. + +I.e. one-to-many sockets in SCTP are not required to explicitly +call into connect(2) or sctp_connectx(2) prior to data exchange. +Instead, they can directly invoke sendmsg(2) and the SCTP stack +will automatically trigger connection establishment through 4WHS +via sctp_primitive_ASSOCIATE(). However, this in its current +implementation is racy: INIT is being sent out immediately (as +it cannot be bundled anyway) and the rest of the DATA chunks are +queued up for later xmit when connection is established, meaning +sendmsg(2) will return successfully. This behaviour can result +in an undesired side-effect that the kernel made the application +think the data has already been transmitted, although none of it +has actually left the machine, worst case even after close(2)'ing +the socket. + +Instead, when the association from client side has been shut down +e.g. first gracefully through SCTP_EOF and then close(2), the +client could afterwards still receive the server's INIT_ACK due +to a connection with higher latency. This INIT_ACK is then considered +out of the blue and hence responded with ABORT as there was no +alive assoc found anymore. This can be easily reproduced f.e. +with sctp_test application from lksctp. One way to fix this race +is to wait for the handshake to actually complete. + +The fix defers waiting after sctp_primitive_ASSOCIATE() and +sctp_primitive_SEND() succeeded, so that DATA chunks cooked up +from sctp_sendmsg() have already been placed into the output +queue through the side-effect interpreter, and therefore can then +be bundeled together with COOKIE_ECHO control chunks. + +strace from example application (shortened): + +socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 3 +sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, + msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 +sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, + msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 +sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, + msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 +sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, + msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 +sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, + msg_iov(0)=[], msg_controllen=48, {cmsg_len=48, cmsg_level=0x84 /* SOL_??? */, cmsg_type=, ...}, + msg_flags=0}, 0) = 0 // graceful shutdown for SOCK_SEQPACKET via SCTP_EOF +close(3) = 0 + +tcpdump before patch (fooling the application): + +22:33:36.306142 IP 192.168.1.114.41462 > 192.168.1.115.8888: sctp (1) [INIT] [init tag: 3879023686] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 3139201684] +22:33:36.316619 IP 192.168.1.115.8888 > 192.168.1.114.41462: sctp (1) [INIT ACK] [init tag: 3345394793] [rwnd: 106496] [OS: 10] [MIS: 10] [init TSN: 3380109591] +22:33:36.317600 IP 192.168.1.114.41462 > 192.168.1.115.8888: sctp (1) [ABORT] + +tcpdump after patch: + +14:28:58.884116 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [INIT] [init tag: 438593213] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 3092969729] +14:28:58.888414 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [INIT ACK] [init tag: 381429855] [rwnd: 106496] [OS: 10] [MIS: 10] [init TSN: 2141904492] +14:28:58.888638 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [COOKIE ECHO] , (2) [DATA] (B)(E) [TSN: 3092969729] [...] +14:28:58.893278 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [COOKIE ACK] , (2) [SACK] [cum ack 3092969729] [a_rwnd 106491] [#gap acks 0] [#dup tsns 0] +14:28:58.893591 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [DATA] (B)(E) [TSN: 3092969730] [...] +14:28:59.096963 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SACK] [cum ack 3092969730] [a_rwnd 106496] [#gap acks 0] [#dup tsns 0] +14:28:59.097086 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [DATA] (B)(E) [TSN: 3092969731] [...] , (2) [DATA] (B)(E) [TSN: 3092969732] [...] +14:28:59.103218 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SACK] [cum ack 3092969732] [a_rwnd 106486] [#gap acks 0] [#dup tsns 0] +14:28:59.103330 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [SHUTDOWN] +14:28:59.107793 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SHUTDOWN ACK] +14:28:59.107890 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [SHUTDOWN COMPLETE] + +Looks like this bug is from the pre-git history museum. ;) + +Fixes: 08707d5482df ("lksctp-2_5_31-0_5_1.patch") +Signed-off-by: Daniel Borkmann +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/sctp/socket.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1604,7 +1604,7 @@ static int sctp_sendmsg(struct kiocb *io + sctp_assoc_t associd = 0; + sctp_cmsgs_t cmsgs = { NULL }; + sctp_scope_t scope; +- bool fill_sinfo_ttl = false; ++ bool fill_sinfo_ttl = false, wait_connect = false; + struct sctp_datamsg *datamsg; + int msg_flags = msg->msg_flags; + __u16 sinfo_flags = 0; +@@ -1944,6 +1944,7 @@ static int sctp_sendmsg(struct kiocb *io + if (err < 0) + goto out_free; + ++ wait_connect = true; + pr_debug("%s: we associated primitively\n", __func__); + } + +@@ -1981,6 +1982,11 @@ static int sctp_sendmsg(struct kiocb *io + sctp_datamsg_put(datamsg); + err = msg_len; + ++ if (unlikely(wait_connect)) { ++ timeo = sock_sndtimeo(sk, msg_flags & MSG_DONTWAIT); ++ sctp_wait_for_connect(asoc, &timeo); ++ } ++ + /* If we are already past ASSOCIATE, the lower + * layers are responsible for association cleanup. + */ diff --git a/queue-3.18/series b/queue-3.18/series index 70bef1cdebd..a1595501a42 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -13,3 +13,19 @@ bluetooth-bnep-bnep_add_connection-should-verify-that-it-s-dealing-with-l2cap-so bluetooth-fix-potential-null-dereference.patch bluetooth-cmtp-cmtp_add_connection-should-verify-that-it-s-dealing-with-l2cap-socket.patch net-phy-do-not-perform-software-reset-for-generic-phy.patch +isdn-fix-a-sleep-in-atomic-bug.patch +string-provide-strscpy.patch +strscpy-zero-any-trailing-garbage-bytes-in-the-destination.patch +isdn-i4l-fix-buffer-overflow.patch +wil6210-fix-deadlock-when-using-fw_no_recovery-option.patch +mailbox-always-wait-in-mbox_send_message-for-blocking-tx-mode.patch +mailbox-skip-complete-wait-event-if-timer-expired.patch +mailbox-handle-empty-message-in-tx_tick.patch +mpt3sas-don-t-overreach-ioc-reply_post-during-initialization.patch +kaweth-fix-firmware-download.patch +kaweth-fix-oops-upon-failed-memory-allocation.patch +ipv6-fix-possible-deadlock-in-ip6_fl_purge-ip6_fl_gc.patch +net-sctp-fix-race-for-one-to-many-sockets-in-sendmsg-s-auto-associate.patch +sh_eth-fix-ethtool-operation-crash-when-net-device-is-down.patch +net-sched-fix-soft-lockup-in-tc_classify.patch +ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch diff --git a/queue-3.18/sh_eth-fix-ethtool-operation-crash-when-net-device-is-down.patch b/queue-3.18/sh_eth-fix-ethtool-operation-crash-when-net-device-is-down.patch new file mode 100644 index 00000000000..c5a2a0ffe4a --- /dev/null +++ b/queue-3.18/sh_eth-fix-ethtool-operation-crash-when-net-device-is-down.patch @@ -0,0 +1,71 @@ +From 4f9dce230b32eec45cec8c28cae61efdfa2f7d57 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Fri, 16 Jan 2015 17:51:25 +0000 +Subject: sh_eth: Fix ethtool operation crash when net device is down + +From: Ben Hutchings + +commit 4f9dce230b32eec45cec8c28cae61efdfa2f7d57 upstream. + +The driver connects and disconnects the PHY device whenever the +net device is brought up and down. The ethtool get_settings, +set_settings and nway_reset operations will dereference a null +or dangling pointer if called while it is down. + +I think it would be preferable to keep the PHY connected, but there +may be good reasons not to. + +As an immediate fix for this bug: +- Set the phydev pointer to NULL after disconnecting the PHY +- Change those three operations to return -ENODEV while the PHY is + not connected + +Signed-off-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -1832,6 +1832,9 @@ static int sh_eth_get_settings(struct ne + unsigned long flags; + int ret; + ++ if (!mdp->phydev) ++ return -ENODEV; ++ + spin_lock_irqsave(&mdp->lock, flags); + ret = phy_ethtool_gset(mdp->phydev, ecmd); + spin_unlock_irqrestore(&mdp->lock, flags); +@@ -1846,6 +1849,9 @@ static int sh_eth_set_settings(struct ne + unsigned long flags; + int ret; + ++ if (!mdp->phydev) ++ return -ENODEV; ++ + spin_lock_irqsave(&mdp->lock, flags); + + /* disable tx and rx */ +@@ -1880,6 +1886,9 @@ static int sh_eth_nway_reset(struct net_ + unsigned long flags; + int ret; + ++ if (!mdp->phydev) ++ return -ENODEV; ++ + spin_lock_irqsave(&mdp->lock, flags); + ret = phy_start_aneg(mdp->phydev); + spin_unlock_irqrestore(&mdp->lock, flags); +@@ -2189,6 +2198,7 @@ static int sh_eth_close(struct net_devic + if (mdp->phydev) { + phy_stop(mdp->phydev); + phy_disconnect(mdp->phydev); ++ mdp->phydev = NULL; + } + + free_irq(ndev->irq, ndev); diff --git a/queue-3.18/string-provide-strscpy.patch b/queue-3.18/string-provide-strscpy.patch new file mode 100644 index 00000000000..d5136d7ec7f --- /dev/null +++ b/queue-3.18/string-provide-strscpy.patch @@ -0,0 +1,158 @@ +From 30035e45753b708e7d47a98398500ca005e02b86 Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Wed, 29 Apr 2015 12:52:04 -0400 +Subject: string: provide strscpy() + +From: Chris Metcalf + +commit 30035e45753b708e7d47a98398500ca005e02b86 upstream. + +The strscpy() API is intended to be used instead of strlcpy(), +and instead of most uses of strncpy(). + +- Unlike strlcpy(), it doesn't read from memory beyond (src + size). + +- Unlike strlcpy() or strncpy(), the API provides an easy way to check + for destination buffer overflow: an -E2BIG error return value. + +- The provided implementation is robust in the face of the source + buffer being asynchronously changed during the copy, unlike the + current implementation of strlcpy(). + +- Unlike strncpy(), the destination buffer will be NUL-terminated + if the string in the source buffer is too long. + +- Also unlike strncpy(), the destination buffer will not be updated + beyond the NUL termination, avoiding strncpy's behavior of zeroing + the entire tail end of the destination buffer. (A memset() after + the strscpy() can be used if this behavior is desired.) + +- The implementation should be reasonably performant on all + platforms since it uses the asm/word-at-a-time.h API rather than + simple byte copy. Kernel-to-kernel string copy is not considered + to be performance critical in any case. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/string.h | 3 + + lib/string.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 91 insertions(+) + +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -25,6 +25,9 @@ extern char * strncpy(char *,const char + #ifndef __HAVE_ARCH_STRLCPY + size_t strlcpy(char *, const char *, size_t); + #endif ++#ifndef __HAVE_ARCH_STRSCPY ++ssize_t __must_check strscpy(char *, const char *, size_t); ++#endif + #ifndef __HAVE_ARCH_STRCAT + extern char * strcat(char *, const char *); + #endif +--- a/lib/string.c ++++ b/lib/string.c +@@ -27,6 +27,10 @@ + #include + #include + ++#include ++#include ++#include ++ + #ifndef __HAVE_ARCH_STRNCASECMP + /** + * strncasecmp - Case insensitive, length-limited string comparison +@@ -154,6 +158,90 @@ size_t strlcpy(char *dest, const char *s + EXPORT_SYMBOL(strlcpy); + #endif + ++#ifndef __HAVE_ARCH_STRSCPY ++/** ++ * strscpy - Copy a C-string into a sized buffer ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: Size of destination buffer ++ * ++ * Copy the string, or as much of it as fits, into the dest buffer. ++ * The routine returns the number of characters copied (not including ++ * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. ++ * The behavior is undefined if the string buffers overlap. ++ * The destination buffer is always NUL terminated, unless it's zero-sized. ++ * ++ * Preferred to strlcpy() since the API doesn't require reading memory ++ * from the src string beyond the specified "count" bytes, and since ++ * the return value is easier to error-check than strlcpy()'s. ++ * In addition, the implementation is robust to the string changing out ++ * from underneath it, unlike the current strlcpy() implementation. ++ * ++ * Preferred to strncpy() since it always returns a valid string, and ++ * doesn't unnecessarily force the tail of the destination buffer to be ++ * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() ++ * with an overflow test, then just memset() the tail of the dest buffer. ++ */ ++ssize_t strscpy(char *dest, const char *src, size_t count) ++{ ++ const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; ++ size_t max = count; ++ long res = 0; ++ ++ if (count == 0) ++ return -E2BIG; ++ ++#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS ++ /* ++ * If src is unaligned, don't cross a page boundary, ++ * since we don't know if the next page is mapped. ++ */ ++ if ((long)src & (sizeof(long) - 1)) { ++ size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); ++ if (limit < max) ++ max = limit; ++ } ++#else ++ /* If src or dest is unaligned, don't do word-at-a-time. */ ++ if (((long) dest | (long) src) & (sizeof(long) - 1)) ++ max = 0; ++#endif ++ ++ while (max >= sizeof(unsigned long)) { ++ unsigned long c, data; ++ ++ c = *(unsigned long *)(src+res); ++ *(unsigned long *)(dest+res) = c; ++ if (has_zero(c, &data, &constants)) { ++ data = prep_zero_mask(c, data, &constants); ++ data = create_zero_mask(data); ++ return res + find_zero(data); ++ } ++ res += sizeof(unsigned long); ++ count -= sizeof(unsigned long); ++ max -= sizeof(unsigned long); ++ } ++ ++ while (count) { ++ char c; ++ ++ c = src[res]; ++ dest[res] = c; ++ if (!c) ++ return res; ++ res++; ++ count--; ++ } ++ ++ /* Hit buffer length without finding a NUL; force NUL-termination. */ ++ if (res) ++ dest[res-1] = '\0'; ++ ++ return -E2BIG; ++} ++EXPORT_SYMBOL(strscpy); ++#endif ++ + #ifndef __HAVE_ARCH_STRCAT + /** + * strcat - Append one %NUL-terminated string to another diff --git a/queue-3.18/strscpy-zero-any-trailing-garbage-bytes-in-the-destination.patch b/queue-3.18/strscpy-zero-any-trailing-garbage-bytes-in-the-destination.patch new file mode 100644 index 00000000000..1e8ba00ef97 --- /dev/null +++ b/queue-3.18/strscpy-zero-any-trailing-garbage-bytes-in-the-destination.patch @@ -0,0 +1,37 @@ +From 990486c8af044f89bddfbde1d1cf9fde449bedbf Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Tue, 6 Oct 2015 12:37:41 -0400 +Subject: strscpy: zero any trailing garbage bytes in the destination + +From: Chris Metcalf + +commit 990486c8af044f89bddfbde1d1cf9fde449bedbf upstream. + +It's possible that the destination can be shadowed in userspace +(as, for example, the perf buffers are now). So we should take +care not to leak data that could be inspected by userspace. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + lib/string.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/lib/string.c ++++ b/lib/string.c +@@ -211,12 +211,13 @@ ssize_t strscpy(char *dest, const char * + unsigned long c, data; + + c = *(unsigned long *)(src+res); +- *(unsigned long *)(dest+res) = c; + if (has_zero(c, &data, &constants)) { + data = prep_zero_mask(c, data, &constants); + data = create_zero_mask(data); ++ *(unsigned long *)(dest+res) = c & zero_bytemask(data); + return res + find_zero(data); + } ++ *(unsigned long *)(dest+res) = c; + res += sizeof(unsigned long); + count -= sizeof(unsigned long); + max -= sizeof(unsigned long); diff --git a/queue-3.18/wil6210-fix-deadlock-when-using-fw_no_recovery-option.patch b/queue-3.18/wil6210-fix-deadlock-when-using-fw_no_recovery-option.patch new file mode 100644 index 00000000000..379d12ffaf3 --- /dev/null +++ b/queue-3.18/wil6210-fix-deadlock-when-using-fw_no_recovery-option.patch @@ -0,0 +1,53 @@ +From dfb5b098e0f40b68aa07f2ec55f4dd762efefbfa Mon Sep 17 00:00:00 2001 +From: Lior David +Date: Wed, 23 Nov 2016 16:06:41 +0200 +Subject: wil6210: fix deadlock when using fw_no_recovery option + +From: Lior David + +commit dfb5b098e0f40b68aa07f2ec55f4dd762efefbfa upstream. + +When FW crashes with no_fw_recovery option, driver +waits for manual recovery with wil->mutex held, this +can easily create deadlocks. +Fix the problem by moving the wait outside the lock. + +Signed-off-by: Lior David +Signed-off-by: Maya Erez +Signed-off-by: Kalle Valo +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/wil6210/main.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ath/wil6210/main.c ++++ b/drivers/net/wireless/ath/wil6210/main.c +@@ -240,18 +240,19 @@ static void wil_fw_error_worker(struct w + + wil->last_fw_recovery = jiffies; + ++ wil_info(wil, "fw error recovery requested (try %d)...\n", ++ wil->recovery_count); ++ if (!no_fw_recovery) ++ wil->recovery_state = fw_recovery_running; ++ if (wil_wait_for_recovery(wil) != 0) ++ return; ++ + mutex_lock(&wil->mutex); + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_MONITOR: +- wil_info(wil, "fw error recovery requested (try %d)...\n", +- wil->recovery_count); +- if (!no_fw_recovery) +- wil->recovery_state = fw_recovery_running; +- if (0 != wil_wait_for_recovery(wil)) +- break; +- ++ /* silent recovery, upper layers will see disconnect */ + __wil_down(wil); + __wil_up(wil); + break;