diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2019-10-24 18:28:19 +0100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2019-10-24 18:40:59 +0100 |
commit | 0949749200031a683d159478504034661fd173dc (patch) | |
tree | 4b128a305aaa50de38c1ce13bdb02351b7799800 | |
parent | 0f200eb2ae5b0ebcded1d034a4095277437a4703 (diff) | |
download | linux-stable-queue-0949749200031a683d159478504034661fd173dc.tar.gz |
Add commits cc'd to stable, up to 5.3-rc1
...plus their obvious dependencies, and a follow-up fix.
49 files changed, 3704 insertions, 1 deletions
diff --git a/queue-3.16/9p-virtio-add-cleanup-path-in-p9_virtio_init.patch b/queue-3.16/9p-virtio-add-cleanup-path-in-p9_virtio_init.patch new file mode 100644 index 00000000..8073b48c --- /dev/null +++ b/queue-3.16/9p-virtio-add-cleanup-path-in-p9_virtio_init.patch @@ -0,0 +1,84 @@ +From: YueHaibing <yuehaibing@huawei.com> +Date: Tue, 30 Apr 2019 19:59:42 +0800 +Subject: 9p/virtio: Add cleanup path in p9_virtio_init + +commit d4548543fc4ece56c6f04b8586f435fb4fd84c20 upstream. + +KASAN report this: + +BUG: unable to handle kernel paging request at ffffffffa0097000 +PGD 3870067 P4D 3870067 PUD 3871063 PMD 2326e2067 PTE 0 +Oops: 0000 [#1 +CPU: 0 PID: 5340 Comm: modprobe Not tainted 5.1.0-rc7+ #25 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014 +RIP: 0010:__list_add_valid+0x10/0x70 +Code: c3 48 8b 06 55 48 89 e5 5d 48 39 07 0f 94 c0 0f b6 c0 c3 90 90 90 90 90 90 90 55 48 89 d0 48 8b 52 08 48 89 e5 48 39 f2 75 19 <48> 8b 32 48 39 f0 75 3a + +RSP: 0018:ffffc90000e23c68 EFLAGS: 00010246 +RAX: ffffffffa00ad000 RBX: ffffffffa009d000 RCX: 0000000000000000 +RDX: ffffffffa0097000 RSI: ffffffffa0097000 RDI: ffffffffa009d000 +RBP: ffffc90000e23c68 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffa0097000 +R13: ffff888231797180 R14: 0000000000000000 R15: ffffc90000e23e78 +FS: 00007fb215285540(0000) GS:ffff888237a00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffffffa0097000 CR3: 000000022f144000 CR4: 00000000000006f0 +Call Trace: + v9fs_register_trans+0x2f/0x60 [9pnet + ? 0xffffffffa0087000 + p9_virtio_init+0x25/0x1000 [9pnet_virtio + do_one_initcall+0x6c/0x3cc + ? kmem_cache_alloc_trace+0x248/0x3b0 + do_init_module+0x5b/0x1f1 + load_module+0x1db1/0x2690 + ? m_show+0x1d0/0x1d0 + __do_sys_finit_module+0xc5/0xd0 + __x64_sys_finit_module+0x15/0x20 + do_syscall_64+0x6b/0x1d0 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x7fb214d8e839 +Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 + +RSP: 002b:00007ffc96554278 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 +RAX: ffffffffffffffda RBX: 000055e67eed2aa0 RCX: 00007fb214d8e839 +RDX: 0000000000000000 RSI: 000055e67ce95c2e RDI: 0000000000000003 +RBP: 000055e67ce95c2e R08: 0000000000000000 R09: 000055e67eed2aa0 +R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000 +R13: 000055e67eeda500 R14: 0000000000040000 R15: 000055e67eed2aa0 +Modules linked in: 9pnet_virtio(+) 9pnet gre rfkill vmw_vsock_virtio_transport_common vsock [last unloaded: 9pnet_virtio +CR2: ffffffffa0097000 +---[ end trace 4a52bb13ff07b761 + +If register_virtio_driver() fails in p9_virtio_init, +we should call v9fs_unregister_trans() to do cleanup. + +Link: http://lkml.kernel.org/r/20190430115942.41840-1-yuehaibing@huawei.com +Reported-by: Hulk Robot <hulkci@huawei.com> +Fixes: b530cc794024 ("9p: add virtio transport") +Signed-off-by: YueHaibing <yuehaibing@huawei.com> +Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/9p/trans_virtio.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/9p/trans_virtio.c ++++ b/net/9p/trans_virtio.c +@@ -718,10 +718,16 @@ static struct p9_trans_module p9_virtio_ + /* The standard init function */ + static int __init p9_virtio_init(void) + { ++ int rc; ++ + INIT_LIST_HEAD(&virtio_chan_list); + + v9fs_register_trans(&p9_virtio_trans); +- return register_virtio_driver(&p9_virtio_drv); ++ rc = register_virtio_driver(&p9_virtio_drv); ++ if (rc) ++ v9fs_unregister_trans(&p9_virtio_trans); ++ ++ return rc; + } + + static void __exit p9_virtio_cleanup(void) diff --git a/queue-3.16/af_key-fix-leaks-in-key_pol_get_resp-and-dump_sp.patch b/queue-3.16/af_key-fix-leaks-in-key_pol_get_resp-and-dump_sp.patch new file mode 100644 index 00000000..b17e9696 --- /dev/null +++ b/queue-3.16/af_key-fix-leaks-in-key_pol_get_resp-and-dump_sp.patch @@ -0,0 +1,44 @@ +From: Jeremy Sowden <jeremy@azazel.net> +Date: Sat, 25 May 2019 19:09:35 +0100 +Subject: af_key: fix leaks in key_pol_get_resp and dump_sp. + +commit 7c80eb1c7e2b8420477fbc998971d62a648035d9 upstream. + +In both functions, if pfkey_xfrm_policy2msg failed we leaked the newly +allocated sk_buff. Free it on error. + +Fixes: 55569ce256ce ("Fix conversion between IPSEC_MODE_xxx and XFRM_MODE_xxx.") +Reported-by: syzbot+4f0529365f7f2208d9f0@syzkaller.appspotmail.com +Signed-off-by: Jeremy Sowden <jeremy@azazel.net> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/key/af_key.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2437,8 +2437,10 @@ static int key_pol_get_resp(struct sock + goto out; + } + err = pfkey_xfrm_policy2msg(out_skb, xp, dir); +- if (err < 0) ++ if (err < 0) { ++ kfree_skb(out_skb); + goto out; ++ } + + out_hdr = (struct sadb_msg *) out_skb->data; + out_hdr->sadb_msg_version = hdr->sadb_msg_version; +@@ -2689,8 +2691,10 @@ static int dump_sp(struct xfrm_policy *x + return PTR_ERR(out_skb); + + err = pfkey_xfrm_policy2msg(out_skb, xp, dir); +- if (err < 0) ++ if (err < 0) { ++ kfree_skb(out_skb); + return err; ++ } + + out_hdr = (struct sadb_msg *) out_skb->data; + out_hdr->sadb_msg_version = pfk->dump.msg_version; diff --git a/queue-3.16/alsa-seq-break-too-long-mutex-context-in-the-write-loop.patch b/queue-3.16/alsa-seq-break-too-long-mutex-context-in-the-write-loop.patch new file mode 100644 index 00000000..88df2e86 --- /dev/null +++ b/queue-3.16/alsa-seq-break-too-long-mutex-context-in-the-write-loop.patch @@ -0,0 +1,68 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Mon, 15 Jul 2019 22:50:27 +0200 +Subject: ALSA: seq: Break too long mutex context in the write loop + +commit ede34f397ddb063b145b9e7d79c6026f819ded13 upstream. + +The fix for the racy writes and ioctls to sequencer widened the +application of client->ioctl_mutex to the whole write loop. Although +it does unlock/relock for the lengthy operation like the event dup, +the loop keeps the ioctl_mutex for the whole time in other +situations. This may take quite long time if the user-space would +give a huge buffer, and this is a likely cause of some weird behavior +spotted by syzcaller fuzzer. + +This patch puts a simple workaround, just adding a mutex break in the +loop when a large number of events have been processed. This +shouldn't hit any performance drop because the threshold is set high +enough for usual operations. + +Fixes: 7bd800915677 ("ALSA: seq: More protection for concurrent write and ioctl races") +Reported-by: syzbot+97aae04ce27e39cbfca9@syzkaller.appspotmail.com +Reported-by: syzbot+4c595632b98bb8ffcc66@syzkaller.appspotmail.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/core/seq/seq_clientmgr.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1014,7 +1014,7 @@ static ssize_t snd_seq_write(struct file + { + struct snd_seq_client *client = file->private_data; + int written = 0, len; +- int err; ++ int err, handled; + struct snd_seq_event event; + + if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT)) +@@ -1027,6 +1027,8 @@ static ssize_t snd_seq_write(struct file + if (!client->accept_output || client->pool == NULL) + return -ENXIO; + ++ repeat: ++ handled = 0; + /* allocate the pool now if the pool is not allocated yet */ + mutex_lock(&client->ioctl_mutex); + if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { +@@ -1086,12 +1088,19 @@ static ssize_t snd_seq_write(struct file + 0, 0, &client->ioctl_mutex); + if (err < 0) + break; ++ handled++; + + __skip_event: + /* Update pointers and counts */ + count -= len; + buf += len; + written += len; ++ ++ /* let's have a coffee break if too many events are queued */ ++ if (++handled >= 200) { ++ mutex_unlock(&client->ioctl_mutex); ++ goto repeat; ++ } + } + + out: diff --git a/queue-3.16/arc-hide-unused-function-unw_hdr_alloc.patch b/queue-3.16/arc-hide-unused-function-unw_hdr_alloc.patch new file mode 100644 index 00000000..8822d7a6 --- /dev/null +++ b/queue-3.16/arc-hide-unused-function-unw_hdr_alloc.patch @@ -0,0 +1,45 @@ +From: Arnd Bergmann <arnd@arndb.de> +Date: Wed, 3 Jul 2019 15:39:25 +0200 +Subject: ARC: hide unused function unw_hdr_alloc + +commit fd5de2721ea7d16e2b16c4049ac49f229551b290 upstream. + +As kernelci.org reports, this function is not used in +vdk_hs38_defconfig: + +arch/arc/kernel/unwind.c:188:14: warning: 'unw_hdr_alloc' defined but not used [-Wunused-function] + +Fixes: bc79c9a72165 ("ARC: dw2 unwind: Reinstante unwinding out of modules") +Link: https://kernelci.org/build/id/5d1cae3f59b514300340c132/logs/ +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arc/kernel/unwind.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/arc/kernel/unwind.c ++++ b/arch/arc/kernel/unwind.c +@@ -183,11 +183,6 @@ static void *__init unw_hdr_alloc_early( + MAX_DMA_ADDRESS); + } + +-static void *unw_hdr_alloc(unsigned long sz) +-{ +- return kmalloc(sz, GFP_KERNEL); +-} +- + static void init_unwind_table(struct unwind_table *table, const char *name, + const void *core_start, unsigned long core_size, + const void *init_start, unsigned long init_size, +@@ -368,6 +363,10 @@ static void init_unwind_hdr(struct unwin + } + + #ifdef CONFIG_MODULES ++static void *unw_hdr_alloc(unsigned long sz) ++{ ++ return kmalloc(sz, GFP_KERNEL); ++} + + static struct unwind_table *last_table; + diff --git a/queue-3.16/arm-riscpc-fix-dma.patch b/queue-3.16/arm-riscpc-fix-dma.patch new file mode 100644 index 00000000..504ee54d --- /dev/null +++ b/queue-3.16/arm-riscpc-fix-dma.patch @@ -0,0 +1,42 @@ +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Thu, 2 May 2019 17:19:18 +0100 +Subject: ARM: riscpc: fix DMA + +commit ffd9a1ba9fdb7f2bd1d1ad9b9243d34e96756ba2 upstream. + +DMA got broken a while back in two different ways: +1) a change in the behaviour of disable_irq() to wait for the interrupt + to finish executing causes us to deadlock at the end of DMA. +2) a change to avoid modifying the scatterlist left the first transfer + uninitialised. + +DMA is only used with expansion cards, so has gone unnoticed. + +Fixes: fa4e99899932 ("[ARM] dma: RiscPC: don't modify DMA SG entries") +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/mach-rpc/dma.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm/mach-rpc/dma.c ++++ b/arch/arm/mach-rpc/dma.c +@@ -131,7 +131,7 @@ static irqreturn_t iomd_dma_handle(int i + } while (1); + + idma->state = ~DMA_ST_AB; +- disable_irq(irq); ++ disable_irq_nosync(irq); + + return IRQ_HANDLED; + } +@@ -174,6 +174,9 @@ static void iomd_enable_dma(unsigned int + DMA_FROM_DEVICE : DMA_TO_DEVICE); + } + ++ idma->dma_addr = idma->dma.sg->dma_address; ++ idma->dma_len = idma->dma.sg->length; ++ + iomd_writeb(DMA_CR_C, dma_base + CR); + idma->state = DMA_ST_AB; + } diff --git a/queue-3.16/bonding-validate-ip-header-before-check-ipproto_igmp.patch b/queue-3.16/bonding-validate-ip-header-before-check-ipproto_igmp.patch new file mode 100644 index 00000000..3bfe174e --- /dev/null +++ b/queue-3.16/bonding-validate-ip-header-before-check-ipproto_igmp.patch @@ -0,0 +1,85 @@ +From: Cong Wang <xiyou.wangcong@gmail.com> +Date: Mon, 1 Jul 2019 20:40:24 -0700 +Subject: bonding: validate ip header before check IPPROTO_IGMP + +commit 9d1bc24b52fb8c5d859f9a47084bf1179470e04c upstream. + +bond_xmit_roundrobin() checks for IGMP packets but it parses +the IP header even before checking skb->protocol. + +We should validate the IP header with pskb_may_pull() before +using iph->protocol. + +Reported-and-tested-by: syzbot+e5be16aa39ad6e755391@syzkaller.appspotmail.com +Fixes: a2fd940f4cff ("bonding: fix broken multicast with round-robin mode") +Cc: Jay Vosburgh <j.vosburgh@gmail.com> +Cc: Veaceslav Falico <vfalico@gmail.com> +Cc: Andy Gospodarek <andy@greyhouse.net> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: + - Keep using ACCESS_ONCE(), dev_kfree_skb_any(), …_can_tx() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/bonding/bond_main.c | 37 ++++++++++++++++++++------------- + 1 file changed, 23 insertions(+), 14 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3700,8 +3700,8 @@ static u32 bond_rr_gen_slave_id(struct b + static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) + { + struct bonding *bond = netdev_priv(bond_dev); +- struct iphdr *iph = ip_hdr(skb); + struct slave *slave; ++ int slave_cnt; + u32 slave_id; + + /* Start with the curr_active_slave that joined the bond as the +@@ -3710,23 +3710,32 @@ static int bond_xmit_roundrobin(struct s + * send the join/membership reports. The curr_active_slave found + * will send all of this type of traffic. + */ +- if (iph->protocol == IPPROTO_IGMP && skb->protocol == htons(ETH_P_IP)) { +- slave = rcu_dereference(bond->curr_active_slave); +- if (slave && bond_slave_can_tx(slave)) +- bond_dev_queue_xmit(bond, skb, slave->dev); +- else +- bond_xmit_slave_id(bond, skb, 0); +- } else { +- int slave_cnt = ACCESS_ONCE(bond->slave_cnt); ++ if (skb->protocol == htons(ETH_P_IP)) { ++ int noff = skb_network_offset(skb); ++ struct iphdr *iph; ++ ++ if (unlikely(!pskb_may_pull(skb, noff + sizeof(*iph)))) ++ goto non_igmp; + +- if (likely(slave_cnt)) { +- slave_id = bond_rr_gen_slave_id(bond); +- bond_xmit_slave_id(bond, skb, slave_id % slave_cnt); +- } else { +- dev_kfree_skb_any(skb); ++ iph = ip_hdr(skb); ++ if (iph->protocol == IPPROTO_IGMP) { ++ slave = rcu_dereference(bond->curr_active_slave); ++ if (slave && bond_slave_can_tx(slave)) ++ bond_dev_queue_xmit(bond, skb, slave->dev); ++ else ++ bond_xmit_slave_id(bond, skb, 0); ++ return NETDEV_TX_OK; + } + } + ++non_igmp: ++ slave_cnt = ACCESS_ONCE(bond->slave_cnt); ++ if (likely(slave_cnt)) { ++ slave_id = bond_rr_gen_slave_id(bond); ++ bond_xmit_slave_id(bond, skb, slave_id % slave_cnt); ++ } else { ++ dev_kfree_skb_any(skb); ++ } + return NETDEV_TX_OK; + } + diff --git a/queue-3.16/caif-hsi-fix-possible-deadlock-in-cfhsi_exit_module.patch b/queue-3.16/caif-hsi-fix-possible-deadlock-in-cfhsi_exit_module.patch new file mode 100644 index 00000000..6e361056 --- /dev/null +++ b/queue-3.16/caif-hsi-fix-possible-deadlock-in-cfhsi_exit_module.patch @@ -0,0 +1,29 @@ +From: Taehee Yoo <ap420073@gmail.com> +Date: Mon, 15 Jul 2019 14:10:17 +0900 +Subject: caif-hsi: fix possible deadlock in cfhsi_exit_module() + +commit fdd258d49e88a9e0b49ef04a506a796f1c768a8e upstream. + +cfhsi_exit_module() calls unregister_netdev() under rtnl_lock(). +but unregister_netdev() internally calls rtnl_lock(). +So deadlock would occur. + +Fixes: c41254006377 ("caif-hsi: Add rtnl support") +Signed-off-by: Taehee Yoo <ap420073@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/caif/caif_hsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/caif/caif_hsi.c ++++ b/drivers/net/caif/caif_hsi.c +@@ -1467,7 +1467,7 @@ static void __exit cfhsi_exit_module(voi + rtnl_lock(); + list_for_each_safe(list_node, n, &cfhsi_list) { + cfhsi = list_entry(list_node, struct cfhsi, list); +- unregister_netdev(cfhsi->ndev); ++ unregister_netdevice(cfhsi->ndev); + } + rtnl_unlock(); + } diff --git a/queue-3.16/carl9170-fix-misuse-of-device-driver-api.patch b/queue-3.16/carl9170-fix-misuse-of-device-driver-api.patch new file mode 100644 index 00000000..857ccb21 --- /dev/null +++ b/queue-3.16/carl9170-fix-misuse-of-device-driver-api.patch @@ -0,0 +1,143 @@ +From: Christian Lamparter <chunkeey@gmail.com> +Date: Sat, 8 Jun 2019 16:49:47 +0200 +Subject: carl9170: fix misuse of device driver API + +commit feb09b2933275a70917a869989ea2823e7356be8 upstream. + +This patch follows Alan Stern's recent patch: +"p54: Fix race between disconnect and firmware loading" + +that overhauled carl9170 buggy firmware loading and driver +unbinding procedures. + +Since the carl9170 code was adapted from p54 it uses the +same functions and is likely to have the same problem, but +it's just that the syzbot hasn't reproduce them (yet). + +a summary from the changes (copied from the p54 patch): + * Call usb_driver_release_interface() rather than + device_release_driver(). + + * Lock udev (the interface's parent) before unbinding the + driver instead of locking udev->parent. + + * During the firmware loading process, take a reference + to the USB interface instead of the USB device. + + * Don't take an unnecessary reference to the device during + probe (and then don't drop it during disconnect). + +and + + * Make sure to prevent use-after-free bugs by explicitly + setting the driver context to NULL after signaling the + completion. + +Cc: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Christian Lamparter <chunkeey@gmail.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/wireless/ath/carl9170/usb.c | 39 +++++++++++-------------- + 1 file changed, 17 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -128,6 +128,8 @@ static struct usb_device_id carl9170_usb + }; + MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); + ++static struct usb_driver carl9170_driver; ++ + static void carl9170_usb_submit_data_urb(struct ar9170 *ar) + { + struct urb *urb; +@@ -967,32 +969,28 @@ err_out: + + static void carl9170_usb_firmware_failed(struct ar9170 *ar) + { +- struct device *parent = ar->udev->dev.parent; +- struct usb_device *udev; +- +- /* +- * Store a copy of the usb_device pointer locally. +- * This is because device_release_driver initiates +- * carl9170_usb_disconnect, which in turn frees our +- * driver context (ar). ++ /* Store a copies of the usb_interface and usb_device pointer locally. ++ * This is because release_driver initiates carl9170_usb_disconnect, ++ * which in turn frees our driver context (ar). + */ +- udev = ar->udev; ++ struct usb_interface *intf = ar->intf; ++ struct usb_device *udev = ar->udev; + + complete(&ar->fw_load_wait); ++ /* at this point 'ar' could be already freed. Don't use it anymore */ ++ ar = NULL; + + /* unbind anything failed */ +- if (parent) +- device_lock(parent); +- +- device_release_driver(&udev->dev); +- if (parent) +- device_unlock(parent); ++ usb_lock_device(udev); ++ usb_driver_release_interface(&carl9170_driver, intf); ++ usb_unlock_device(udev); + +- usb_put_dev(udev); ++ usb_put_intf(intf); + } + + static void carl9170_usb_firmware_finish(struct ar9170 *ar) + { ++ struct usb_interface *intf = ar->intf; + int err; + + err = carl9170_parse_firmware(ar); +@@ -1010,7 +1008,7 @@ static void carl9170_usb_firmware_finish + goto err_unrx; + + complete(&ar->fw_load_wait); +- usb_put_dev(ar->udev); ++ usb_put_intf(intf); + return; + + err_unrx: +@@ -1053,7 +1051,6 @@ static int carl9170_usb_probe(struct usb + return PTR_ERR(ar); + + udev = interface_to_usbdev(intf); +- usb_get_dev(udev); + ar->udev = udev; + ar->intf = intf; + ar->features = id->driver_info; +@@ -1095,15 +1092,14 @@ static int carl9170_usb_probe(struct usb + atomic_set(&ar->rx_anch_urbs, 0); + atomic_set(&ar->rx_pool_urbs, 0); + +- usb_get_dev(ar->udev); ++ usb_get_intf(intf); + + carl9170_set_state(ar, CARL9170_STOPPED); + + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { +- usb_put_dev(udev); +- usb_put_dev(udev); ++ usb_put_intf(intf); + carl9170_free(ar); + } + return err; +@@ -1132,7 +1128,6 @@ static void carl9170_usb_disconnect(stru + + carl9170_release_firmware(ar); + carl9170_free(ar); +- usb_put_dev(udev); + } + + #ifdef CONFIG_PM diff --git a/queue-3.16/coda-pass-the-host-file-in-vma-vm_file-on-mmap.patch b/queue-3.16/coda-pass-the-host-file-in-vma-vm_file-on-mmap.patch new file mode 100644 index 00000000..377b1217 --- /dev/null +++ b/queue-3.16/coda-pass-the-host-file-in-vma-vm_file-on-mmap.patch @@ -0,0 +1,163 @@ +From: Jan Harkes <jaharkes@cs.cmu.edu> +Date: Tue, 16 Jul 2019 16:28:04 -0700 +Subject: coda: pass the host file in vma->vm_file on mmap + +commit 7fa0a1da3dadfd9216df7745a1331fdaa0940d1c upstream. + +Patch series "Coda updates". + +The following patch series is a collection of various fixes for Coda, +most of which were collected from linux-fsdevel or linux-kernel but +which have as yet not found their way upstream. + +This patch (of 22): + +Various file systems expect that vma->vm_file points at their own file +handle, several use file_inode(vma->vm_file) to get at their inode or +use vma->vm_file->private_data. However the way Coda wrapped mmap on a +host file broke this assumption, vm_file was still pointing at the Coda +file and the host file systems would scribble over Coda's inode and +private file data. + +This patch fixes the incorrect expectation and wraps vm_ops->open and +vm_ops->close to allow Coda to track when the vm_area_struct is +destroyed so we still release the reference on the Coda file handle at +the right time. + +Link: http://lkml.kernel.org/r/0e850c6e59c0b147dc2dcd51a3af004c948c3697.1558117389.git.jaharkes@cs.cmu.edu +Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: Colin Ian King <colin.king@canonical.com> +Cc: Dan Carpenter <dan.carpenter@oracle.com> +Cc: David Howells <dhowells@redhat.com> +Cc: Fabian Frederick <fabf@skynet.be> +Cc: Mikko Rapeli <mikko.rapeli@iki.fi> +Cc: Sam Protsenko <semen.protsenko@linaro.org> +Cc: Yann Droneaud <ydroneaud@opteya.com> +Cc: Zhouyang Jia <jiazhouyang09@gmail.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: Keep calling file_operations::mmap directly] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/coda/file.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 68 insertions(+), 2 deletions(-) + +--- a/fs/coda/file.c ++++ b/fs/coda/file.c +@@ -26,6 +26,13 @@ + #include "coda_linux.h" + #include "coda_int.h" + ++struct coda_vm_ops { ++ atomic_t refcnt; ++ struct file *coda_file; ++ const struct vm_operations_struct *host_vm_ops; ++ struct vm_operations_struct vm_ops; ++}; ++ + static ssize_t + coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos) + { +@@ -93,6 +100,34 @@ coda_file_write(struct file *coda_file, + return ret; + } + ++static void ++coda_vm_open(struct vm_area_struct *vma) ++{ ++ struct coda_vm_ops *cvm_ops = ++ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops); ++ ++ atomic_inc(&cvm_ops->refcnt); ++ ++ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open) ++ cvm_ops->host_vm_ops->open(vma); ++} ++ ++static void ++coda_vm_close(struct vm_area_struct *vma) ++{ ++ struct coda_vm_ops *cvm_ops = ++ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops); ++ ++ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close) ++ cvm_ops->host_vm_ops->close(vma); ++ ++ if (atomic_dec_and_test(&cvm_ops->refcnt)) { ++ vma->vm_ops = cvm_ops->host_vm_ops; ++ fput(cvm_ops->coda_file); ++ kfree(cvm_ops); ++ } ++} ++ + static int + coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) + { +@@ -100,6 +135,8 @@ coda_file_mmap(struct file *coda_file, s + struct coda_inode_info *cii; + struct file *host_file; + struct inode *coda_inode, *host_inode; ++ struct coda_vm_ops *cvm_ops; ++ int ret; + + cfi = CODA_FTOC(coda_file); + BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); +@@ -108,6 +145,13 @@ coda_file_mmap(struct file *coda_file, s + if (!host_file->f_op->mmap) + return -ENODEV; + ++ if (WARN_ON(coda_file != vma->vm_file)) ++ return -EIO; ++ ++ cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL); ++ if (!cvm_ops) ++ return -ENOMEM; ++ + coda_inode = file_inode(coda_file); + host_inode = file_inode(host_file); + +@@ -121,6 +165,7 @@ coda_file_mmap(struct file *coda_file, s + * the container file on us! */ + else if (coda_inode->i_mapping != host_inode->i_mapping) { + spin_unlock(&cii->c_lock); ++ kfree(cvm_ops); + return -EBUSY; + } + +@@ -129,7 +174,29 @@ coda_file_mmap(struct file *coda_file, s + cfi->cfi_mapcount++; + spin_unlock(&cii->c_lock); + +- return host_file->f_op->mmap(host_file, vma); ++ vma->vm_file = get_file(host_file); ++ ret = host_file->f_op->mmap(host_file, vma); ++ ++ if (ret) { ++ /* if ->mmap fails, our caller will put coda_file so we ++ * should drop the reference to the host_file that we got. ++ */ ++ fput(host_file); ++ kfree(cvm_ops); ++ } else { ++ /* here we add redirects for the open/close vm_operations */ ++ cvm_ops->host_vm_ops = vma->vm_ops; ++ if (vma->vm_ops) ++ cvm_ops->vm_ops = *vma->vm_ops; ++ ++ cvm_ops->vm_ops.open = coda_vm_open; ++ cvm_ops->vm_ops.close = coda_vm_close; ++ cvm_ops->coda_file = coda_file; ++ atomic_set(&cvm_ops->refcnt, 1); ++ ++ vma->vm_ops = &cvm_ops->vm_ops; ++ } ++ return ret; + } + + int coda_open(struct inode *coda_inode, struct file *coda_file) +@@ -239,4 +306,3 @@ const struct file_operations coda_file_o + .fsync = coda_fsync, + .splice_read = coda_file_splice_read, + }; +- diff --git a/queue-3.16/crypto-ghash-fix-unaligned-memory-access-in-ghash_setkey.patch b/queue-3.16/crypto-ghash-fix-unaligned-memory-access-in-ghash_setkey.patch new file mode 100644 index 00000000..072deb89 --- /dev/null +++ b/queue-3.16/crypto-ghash-fix-unaligned-memory-access-in-ghash_setkey.patch @@ -0,0 +1,52 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Thu, 30 May 2019 10:50:39 -0700 +Subject: crypto: ghash - fix unaligned memory access in ghash_setkey() + +commit 5c6bc4dfa515738149998bb0db2481a4fdead979 upstream. + +Changing ghash_mod_init() to be subsys_initcall made it start running +before the alignment fault handler has been installed on ARM. In kernel +builds where the keys in the ghash test vectors happened to be +misaligned in the kernel image, this exposed the longstanding bug that +ghash_setkey() is incorrectly casting the key buffer (which can have any +alignment) to be128 for passing to gf128mul_init_4k_lle(). + +Fix this by memcpy()ing the key to a temporary buffer. + +Don't fix it by setting an alignmask on the algorithm instead because +that would unnecessarily force alignment of the data too. + +Fixes: 2cdc6899a88e ("crypto: ghash - Add GHASH digest algorithm for GCM") +Reported-by: Peter Robinson <pbrobinson@gmail.com> +Signed-off-by: Eric Biggers <ebiggers@google.com> +Tested-by: Peter Robinson <pbrobinson@gmail.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + crypto/ghash-generic.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/crypto/ghash-generic.c ++++ b/crypto/ghash-generic.c +@@ -45,6 +45,7 @@ static int ghash_setkey(struct crypto_sh + const u8 *key, unsigned int keylen) + { + struct ghash_ctx *ctx = crypto_shash_ctx(tfm); ++ be128 k; + + if (keylen != GHASH_BLOCK_SIZE) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); +@@ -53,7 +54,12 @@ static int ghash_setkey(struct crypto_sh + + if (ctx->gf128) + gf128mul_free_4k(ctx->gf128); +- ctx->gf128 = gf128mul_init_4k_lle((be128 *)key); ++ ++ BUILD_BUG_ON(sizeof(k) != GHASH_BLOCK_SIZE); ++ memcpy(&k, key, GHASH_BLOCK_SIZE); /* avoid violating alignment rules */ ++ ctx->gf128 = gf128mul_init_4k_lle(&k); ++ memzero_explicit(&k, GHASH_BLOCK_SIZE); ++ + if (!ctx->gf128) + return -ENOMEM; + diff --git a/queue-3.16/crypto-talitos-check-aes-key-size.patch b/queue-3.16/crypto-talitos-check-aes-key-size.patch new file mode 100644 index 00000000..04e08652 --- /dev/null +++ b/queue-3.16/crypto-talitos-check-aes-key-size.patch @@ -0,0 +1,45 @@ +From: Christophe Leroy <christophe.leroy@c-s.fr> +Date: Tue, 21 May 2019 13:34:10 +0000 +Subject: crypto: talitos - check AES key size + +commit 1ba34e71e9e56ac29a52e0d42b6290f3dc5bfd90 upstream. + +Although the HW accepts any size and silently truncates +it to the correct length, the extra tests expects EINVAL +to be returned when the key size is not valid. + +Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> +Fixes: 4de9d0b547b9 ("crypto: talitos - Add ablkcipher algorithms") +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +[bwh: Backported to 3.16: only cbc(aes) algorithm is supported] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -1335,6 +1335,18 @@ static int ablkcipher_setkey(struct cryp + return 0; + } + ++static int ablkcipher_aes_setkey(struct crypto_ablkcipher *cipher, ++ const u8 *key, unsigned int keylen) ++{ ++ if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 || ++ keylen == AES_KEYSIZE_256) ++ return ablkcipher_setkey(cipher, key, keylen); ++ ++ crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ ++ return -EINVAL; ++} ++ + static void common_nonsnoop_unmap(struct device *dev, + struct talitos_edesc *edesc, + struct ablkcipher_request *areq) +@@ -2170,6 +2182,7 @@ static struct talitos_alg_template drive + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, ++ .setkey = ablkcipher_aes_setkey, + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | diff --git a/queue-3.16/ecryptfs-fix-a-couple-type-promotion-bugs.patch b/queue-3.16/ecryptfs-fix-a-couple-type-promotion-bugs.patch new file mode 100644 index 00000000..635beb0f --- /dev/null +++ b/queue-3.16/ecryptfs-fix-a-couple-type-promotion-bugs.patch @@ -0,0 +1,46 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Wed, 4 Jul 2018 12:35:56 +0300 +Subject: eCryptfs: fix a couple type promotion bugs + +commit 0bdf8a8245fdea6f075a5fede833a5fcf1b3466c upstream. + +ECRYPTFS_SIZE_AND_MARKER_BYTES is type size_t, so if "rc" is negative +that gets type promoted to a high positive value and treated as success. + +Fixes: 778aeb42a708 ("eCryptfs: Cleanup and optimize ecryptfs_lookup_interpose()") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +[tyhicks: Use "if/else if" rather than "if/if"] +Signed-off-by: Tyler Hicks <tyhicks@canonical.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ecryptfs/crypto.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -1042,8 +1042,10 @@ int ecryptfs_read_and_validate_header_re + + rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES, + inode); +- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) +- return rc >= 0 ? -EINVAL : rc; ++ if (rc < 0) ++ return rc; ++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) ++ return -EINVAL; + rc = ecryptfs_validate_marker(marker); + if (!rc) + ecryptfs_i_size_init(file_size, inode); +@@ -1401,8 +1403,10 @@ int ecryptfs_read_and_validate_xattr_reg + rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), + ECRYPTFS_XATTR_NAME, file_size, + ECRYPTFS_SIZE_AND_MARKER_BYTES); +- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) +- return rc >= 0 ? -EINVAL : rc; ++ if (rc < 0) ++ return rc; ++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) ++ return -EINVAL; + rc = ecryptfs_validate_marker(marker); + if (!rc) + ecryptfs_i_size_init(file_size, inode); diff --git a/queue-3.16/edac-fix-global-out-of-bounds-write-when-setting-edac_mc_poll_msec.patch b/queue-3.16/edac-fix-global-out-of-bounds-write-when-setting-edac_mc_poll_msec.patch new file mode 100644 index 00000000..f8799787 --- /dev/null +++ b/queue-3.16/edac-fix-global-out-of-bounds-write-when-setting-edac_mc_poll_msec.patch @@ -0,0 +1,152 @@ +From: Eiichi Tsukata <devel@etsukata.com> +Date: Wed, 26 Jun 2019 14:40:11 +0900 +Subject: EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec + +commit d8655e7630dafa88bc37f101640e39c736399771 upstream. + +Commit 9da21b1509d8 ("EDAC: Poll timeout cannot be zero, p2") assumes +edac_mc_poll_msec to be unsigned long, but the type of the variable still +remained as int. Setting edac_mc_poll_msec can trigger out-of-bounds +write. + +Reproducer: + + # echo 1001 > /sys/module/edac_core/parameters/edac_mc_poll_msec + +KASAN report: + + BUG: KASAN: global-out-of-bounds in edac_set_poll_msec+0x140/0x150 + Write of size 8 at addr ffffffffb91b2d00 by task bash/1996 + + CPU: 1 PID: 1996 Comm: bash Not tainted 5.2.0-rc6+ #23 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 + Call Trace: + dump_stack+0xca/0x13e + print_address_description.cold+0x5/0x246 + __kasan_report.cold+0x75/0x9a + ? edac_set_poll_msec+0x140/0x150 + kasan_report+0xe/0x20 + edac_set_poll_msec+0x140/0x150 + ? dimmdev_location_show+0x30/0x30 + ? vfs_lock_file+0xe0/0xe0 + ? _raw_spin_lock+0x87/0xe0 + param_attr_store+0x1b5/0x310 + ? param_array_set+0x4f0/0x4f0 + module_attr_store+0x58/0x80 + ? module_attr_show+0x80/0x80 + sysfs_kf_write+0x13d/0x1a0 + kernfs_fop_write+0x2bc/0x460 + ? sysfs_kf_bin_read+0x270/0x270 + ? kernfs_notify+0x1f0/0x1f0 + __vfs_write+0x81/0x100 + vfs_write+0x1e1/0x560 + ksys_write+0x126/0x250 + ? __ia32_sys_read+0xb0/0xb0 + ? do_syscall_64+0x1f/0x390 + do_syscall_64+0xc1/0x390 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7fa7caa5e970 + Code: 73 01 c3 48 8b 0d 28 d5 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 99 2d 2c 00 00 75 10 b8 01 00 00 00 04 + RSP: 002b:00007fff6acfdfe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007fa7caa5e970 + RDX: 0000000000000005 RSI: 0000000000e95c08 RDI: 0000000000000001 + RBP: 0000000000e95c08 R08: 00007fa7cad1e760 R09: 00007fa7cb36a700 + R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000005 + R13: 0000000000000001 R14: 00007fa7cad1d600 R15: 0000000000000005 + + The buggy address belongs to the variable: + edac_mc_poll_msec+0x0/0x40 + + Memory state around the buggy address: + ffffffffb91b2c00: 00 00 00 00 fa fa fa fa 00 00 00 00 fa fa fa fa + ffffffffb91b2c80: 00 00 00 00 fa fa fa fa 00 00 00 00 fa fa fa fa + >ffffffffb91b2d00: 04 fa fa fa fa fa fa fa 04 fa fa fa fa fa fa fa + ^ + ffffffffb91b2d80: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 + ffffffffb91b2e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +Fix it by changing the type of edac_mc_poll_msec to unsigned int. +The reason why this patch adopts unsigned int rather than unsigned long +is msecs_to_jiffies() assumes arg to be unsigned int. We can avoid +integer conversion bugs and unsigned int will be large enough for +edac_mc_poll_msec. + +Reviewed-by: James Morse <james.morse@arm.com> +Fixes: 9da21b1509d8 ("EDAC: Poll timeout cannot be zero, p2") +Signed-off-by: Eiichi Tsukata <devel@etsukata.com> +Signed-off-by: Tony Luck <tony.luck@intel.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/edac/edac_mc_sysfs.c | 16 ++++++++-------- + drivers/edac/edac_module.h | 2 +- + 2 files changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/edac/edac_mc_sysfs.c ++++ b/drivers/edac/edac_mc_sysfs.c +@@ -26,7 +26,7 @@ + static int edac_mc_log_ue = 1; + static int edac_mc_log_ce = 1; + static int edac_mc_panic_on_ue; +-static int edac_mc_poll_msec = 1000; ++static unsigned int edac_mc_poll_msec = 1000; + + /* Getter functions for above */ + int edac_mc_get_log_ue(void) +@@ -45,30 +45,30 @@ int edac_mc_get_panic_on_ue(void) + } + + /* this is temporary */ +-int edac_mc_get_poll_msec(void) ++unsigned int edac_mc_get_poll_msec(void) + { + return edac_mc_poll_msec; + } + + static int edac_set_poll_msec(const char *val, struct kernel_param *kp) + { +- unsigned long l; ++ unsigned int i; + int ret; + + if (!val) + return -EINVAL; + +- ret = kstrtoul(val, 0, &l); ++ ret = kstrtouint(val, 0, &i); + if (ret) + return ret; + +- if (l < 1000) ++ if (i < 1000) + return -EINVAL; + +- *((unsigned long *)kp->arg) = l; ++ *((unsigned int *)kp->arg) = i; + + /* notify edac_mc engine to reset the poll period */ +- edac_mc_reset_delay_period(l); ++ edac_mc_reset_delay_period(i); + + return 0; + } +@@ -82,7 +82,7 @@ MODULE_PARM_DESC(edac_mc_log_ue, + module_param(edac_mc_log_ce, int, 0644); + MODULE_PARM_DESC(edac_mc_log_ce, + "Log correctable error to console: 0=off 1=on"); +-module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_int, ++module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_uint, + &edac_mc_poll_msec, 0644); + MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds"); + +--- a/drivers/edac/edac_module.h ++++ b/drivers/edac/edac_module.h +@@ -32,7 +32,7 @@ extern int edac_mc_get_log_ue(void); + extern int edac_mc_get_log_ce(void); + extern int edac_mc_get_panic_on_ue(void); + extern int edac_get_poll_msec(void); +-extern int edac_mc_get_poll_msec(void); ++extern unsigned int edac_mc_get_poll_msec(void); + + unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, + unsigned len); diff --git a/queue-3.16/gpio-omap-fix-lack-of-irqstatus_raw0-for-omap4.patch b/queue-3.16/gpio-omap-fix-lack-of-irqstatus_raw0-for-omap4.patch new file mode 100644 index 00000000..d7904b0c --- /dev/null +++ b/queue-3.16/gpio-omap-fix-lack-of-irqstatus_raw0-for-omap4.patch @@ -0,0 +1,37 @@ +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Mon, 10 Jun 2019 20:10:45 +0300 +Subject: gpio: omap: fix lack of irqstatus_raw0 for OMAP4 + +commit 64ea3e9094a1f13b96c33244a3fb3a0f45690bd2 upstream. + +Commit 384ebe1c2849 ("gpio/omap: Add DT support to GPIO driver") added +the register definition tables to the gpio-omap driver. Subsequently to +that commit, commit 4e962e8998cc ("gpio/omap: remove cpu_is_omapxxxx() +checks from *_runtime_resume()") added definitions for irqstatus_raw* +registers to the legacy OMAP4 definitions, but missed the DT +definitions. + +This causes an unintentional change of behaviour for the 1.101 errata +workaround on OMAP4 platforms. Fix this oversight. + +Fixes: 4e962e8998cc ("gpio/omap: remove cpu_is_omapxxxx() checks from *_runtime_resume()") +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> +Tested-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpio/gpio-omap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpio/gpio-omap.c ++++ b/drivers/gpio/gpio-omap.c +@@ -1568,6 +1568,8 @@ static struct omap_gpio_reg_offs omap4_g + .clr_dataout = OMAP4_GPIO_CLEARDATAOUT, + .irqstatus = OMAP4_GPIO_IRQSTATUS0, + .irqstatus2 = OMAP4_GPIO_IRQSTATUS1, ++ .irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0, ++ .irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1, + .irqenable = OMAP4_GPIO_IRQSTATUSSET0, + .irqenable2 = OMAP4_GPIO_IRQSTATUSSET1, + .set_irqenable = OMAP4_GPIO_IRQSTATUSSET0, diff --git a/queue-3.16/igmp-fix-memory-leak-in-igmpv3_del_delrec.patch b/queue-3.16/igmp-fix-memory-leak-in-igmpv3_del_delrec.patch new file mode 100644 index 00000000..a369cf1e --- /dev/null +++ b/queue-3.16/igmp-fix-memory-leak-in-igmpv3_del_delrec.patch @@ -0,0 +1,75 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Thu, 27 Jun 2019 01:27:01 -0700 +Subject: igmp: fix memory leak in igmpv3_del_delrec() + +commit e5b1c6c6277d5a283290a8c033c72544746f9b5b upstream. + +im->tomb and/or im->sources might not be NULL, but we +currently overwrite their values blindly. + +Using swap() will make sure the following call to kfree_pmc(pmc) +will properly free the psf structures. + +Tested with the C repro provided by syzbot, which basically does : + + socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3 + setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP, "\340\0\0\2\177\0\0\1\0\0\0\0", 12) = 0 + ioctl(3, SIOCSIFFLAGS, {ifr_name="lo", ifr_flags=0}) = 0 + setsockopt(3, SOL_IP, IP_MSFILTER, "\340\0\0\2\177\0\0\1\1\0\0\0\1\0\0\0\377\377\377\377", 20) = 0 + ioctl(3, SIOCSIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP}) = 0 + exit_group(0) = ? + +BUG: memory leak +unreferenced object 0xffff88811450f140 (size 64): + comm "softirq", pid 0, jiffies 4294942448 (age 32.070s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ + backtrace: + [<00000000c7bad083>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] + [<00000000c7bad083>] slab_post_alloc_hook mm/slab.h:439 [inline] + [<00000000c7bad083>] slab_alloc mm/slab.c:3326 [inline] + [<00000000c7bad083>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 + [<000000009acc4151>] kmalloc include/linux/slab.h:547 [inline] + [<000000009acc4151>] kzalloc include/linux/slab.h:742 [inline] + [<000000009acc4151>] ip_mc_add1_src net/ipv4/igmp.c:1976 [inline] + [<000000009acc4151>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2100 + [<000000004ac14566>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2484 + [<0000000052d8f995>] do_ip_setsockopt.isra.0+0x1795/0x1930 net/ipv4/ip_sockglue.c:959 + [<000000004ee1e21f>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1248 + [<0000000066cdfe74>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2618 + [<000000009383a786>] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3126 + [<00000000d8ac0c94>] __sys_setsockopt+0x98/0x120 net/socket.c:2072 + [<000000001b1e9666>] __do_sys_setsockopt net/socket.c:2083 [inline] + [<000000001b1e9666>] __se_sys_setsockopt net/socket.c:2080 [inline] + [<000000001b1e9666>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2080 + [<00000000420d395e>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:301 + [<000000007fd83a4b>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: 24803f38a5c0 ("igmp: do not remove igmp souce list info when set link down") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Cc: Hangbin Liu <liuhangbin@gmail.com> +Reported-by: syzbot+6ca1abd0db68b5173a4f@syzkaller.appspotmail.com +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv4/igmp.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1178,12 +1178,8 @@ static void igmpv3_del_delrec(struct in_ + im->interface = pmc->interface; + im->crcount = in_dev->mr_qrv ?: IGMP_Unsolicited_Report_Count; + if (im->sfmode == MCAST_INCLUDE) { +- im->tomb = pmc->tomb; +- pmc->tomb = NULL; +- +- im->sources = pmc->sources; +- pmc->sources = NULL; +- ++ swap(im->tomb, pmc->tomb); ++ swap(im->sources, pmc->sources); + for (psf = im->sources; psf; psf = psf->sf_next) + psf->sf_crcount = im->crcount; + } diff --git a/queue-3.16/input-psmouse-fix-build-error-of-multiple-definition.patch b/queue-3.16/input-psmouse-fix-build-error-of-multiple-definition.patch new file mode 100644 index 00000000..2a6928e4 --- /dev/null +++ b/queue-3.16/input-psmouse-fix-build-error-of-multiple-definition.patch @@ -0,0 +1,34 @@ +From: YueHaibing <yuehaibing@huawei.com> +Date: Tue, 16 Jul 2019 20:17:20 +0200 +Subject: Input: psmouse - fix build error of multiple definition + +commit 49e6979e7e92cf496105b5636f1df0ac17c159c0 upstream. + +trackpoint_detect() should be static inline while +CONFIG_MOUSE_PS2_TRACKPOINT is not set, otherwise, we build fails: + +drivers/input/mouse/alps.o: In function `trackpoint_detect': +alps.c:(.text+0x8e00): multiple definition of `trackpoint_detect' +drivers/input/mouse/psmouse-base.o:psmouse-base.c:(.text+0x1b50): first defined here + +Reported-by: Hulk Robot <hulkci@huawei.com> +Fixes: 55e3d9224b60 ("Input: psmouse - allow disabing certain protocol extensions") +Signed-off-by: YueHaibing <yuehaibing@huawei.com> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/mouse/trackpoint.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/input/mouse/trackpoint.h ++++ b/drivers/input/mouse/trackpoint.h +@@ -148,7 +148,8 @@ struct trackpoint_data + #ifdef CONFIG_MOUSE_PS2_TRACKPOINT + int trackpoint_detect(struct psmouse *psmouse, bool set_properties); + #else +-inline int trackpoint_detect(struct psmouse *psmouse, bool set_properties) ++static inline int trackpoint_detect(struct psmouse *psmouse, ++ bool set_properties) + { + return -ENOSYS; + } diff --git a/queue-3.16/kvm-x86-vpmu-refine-kvm_pmu-err-msg-when-event-creation-failed.patch b/queue-3.16/kvm-x86-vpmu-refine-kvm_pmu-err-msg-when-event-creation-failed.patch new file mode 100644 index 00000000..6fbc979d --- /dev/null +++ b/queue-3.16/kvm-x86-vpmu-refine-kvm_pmu-err-msg-when-event-creation-failed.patch @@ -0,0 +1,34 @@ +From: Like Xu <like.xu@linux.intel.com> +Date: Thu, 18 Jul 2019 13:35:14 +0800 +Subject: KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed + +commit 6fc3977ccc5d3c22e851f2dce2d3ce2a0a843842 upstream. + +If a perf_event creation fails due to any reason of the host perf +subsystem, it has no chance to log the corresponding event for guest +which may cause abnormal sampling data in guest result. In debug mode, +this message helps to understand the state of vPMC and we may not +limit the number of occurrences but not in a spamming style. + +Suggested-by: Joe Perches <joe@perches.com> +Signed-off-by: Like Xu <like.xu@linux.intel.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kvm/pmu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -187,8 +187,8 @@ static void reprogram_counter(struct kvm + intr ? kvm_perf_overflow_intr : + kvm_perf_overflow, pmc); + if (IS_ERR(event)) { +- printk_once("kvm: pmu event creation failed %ld\n", +- PTR_ERR(event)); ++ pr_debug_ratelimited("kvm_pmu: event creation failed %ld for pmc->idx = %d\n", ++ PTR_ERR(event), pmc->idx); + return; + } + diff --git a/queue-3.16/lib-scatterlist-fix-mapping-iterator-when-sg-offset-is-greater-than.patch b/queue-3.16/lib-scatterlist-fix-mapping-iterator-when-sg-offset-is-greater-than.patch new file mode 100644 index 00000000..3daee7e2 --- /dev/null +++ b/queue-3.16/lib-scatterlist-fix-mapping-iterator-when-sg-offset-is-greater-than.patch @@ -0,0 +1,53 @@ +From: Christophe Leroy <christophe.leroy@c-s.fr> +Date: Mon, 24 Jun 2019 07:20:14 +0000 +Subject: lib/scatterlist: Fix mapping iterator when sg->offset is greater than + PAGE_SIZE + +commit aeb87246537a83c2aff482f3f34a2e0991e02cbc upstream. + +All mapping iterator logic is based on the assumption that sg->offset +is always lower than PAGE_SIZE. + +But there are situations where sg->offset is such that the SG item +is on the second page. In that case sg_copy_to_buffer() fails +properly copying the data into the buffer. One of the reason is +that the data will be outside the kmapped area used to access that +data. + +This patch fixes the issue by adjusting the mapping iterator +offset and pgoffset fields such that offset is always lower than +PAGE_SIZE. + +Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> +Fixes: 4225fc8555a9 ("lib/scatterlist: use page iterator in the mapping iterator") +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + lib/scatterlist.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/lib/scatterlist.c ++++ b/lib/scatterlist.c +@@ -459,17 +459,18 @@ static bool sg_miter_get_next_page(struc + { + if (!miter->__remaining) { + struct scatterlist *sg; +- unsigned long pgoffset; + + if (!__sg_page_iter_next(&miter->piter)) + return false; + + sg = miter->piter.sg; +- pgoffset = miter->piter.sg_pgoffset; + +- miter->__offset = pgoffset ? 0 : sg->offset; ++ miter->__offset = miter->piter.sg_pgoffset ? 0 : sg->offset; ++ miter->piter.sg_pgoffset += miter->__offset >> PAGE_SHIFT; ++ miter->__offset &= PAGE_SIZE - 1; + miter->__remaining = sg->offset + sg->length - +- (pgoffset << PAGE_SHIFT) - miter->__offset; ++ (miter->piter.sg_pgoffset << PAGE_SHIFT) - ++ miter->__offset; + miter->__remaining = min_t(unsigned long, miter->__remaining, + PAGE_SIZE - miter->__offset); + } diff --git a/queue-3.16/media-v4l2-test-type-instead-of-cfg-type-in-v4l2_ctrl_new_custom.patch b/queue-3.16/media-v4l2-test-type-instead-of-cfg-type-in-v4l2_ctrl_new_custom.patch new file mode 100644 index 00000000..d2dab1f3 --- /dev/null +++ b/queue-3.16/media-v4l2-test-type-instead-of-cfg-type-in-v4l2_ctrl_new_custom.patch @@ -0,0 +1,42 @@ +From: Boris Brezillon <boris.brezillon@collabora.com> +Date: Wed, 19 Jun 2019 05:21:33 -0400 +Subject: media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() + +commit 07d89227a983df957a6a7c56f7c040cde9ac571f upstream. + +cfg->type can be overridden by v4l2_ctrl_fill() and the new value is +stored in the local type var. Fix the tests to use this local var. + +Fixes: 0996517cf8ea ("V4L/DVB: v4l2: Add new control handling framework") +Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> +[hverkuil-cisco@xs4all.nl: change to !qmenu and !qmenu_int (checkpatch)] +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/v4l2-core/v4l2-ctrls.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -1747,16 +1747,15 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(s + v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, + &def, &flags); + +- is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU || +- cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU); ++ is_menu = (type == V4L2_CTRL_TYPE_MENU || ++ type == V4L2_CTRL_TYPE_INTEGER_MENU); + if (is_menu) + WARN_ON(step); + else + WARN_ON(cfg->menu_skip_mask); +- if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ++ if (type == V4L2_CTRL_TYPE_MENU && !qmenu) { + qmenu = v4l2_ctrl_get_menu(cfg->id); +- else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU && +- qmenu_int == NULL) { ++ } else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) { + handler_set_err(hdl, -EINVAL); + return NULL; + } diff --git a/queue-3.16/memstick-fix-error-cleanup-path-of-memstick_init.patch b/queue-3.16/memstick-fix-error-cleanup-path-of-memstick_init.patch new file mode 100644 index 00000000..93c5a48a --- /dev/null +++ b/queue-3.16/memstick-fix-error-cleanup-path-of-memstick_init.patch @@ -0,0 +1,69 @@ +From: Wang Hai <wanghai26@huawei.com> +Date: Wed, 15 May 2019 22:37:25 +0800 +Subject: memstick: Fix error cleanup path of memstick_init + +commit 65f1a0d39c289bb6fc85635528cd36c4b07f560e upstream. + +If bus_register fails. On its error handling path, it has cleaned up +what it has done. There is no need to call bus_unregister again. +Otherwise, if bus_unregister is called, issues such as null-ptr-deref +will arise. + +Syzkaller report this: + +kobject_add_internal failed for memstick (error: -12 parent: bus) +BUG: KASAN: null-ptr-deref in sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 +Read of size 8 at addr 0000000000000078 by task syz-executor.0/4460 + +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0xa9/0x10e lib/dump_stack.c:113 + __kasan_report+0x171/0x18d mm/kasan/report.c:321 + kasan_report+0xe/0x20 mm/kasan/common.c:614 + sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 + sysfs_remove_file include/linux/sysfs.h:519 [inline] + bus_remove_file+0x6c/0x90 drivers/base/bus.c:145 + remove_probe_files drivers/base/bus.c:599 [inline] + bus_unregister+0x6e/0x100 drivers/base/bus.c:916 ? 0xffffffffc1590000 + memstick_init+0x7a/0x1000 [memstick] + do_one_initcall+0xb9/0x3b5 init/main.c:914 + do_init_module+0xe0/0x330 kernel/module.c:3468 + load_module+0x38eb/0x4270 kernel/module.c:3819 + __do_sys_finit_module+0x162/0x190 kernel/module.c:3909 + do_syscall_64+0x72/0x2a0 arch/x86/entry/common.c:298 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support") +Reported-by: Hulk Robot <hulkci@huawei.com> +Signed-off-by: Wang Hai <wanghai26@huawei.com> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/memstick/core/memstick.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/memstick/core/memstick.c ++++ b/drivers/memstick/core/memstick.c +@@ -626,13 +626,18 @@ static int __init memstick_init(void) + return -ENOMEM; + + rc = bus_register(&memstick_bus_type); +- if (!rc) +- rc = class_register(&memstick_host_class); ++ if (rc) ++ goto error_destroy_workqueue; + +- if (!rc) +- return 0; ++ rc = class_register(&memstick_host_class); ++ if (rc) ++ goto error_bus_unregister; + ++ return 0; ++ ++error_bus_unregister: + bus_unregister(&memstick_bus_type); ++error_destroy_workqueue: + destroy_workqueue(workqueue); + + return rc; diff --git a/queue-3.16/mm-mmu_notifier-use-hlist_add_head_rcu.patch b/queue-3.16/mm-mmu_notifier-use-hlist_add_head_rcu.patch new file mode 100644 index 00000000..a04a2327 --- /dev/null +++ b/queue-3.16/mm-mmu_notifier-use-hlist_add_head_rcu.patch @@ -0,0 +1,63 @@ +From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> +Date: Thu, 11 Jul 2019 20:58:50 -0700 +Subject: mm/mmu_notifier: use hlist_add_head_rcu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 543bdb2d825fe2400d6e951f1786d92139a16931 upstream. + +Make mmu_notifier_register() safer by issuing a memory barrier before +registering a new notifier. This fixes a theoretical bug on weakly +ordered CPUs. For example, take this simplified use of notifiers by a +driver: + + my_struct->mn.ops = &my_ops; /* (1) */ + mmu_notifier_register(&my_struct->mn, mm) + ... + hlist_add_head(&mn->hlist, &mm->mmu_notifiers); /* (2) */ + ... + +Once mmu_notifier_register() releases the mm locks, another thread can +invalidate a range: + + mmu_notifier_invalidate_range() + ... + hlist_for_each_entry_rcu(mn, &mm->mmu_notifiers, hlist) { + if (mn->ops->invalidate_range) + +The read side relies on the data dependency between mn and ops to ensure +that the pointer is properly initialized. But the write side doesn't have +any dependency between (1) and (2), so they could be reordered and the +readers could dereference an invalid mn->ops. mmu_notifier_register() +does take all the mm locks before adding to the hlist, but those have +acquire semantics which isn't sufficient. + +By calling hlist_add_head_rcu() instead of hlist_add_head() we update the +hlist using a store-release, ensuring that readers see prior +initialization of my_struct. This situation is better illustated by +litmus test MP+onceassign+derefonce. + +Link: http://lkml.kernel.org/r/20190502133532.24981-1-jean-philippe.brucker@arm.com +Fixes: cddb8a5c14aa ("mmu-notifiers: core") +Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> +Cc: Jérôme Glisse <jglisse@redhat.com> +Cc: Michal Hocko <mhocko@suse.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/mmu_notifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mmu_notifier.c ++++ b/mm/mmu_notifier.c +@@ -224,7 +224,7 @@ static int do_mmu_notifier_register(stru + * thanks to mm_take_all_locks(). + */ + spin_lock(&mm->mmu_notifier_mm->lock); +- hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); ++ hlist_add_head_rcu(&mn->hlist, &mm->mmu_notifier_mm->list); + spin_unlock(&mm->mmu_notifier_mm->lock); + + mm_drop_all_locks(mm); diff --git a/queue-3.16/mwifiex-don-t-abort-on-small-spec-compliant-vendor-ies.patch b/queue-3.16/mwifiex-don-t-abort-on-small-spec-compliant-vendor-ies.patch new file mode 100644 index 00000000..61050d9e --- /dev/null +++ b/queue-3.16/mwifiex-don-t-abort-on-small-spec-compliant-vendor-ies.patch @@ -0,0 +1,136 @@ +From: Brian Norris <briannorris@chromium.org> +Date: Fri, 14 Jun 2019 17:13:20 -0700 +Subject: mwifiex: Don't abort on small, spec-compliant vendor IEs + +commit 63d7ef36103d26f20325a921ecc96a3288560146 upstream. + +Per the 802.11 specification, vendor IEs are (at minimum) only required +to contain an OUI. A type field is also included in ieee80211.h (struct +ieee80211_vendor_ie) but doesn't appear in the specification. The +remaining fields (subtype, version) are a convention used in WMM +headers. + +Thus, we should not reject vendor-specific IEs that have only the +minimum length (3 bytes) -- we should skip over them (since we only want +to match longer IEs, that match either WMM or WPA formats). We can +reject elements that don't have the minimum-required 3 byte OUI. + +While we're at it, move the non-standard subtype and version fields into +the WMM structs, to avoid this confusion in the future about generic +"vendor header" attributes. + +Fixes: 685c9b7750bf ("mwifiex: Abort at too short BSS descriptor element") +Cc: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Brian Norris <briannorris@chromium.org> +Reviewed-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +[bwh: Backported to 3.16: adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/wireless/mwifiex/fw.h | 12 +++++++++--- + drivers/net/wireless/mwifiex/scan.c | 18 +++++++++++------- + drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++-- + drivers/net/wireless/mwifiex/wmm.c | 2 +- + 4 files changed, 23 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/mwifiex/fw.h ++++ b/drivers/net/wireless/mwifiex/fw.h +@@ -1398,9 +1398,10 @@ struct mwifiex_ie_types_wmm_queue_status + struct ieee_types_vendor_header { + u8 element_id; + u8 len; +- u8 oui[4]; /* 0~2: oui, 3: oui_type */ +- u8 oui_subtype; +- u8 version; ++ struct { ++ u8 oui[3]; ++ u8 oui_type; ++ } __packed oui; + } __packed; + + struct ieee_types_wmm_parameter { +@@ -1414,6 +1415,9 @@ struct ieee_types_wmm_parameter { + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; ++ u8 oui_subtype; ++ u8 version; ++ + u8 qos_info_bitmap; + u8 reserved; + struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS]; +@@ -1431,6 +1435,8 @@ struct ieee_types_wmm_info { + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; ++ u8 oui_subtype; ++ u8 version; + + u8 qos_info_bitmap; + } __packed; +--- a/drivers/net/wireless/mwifiex/scan.c ++++ b/drivers/net/wireless/mwifiex/scan.c +@@ -1284,21 +1284,25 @@ int mwifiex_update_bss_desc_with_ie(stru + break; + + case WLAN_EID_VENDOR_SPECIFIC: +- if (element_len + 2 < sizeof(vendor_ie->vend_hdr)) +- return -EINVAL; +- + vendor_ie = (struct ieee_types_vendor_specific *) + current_ptr; + +- if (!memcmp +- (vendor_ie->vend_hdr.oui, wpa_oui, +- sizeof(wpa_oui))) { ++ /* 802.11 requires at least 3-byte OUI. */ ++ if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui)) ++ return -EINVAL; ++ ++ /* Not long enough for a match? Skip it. */ ++ if (element_len < sizeof(wpa_oui)) ++ break; ++ ++ if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui, ++ sizeof(wpa_oui))) { + bss_entry->bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + current_ptr; + bss_entry->wpa_offset = (u16) + (current_ptr - bss_entry->beacon_buf); +- } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, ++ } else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui, + sizeof(wmm_oui))) { + if (total_ie_len == + sizeof(struct ieee_types_wmm_parameter) || +--- a/drivers/net/wireless/mwifiex/sta_ioctl.c ++++ b/drivers/net/wireless/mwifiex/sta_ioctl.c +@@ -1318,7 +1318,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex + pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; + /* Test to see if it is a WPA IE, if not, then it is a gen IE */ + if (((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && +- (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || ++ (!memcmp(&pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || + (pvendor_ie->element_id == WLAN_EID_RSN)) { + + /* IE is a WPA/WPA2 IE so call set_wpa function */ +@@ -1343,7 +1343,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex + */ + pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; + if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && +- (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { ++ (!memcmp(&pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { + priv->wps.session_enable = true; + dev_dbg(priv->adapter->dev, + "info: WPS Session Enabled.\n"); +--- a/drivers/net/wireless/mwifiex/wmm.c ++++ b/drivers/net/wireless/mwifiex/wmm.c +@@ -241,7 +241,7 @@ mwifiex_wmm_setup_queue_priorities(struc + + dev_dbg(priv->adapter->dev, "info: WMM Parameter IE: version=%d, " + "qos_info Parameter Set Count=%d, Reserved=%#x\n", +- wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap & ++ wmm_ie->version, wmm_ie->qos_info_bitmap & + IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK, + wmm_ie->reserved); + diff --git a/queue-3.16/mwifiex-fix-802.11n-wpa-detection.patch b/queue-3.16/mwifiex-fix-802.11n-wpa-detection.patch new file mode 100644 index 00000000..be082b9e --- /dev/null +++ b/queue-3.16/mwifiex-fix-802.11n-wpa-detection.patch @@ -0,0 +1,48 @@ +From: Brian Norris <briannorris@chromium.org> +Date: Wed, 24 Jul 2019 12:46:34 -0700 +Subject: mwifiex: fix 802.11n/WPA detection + +commit df612421fe2566654047769c6852ffae1a31df16 upstream. + +Commit 63d7ef36103d ("mwifiex: Don't abort on small, spec-compliant +vendor IEs") adjusted the ieee_types_vendor_header struct, which +inadvertently messed up the offsets used in +mwifiex_is_wpa_oui_present(). Add that offset back in, mirroring +mwifiex_is_rsn_oui_present(). + +As it stands, commit 63d7ef36103d breaks compatibility with WPA (not +WPA2) 802.11n networks, since we hit the "info: Disable 11n if AES is +not supported by AP" case in mwifiex_is_network_compatible(). + +Fixes: 63d7ef36103d ("mwifiex: Don't abort on small, spec-compliant vendor IEs") +Signed-off-by: Brian Norris <briannorris@chromium.org> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +[bwh: Backported to 3.16: adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/wireless/mwifiex/main.h | 1 + + drivers/net/wireless/mwifiex/scan.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/mwifiex/main.h ++++ b/drivers/net/wireless/mwifiex/main.h +@@ -94,6 +94,7 @@ enum { + + #define MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN 2 + ++#define WPA_GTK_OUI_OFFSET 2 + #define RSN_GTK_OUI_OFFSET 2 + + #define MWIFIEX_OUI_NOT_PRESENT 0 +--- a/drivers/net/wireless/mwifiex/scan.c ++++ b/drivers/net/wireless/mwifiex/scan.c +@@ -151,7 +151,8 @@ mwifiex_is_wpa_oui_present(struct mwifie + if (((bss_desc->bcn_wpa_ie) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == + WLAN_EID_VENDOR_SPECIFIC))) { +- iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; ++ iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data + ++ WPA_GTK_OUI_OFFSET); + oui = &mwifiex_wpa_oui[cipher][0]; + ret = mwifiex_search_oui_in_ie(iebody, oui); + if (ret) diff --git a/queue-3.16/net-bridge-stp-don-t-cache-eth-dest-pointer-before-skb-pull.patch b/queue-3.16/net-bridge-stp-don-t-cache-eth-dest-pointer-before-skb-pull.patch new file mode 100644 index 00000000..b9fea0e1 --- /dev/null +++ b/queue-3.16/net-bridge-stp-don-t-cache-eth-dest-pointer-before-skb-pull.patch @@ -0,0 +1,35 @@ +From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> +Date: Tue, 2 Jul 2019 15:00:21 +0300 +Subject: net: bridge: stp: don't cache eth dest pointer before skb pull + +commit 2446a68ae6a8cee6d480e2f5b52f5007c7c41312 upstream. + +Don't cache eth dest pointer before calling pskb_may_pull. + +Fixes: cf0f02d04a83 ("[BRIDGE]: use llc for receiving STP packets") +Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/bridge/br_stp_bpdu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/bridge/br_stp_bpdu.c ++++ b/net/bridge/br_stp_bpdu.c +@@ -140,7 +140,6 @@ void br_send_tcn_bpdu(struct net_bridge_ + void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, + struct net_device *dev) + { +- const unsigned char *dest = eth_hdr(skb)->h_dest; + struct net_bridge_port *p; + struct net_bridge *br; + const unsigned char *buf; +@@ -169,7 +168,7 @@ void br_stp_rcv(const struct stp_proto * + if (p->state == BR_STATE_DISABLED) + goto out; + +- if (!ether_addr_equal(dest, br->group_addr)) ++ if (!ether_addr_equal(eth_hdr(skb)->h_dest, br->group_addr)) + goto out; + + if (p->flags & BR_BPDU_GUARD) { diff --git a/queue-3.16/net-neigh-fix-multiple-neigh-timer-scheduling.patch b/queue-3.16/net-neigh-fix-multiple-neigh-timer-scheduling.patch new file mode 100644 index 00000000..25ab8956 --- /dev/null +++ b/queue-3.16/net-neigh-fix-multiple-neigh-timer-scheduling.patch @@ -0,0 +1,89 @@ +From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Date: Sun, 14 Jul 2019 23:36:11 +0200 +Subject: net: neigh: fix multiple neigh timer scheduling + +commit 071c37983d99da07797294ea78e9da1a6e287144 upstream. + +Neigh timer can be scheduled multiple times from userspace adding +multiple neigh entries and forcing the neigh timer scheduling passing +NTF_USE in the netlink requests. +This will result in a refcount leak and in the following dump stack: + +[ 32.465295] NEIGH: BUG, double timer add, state is 8 +[ 32.465308] CPU: 0 PID: 416 Comm: double_timer_ad Not tainted 5.2.0+ #65 +[ 32.465311] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-2.fc30 04/01/2014 +[ 32.465313] Call Trace: +[ 32.465318] dump_stack+0x7c/0xc0 +[ 32.465323] __neigh_event_send+0x20c/0x880 +[ 32.465326] ? ___neigh_create+0x846/0xfb0 +[ 32.465329] ? neigh_lookup+0x2a9/0x410 +[ 32.465332] ? neightbl_fill_info.constprop.0+0x800/0x800 +[ 32.465334] neigh_add+0x4f8/0x5e0 +[ 32.465337] ? neigh_xmit+0x620/0x620 +[ 32.465341] ? find_held_lock+0x85/0xa0 +[ 32.465345] rtnetlink_rcv_msg+0x204/0x570 +[ 32.465348] ? rtnl_dellink+0x450/0x450 +[ 32.465351] ? mark_held_locks+0x90/0x90 +[ 32.465354] ? match_held_lock+0x1b/0x230 +[ 32.465357] netlink_rcv_skb+0xc4/0x1d0 +[ 32.465360] ? rtnl_dellink+0x450/0x450 +[ 32.465363] ? netlink_ack+0x420/0x420 +[ 32.465366] ? netlink_deliver_tap+0x115/0x560 +[ 32.465369] ? __alloc_skb+0xc9/0x2f0 +[ 32.465372] netlink_unicast+0x270/0x330 +[ 32.465375] ? netlink_attachskb+0x2f0/0x2f0 +[ 32.465378] netlink_sendmsg+0x34f/0x5a0 +[ 32.465381] ? netlink_unicast+0x330/0x330 +[ 32.465385] ? move_addr_to_kernel.part.0+0x20/0x20 +[ 32.465388] ? netlink_unicast+0x330/0x330 +[ 32.465391] sock_sendmsg+0x91/0xa0 +[ 32.465394] ___sys_sendmsg+0x407/0x480 +[ 32.465397] ? copy_msghdr_from_user+0x200/0x200 +[ 32.465401] ? _raw_spin_unlock_irqrestore+0x37/0x40 +[ 32.465404] ? lockdep_hardirqs_on+0x17d/0x250 +[ 32.465407] ? __wake_up_common_lock+0xcb/0x110 +[ 32.465410] ? __wake_up_common+0x230/0x230 +[ 32.465413] ? netlink_bind+0x3e1/0x490 +[ 32.465416] ? netlink_setsockopt+0x540/0x540 +[ 32.465420] ? __fget_light+0x9c/0xf0 +[ 32.465423] ? sockfd_lookup_light+0x8c/0xb0 +[ 32.465426] __sys_sendmsg+0xa5/0x110 +[ 32.465429] ? __ia32_sys_shutdown+0x30/0x30 +[ 32.465432] ? __fd_install+0xe1/0x2c0 +[ 32.465435] ? lockdep_hardirqs_off+0xb5/0x100 +[ 32.465438] ? mark_held_locks+0x24/0x90 +[ 32.465441] ? do_syscall_64+0xf/0x270 +[ 32.465444] do_syscall_64+0x63/0x270 +[ 32.465448] entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Fix the issue unscheduling neigh_timer if selected entry is in 'IN_TIMER' +receiving a netlink request with NTF_USE flag set + +Reported-by: Marek Majkowski <marek@cloudflare.com> +Fixes: 0c5c2d308906 ("neigh: Allow for user space users of the neighbour table") +Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Reviewed-by: David Ahern <dsahern@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/core/neighbour.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -995,6 +995,7 @@ int __neigh_event_send(struct neighbour + + atomic_set(&neigh->probes, + NEIGH_VAR(neigh->parms, UCAST_PROBES)); ++ neigh_del_timer(neigh); + neigh->nud_state = NUD_INCOMPLETE; + neigh->updated = now; + next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), +@@ -1011,6 +1012,7 @@ int __neigh_event_send(struct neighbour + } + } else if (neigh->nud_state & NUD_STALE) { + neigh_dbg(2, "neigh %p is delayed\n", neigh); ++ neigh_del_timer(neigh); + neigh->nud_state = NUD_DELAY; + neigh->updated = jiffies; + neigh_add_timer(neigh, jiffies + diff --git a/queue-3.16/nfsv4-handle-the-special-linux-file-open-access-mode.patch b/queue-3.16/nfsv4-handle-the-special-linux-file-open-access-mode.patch new file mode 100644 index 00000000..c43d4fd1 --- /dev/null +++ b/queue-3.16/nfsv4-handle-the-special-linux-file-open-access-mode.patch @@ -0,0 +1,44 @@ +From: Trond Myklebust <trond.myklebust@hammerspace.com> +Date: Thu, 27 Jun 2019 06:41:45 -0400 +Subject: NFSv4: Handle the special Linux file open access mode + +commit 44942b4e457beda00981f616402a1a791e8c616e upstream. + +According to the open() manpage, Linux reserves the access mode 3 +to mean "check for read and write permission on the file and return +a file descriptor that can't be used for reading or writing." + +Currently, the NFSv4 code will ask the server to open the file, +and will use an incorrect share access mode of 0. Since it has +an incorrect share access mode, the client later forgets to send +a corresponding close, meaning it can leak stateids on the server. + +Fixes: ce4ef7c0a8a05 ("NFS: Split out NFS v4 file operations") +Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/nfs/inode.c | 1 + + fs/nfs/nfs4file.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -893,6 +893,7 @@ int nfs_open(struct inode *inode, struct + nfs_fscache_open_file(inode, filp); + return 0; + } ++EXPORT_SYMBOL_GPL(nfs_open); + + int nfs_release(struct inode *inode, struct file *filp) + { +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -34,7 +34,7 @@ nfs4_file_open(struct inode *inode, stru + dprintk("NFS: open file(%pd2)\n", dentry); + + if ((openflags & O_ACCMODE) == 3) +- openflags--; ++ return nfs_open(inode, filp); + + /* We can't create new files here */ + openflags &= ~(O_CREAT|O_EXCL); diff --git a/queue-3.16/padata-use-smp_mb-in-padata_reorder-to-avoid-orphaned-padata-jobs.patch b/queue-3.16/padata-use-smp_mb-in-padata_reorder-to-avoid-orphaned-padata-jobs.patch new file mode 100644 index 00000000..d51e82a6 --- /dev/null +++ b/queue-3.16/padata-use-smp_mb-in-padata_reorder-to-avoid-orphaned-padata-jobs.patch @@ -0,0 +1,112 @@ +From: Daniel Jordan <daniel.m.jordan@oracle.com> +Date: Tue, 16 Jul 2019 12:32:53 -0400 +Subject: padata: use smp_mb in padata_reorder to avoid orphaned padata jobs + +commit cf144f81a99d1a3928f90b0936accfd3f45c9a0a upstream. + +Testing padata with the tcrypt module on a 5.2 kernel... + + # modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3 + # modprobe tcrypt mode=211 sec=1 + +...produces this splat: + + INFO: task modprobe:10075 blocked for more than 120 seconds. + Not tainted 5.2.0-base+ #16 + modprobe D 0 10075 10064 0x80004080 + Call Trace: + ? __schedule+0x4dd/0x610 + ? ring_buffer_unlock_commit+0x23/0x100 + schedule+0x6c/0x90 + schedule_timeout+0x3b/0x320 + ? trace_buffer_unlock_commit_regs+0x4f/0x1f0 + wait_for_common+0x160/0x1a0 + ? wake_up_q+0x80/0x80 + { crypto_wait_req } # entries in braces added by hand + { do_one_aead_op } + { test_aead_jiffies } + test_aead_speed.constprop.17+0x681/0xf30 [tcrypt] + do_test+0x4053/0x6a2b [tcrypt] + ? 0xffffffffa00f4000 + tcrypt_mod_init+0x50/0x1000 [tcrypt] + ... + +The second modprobe command never finishes because in padata_reorder, +CPU0's load of reorder_objects is executed before the unlocking store in +spin_unlock_bh(pd->lock), causing CPU0 to miss CPU1's increment: + +CPU0 CPU1 + +padata_reorder padata_do_serial + LOAD reorder_objects // 0 + INC reorder_objects // 1 + padata_reorder + TRYLOCK pd->lock // failed + UNLOCK pd->lock + +CPU0 deletes the timer before returning from padata_reorder and since no +other job is submitted to padata, modprobe waits indefinitely. + +Add a pair of full barriers to guarantee proper ordering: + +CPU0 CPU1 + +padata_reorder padata_do_serial + UNLOCK pd->lock + smp_mb() + LOAD reorder_objects + INC reorder_objects + smp_mb__after_atomic() + padata_reorder + TRYLOCK pd->lock + +smp_mb__after_atomic is needed so the read part of the trylock operation +comes after the INC, as Andrea points out. Thanks also to Andrea for +help with writing a litmus test. + +Fixes: 16295bec6398 ("padata: Generic parallelization/serialization interface") +Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com> +Cc: Andrea Parri <andrea.parri@amarulasolutions.com> +Cc: Boqun Feng <boqun.feng@gmail.com> +Cc: Herbert Xu <herbert@gondor.apana.org.au> +Cc: Paul E. McKenney <paulmck@linux.ibm.com> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Steffen Klassert <steffen.klassert@secunet.com> +Cc: linux-arch@vger.kernel.org +Cc: linux-crypto@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/padata.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -272,7 +272,12 @@ static void padata_reorder(struct parall + * The next object that needs serialization might have arrived to + * the reorder queues in the meantime, we will be called again + * from the timer function if no one else cares for it. ++ * ++ * Ensure reorder_objects is read after pd->lock is dropped so we see ++ * an increment from another task in padata_do_serial. Pairs with ++ * smp_mb__after_atomic in padata_do_serial. + */ ++ smp_mb(); + if (atomic_read(&pd->reorder_objects) + && !(pinst->flags & PADATA_RESET)) + mod_timer(&pd->timer, jiffies + HZ); +@@ -341,6 +346,13 @@ void padata_do_serial(struct padata_priv + list_add_tail(&padata->list, &pqueue->reorder.list); + spin_unlock(&pqueue->reorder.lock); + ++ /* ++ * Ensure the atomic_inc of reorder_objects above is ordered correctly ++ * with the trylock of pd->lock in padata_reorder. Pairs with smp_mb ++ * in padata_reorder. ++ */ ++ smp_mb__after_atomic(); ++ + put_cpu(); + + padata_reorder(pd); diff --git a/queue-3.16/parisc-fix-kernel-panic-due-invalid-values-in-iaoq0-or-iaoq1.patch b/queue-3.16/parisc-fix-kernel-panic-due-invalid-values-in-iaoq0-or-iaoq1.patch new file mode 100644 index 00000000..ec084098 --- /dev/null +++ b/queue-3.16/parisc-fix-kernel-panic-due-invalid-values-in-iaoq0-or-iaoq1.patch @@ -0,0 +1,79 @@ +From: Helge Deller <deller@gmx.de> +Date: Tue, 16 Jul 2019 21:43:11 +0200 +Subject: parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 + +commit 10835c854685393a921b68f529bf740fa7c9984d upstream. + +On parisc the privilege level of a process is stored in the lowest two bits of +the instruction pointers (IAOQ0 and IAOQ1). On Linux we use privilege level 0 +for the kernel and privilege level 3 for user-space. So userspace should not be +allowed to modify IAOQ0 or IAOQ1 of a ptraced process to change it's privilege +level to e.g. 0 to try to gain kernel privileges. + +This patch prevents such modifications by always setting the two lowest bits to +one (which relates to privilege level 3 for user-space) if IAOQ0 or IAOQ1 are +modified via ptrace calls in the native and compat ptrace paths. + +Link: https://bugs.gentoo.org/481768 +Reported-by: Jeroen Roovers <jer@gentoo.org> +Tested-by: Rolf Eike Beer <eike-kernel@sf-tec.de> +Signed-off-by: Helge Deller <deller@gmx.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/parisc/kernel/ptrace.c | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +--- a/arch/parisc/kernel/ptrace.c ++++ b/arch/parisc/kernel/ptrace.c +@@ -155,6 +155,9 @@ long arch_ptrace(struct task_struct *chi + if ((addr & (sizeof(unsigned long)-1)) || + addr >= sizeof(struct pt_regs)) + break; ++ if (addr == PT_IAOQ0 || addr == PT_IAOQ1) { ++ data |= 3; /* ensure userspace privilege */ ++ } + if ((addr >= PT_GR1 && addr <= PT_GR31) || + addr == PT_IAOQ0 || addr == PT_IAOQ1 || + (addr >= PT_FR0 && addr <= PT_FR31 + 4) || +@@ -188,16 +191,18 @@ long arch_ptrace(struct task_struct *chi + + static compat_ulong_t translate_usr_offset(compat_ulong_t offset) + { +- if (offset < 0) +- return sizeof(struct pt_regs); +- else if (offset <= 32*4) /* gr[0..31] */ +- return offset * 2 + 4; +- else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */ +- return offset + 32*4; +- else if (offset < sizeof(struct pt_regs)/2 + 32*4) +- return offset * 2 + 4 - 32*8; ++ compat_ulong_t pos; ++ ++ if (offset < 32*4) /* gr[0..31] */ ++ pos = offset * 2 + 4; ++ else if (offset < 32*4+32*8) /* fr[0] ... fr[31] */ ++ pos = (offset - 32*4) + PT_FR0; ++ else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */ ++ pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4; + else +- return sizeof(struct pt_regs); ++ pos = sizeof(struct pt_regs); ++ ++ return pos; + } + + long compat_arch_ptrace(struct task_struct *child, compat_long_t request, +@@ -241,9 +246,12 @@ long compat_arch_ptrace(struct task_stru + addr = translate_usr_offset(addr); + if (addr >= sizeof(struct pt_regs)) + break; ++ if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) { ++ data |= 3; /* ensure userspace privilege */ ++ } + if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { + /* Special case, fp regs are 64 bits anyway */ +- *(__u64 *) ((char *) task_regs(child) + addr) = data; ++ *(__u32 *) ((char *) task_regs(child) + addr) = data; + ret = 0; + } + else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) || diff --git a/queue-3.16/pci-do-not-poll-for-pme-if-the-device-is-in-d3cold.patch b/queue-3.16/pci-do-not-poll-for-pme-if-the-device-is-in-d3cold.patch new file mode 100644 index 00000000..ea0b4863 --- /dev/null +++ b/queue-3.16/pci-do-not-poll-for-pme-if-the-device-is-in-d3cold.patch @@ -0,0 +1,51 @@ +From: Mika Westerberg <mika.westerberg@linux.intel.com> +Date: Wed, 12 Jun 2019 13:57:39 +0300 +Subject: PCI: Do not poll for PME if the device is in D3cold + +commit 000dd5316e1c756a1c028f22e01d06a38249dd4d upstream. + +PME polling does not take into account that a device that is directly +connected to the host bridge may go into D3cold as well. This leads to a +situation where the PME poll thread reads from a config space of a +device that is in D3cold and gets incorrect information because the +config space is not accessible. + +Here is an example from Intel Ice Lake system where two PCIe root ports +are in D3cold (I've instrumented the kernel to log the PMCSR register +contents): + + [ 62.971442] pcieport 0000:00:07.1: Check PME status, PMCSR=0xffff + [ 62.971504] pcieport 0000:00:07.0: Check PME status, PMCSR=0xffff + +Since 0xffff is interpreted so that PME is pending, the root ports will +be runtime resumed. This repeats over and over again essentially +blocking all runtime power management. + +Prevent this from happening by checking whether the device is in D3cold +before its PME status is read. + +Fixes: 71a83bd727cc ("PCI/PM: add runtime PM support to PCIe port") +Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Reviewed-by: Lukas Wunner <lukas@wunner.de> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/pci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1680,6 +1680,13 @@ static void pci_pme_list_scan(struct wor + */ + if (bridge && bridge->current_state != PCI_D0) + continue; ++ /* ++ * If the device is in D3cold it should not be ++ * polled either. ++ */ ++ if (pme_dev->dev->current_state == PCI_D3cold) ++ continue; ++ + pci_pme_wakeup(pme_dev->dev, NULL); + } else { + list_del(&pme_dev->list); diff --git a/queue-3.16/powerpc-32s-fix-suspend-resume-when-ibats-4-7-are-used.patch b/queue-3.16/powerpc-32s-fix-suspend-resume-when-ibats-4-7-are-used.patch new file mode 100644 index 00000000..053996e5 --- /dev/null +++ b/queue-3.16/powerpc-32s-fix-suspend-resume-when-ibats-4-7-are-used.patch @@ -0,0 +1,244 @@ +From: Christophe Leroy <christophe.leroy@c-s.fr> +Date: Mon, 17 Jun 2019 21:42:14 +0000 +Subject: powerpc/32s: fix suspend/resume when IBATs 4-7 are used + +commit 6ecb78ef56e08d2119d337ae23cb951a640dc52d upstream. + +Previously, only IBAT1 and IBAT2 were used to map kernel linear mem. +Since commit 63b2bc619565 ("powerpc/mm/32s: Use BATs for +STRICT_KERNEL_RWX"), we may have all 8 BATs used for mapping +kernel text. But the suspend/restore functions only save/restore +BATs 0 to 3, and clears BATs 4 to 7. + +Make suspend and restore functions respectively save and reload +the 8 BATs on CPUs having MMU_FTR_USE_HIGH_BATS feature. + +Reported-by: Andreas Schwab <schwab@linux-m68k.org> +Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/swsusp_32.S | 73 ++++++++++++++++++++++--- + arch/powerpc/platforms/powermac/sleep.S | 68 +++++++++++++++++++++-- + 2 files changed, 128 insertions(+), 13 deletions(-) + +--- a/arch/powerpc/kernel/swsusp_32.S ++++ b/arch/powerpc/kernel/swsusp_32.S +@@ -23,11 +23,19 @@ + #define SL_IBAT2 0x48 + #define SL_DBAT3 0x50 + #define SL_IBAT3 0x58 +-#define SL_TB 0x60 +-#define SL_R2 0x68 +-#define SL_CR 0x6c +-#define SL_LR 0x70 +-#define SL_R12 0x74 /* r12 to r31 */ ++#define SL_DBAT4 0x60 ++#define SL_IBAT4 0x68 ++#define SL_DBAT5 0x70 ++#define SL_IBAT5 0x78 ++#define SL_DBAT6 0x80 ++#define SL_IBAT6 0x88 ++#define SL_DBAT7 0x90 ++#define SL_IBAT7 0x98 ++#define SL_TB 0xa0 ++#define SL_R2 0xa8 ++#define SL_CR 0xac ++#define SL_LR 0xb0 ++#define SL_R12 0xb4 /* r12 to r31 */ + #define SL_SIZE (SL_R12 + 80) + + .section .data +@@ -112,6 +120,41 @@ _GLOBAL(swsusp_arch_suspend) + mfibatl r4,3 + stw r4,SL_IBAT3+4(r11) + ++BEGIN_MMU_FTR_SECTION ++ mfspr r4,SPRN_DBAT4U ++ stw r4,SL_DBAT4(r11) ++ mfspr r4,SPRN_DBAT4L ++ stw r4,SL_DBAT4+4(r11) ++ mfspr r4,SPRN_DBAT5U ++ stw r4,SL_DBAT5(r11) ++ mfspr r4,SPRN_DBAT5L ++ stw r4,SL_DBAT5+4(r11) ++ mfspr r4,SPRN_DBAT6U ++ stw r4,SL_DBAT6(r11) ++ mfspr r4,SPRN_DBAT6L ++ stw r4,SL_DBAT6+4(r11) ++ mfspr r4,SPRN_DBAT7U ++ stw r4,SL_DBAT7(r11) ++ mfspr r4,SPRN_DBAT7L ++ stw r4,SL_DBAT7+4(r11) ++ mfspr r4,SPRN_IBAT4U ++ stw r4,SL_IBAT4(r11) ++ mfspr r4,SPRN_IBAT4L ++ stw r4,SL_IBAT4+4(r11) ++ mfspr r4,SPRN_IBAT5U ++ stw r4,SL_IBAT5(r11) ++ mfspr r4,SPRN_IBAT5L ++ stw r4,SL_IBAT5+4(r11) ++ mfspr r4,SPRN_IBAT6U ++ stw r4,SL_IBAT6(r11) ++ mfspr r4,SPRN_IBAT6L ++ stw r4,SL_IBAT6+4(r11) ++ mfspr r4,SPRN_IBAT7U ++ stw r4,SL_IBAT7(r11) ++ mfspr r4,SPRN_IBAT7L ++ stw r4,SL_IBAT7+4(r11) ++END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) ++ + #if 0 + /* Backup various CPU config stuffs */ + bl __save_cpu_setup +@@ -277,27 +320,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + mtibatu 3,r4 + lwz r4,SL_IBAT3+4(r11) + mtibatl 3,r4 +-#endif +- + BEGIN_MMU_FTR_SECTION +- li r4,0 ++ lwz r4,SL_DBAT4(r11) + mtspr SPRN_DBAT4U,r4 ++ lwz r4,SL_DBAT4+4(r11) + mtspr SPRN_DBAT4L,r4 ++ lwz r4,SL_DBAT5(r11) + mtspr SPRN_DBAT5U,r4 ++ lwz r4,SL_DBAT5+4(r11) + mtspr SPRN_DBAT5L,r4 ++ lwz r4,SL_DBAT6(r11) + mtspr SPRN_DBAT6U,r4 ++ lwz r4,SL_DBAT6+4(r11) + mtspr SPRN_DBAT6L,r4 ++ lwz r4,SL_DBAT7(r11) + mtspr SPRN_DBAT7U,r4 ++ lwz r4,SL_DBAT7+4(r11) + mtspr SPRN_DBAT7L,r4 ++ lwz r4,SL_IBAT4(r11) + mtspr SPRN_IBAT4U,r4 ++ lwz r4,SL_IBAT4+4(r11) + mtspr SPRN_IBAT4L,r4 ++ lwz r4,SL_IBAT5(r11) + mtspr SPRN_IBAT5U,r4 ++ lwz r4,SL_IBAT5+4(r11) + mtspr SPRN_IBAT5L,r4 ++ lwz r4,SL_IBAT6(r11) + mtspr SPRN_IBAT6U,r4 ++ lwz r4,SL_IBAT6+4(r11) + mtspr SPRN_IBAT6L,r4 ++ lwz r4,SL_IBAT7(r11) + mtspr SPRN_IBAT7U,r4 ++ lwz r4,SL_IBAT7+4(r11) + mtspr SPRN_IBAT7L,r4 + END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) ++#endif + + /* Flush all TLBs */ + lis r4,0x1000 +--- a/arch/powerpc/platforms/powermac/sleep.S ++++ b/arch/powerpc/platforms/powermac/sleep.S +@@ -37,10 +37,18 @@ + #define SL_IBAT2 0x48 + #define SL_DBAT3 0x50 + #define SL_IBAT3 0x58 +-#define SL_TB 0x60 +-#define SL_R2 0x68 +-#define SL_CR 0x6c +-#define SL_R12 0x70 /* r12 to r31 */ ++#define SL_DBAT4 0x60 ++#define SL_IBAT4 0x68 ++#define SL_DBAT5 0x70 ++#define SL_IBAT5 0x78 ++#define SL_DBAT6 0x80 ++#define SL_IBAT6 0x88 ++#define SL_DBAT7 0x90 ++#define SL_IBAT7 0x98 ++#define SL_TB 0xa0 ++#define SL_R2 0xa8 ++#define SL_CR 0xac ++#define SL_R12 0xb0 /* r12 to r31 */ + #define SL_SIZE (SL_R12 + 80) + + .section .text +@@ -125,6 +133,41 @@ _GLOBAL(low_sleep_handler) + mfibatl r4,3 + stw r4,SL_IBAT3+4(r1) + ++BEGIN_MMU_FTR_SECTION ++ mfspr r4,SPRN_DBAT4U ++ stw r4,SL_DBAT4(r1) ++ mfspr r4,SPRN_DBAT4L ++ stw r4,SL_DBAT4+4(r1) ++ mfspr r4,SPRN_DBAT5U ++ stw r4,SL_DBAT5(r1) ++ mfspr r4,SPRN_DBAT5L ++ stw r4,SL_DBAT5+4(r1) ++ mfspr r4,SPRN_DBAT6U ++ stw r4,SL_DBAT6(r1) ++ mfspr r4,SPRN_DBAT6L ++ stw r4,SL_DBAT6+4(r1) ++ mfspr r4,SPRN_DBAT7U ++ stw r4,SL_DBAT7(r1) ++ mfspr r4,SPRN_DBAT7L ++ stw r4,SL_DBAT7+4(r1) ++ mfspr r4,SPRN_IBAT4U ++ stw r4,SL_IBAT4(r1) ++ mfspr r4,SPRN_IBAT4L ++ stw r4,SL_IBAT4+4(r1) ++ mfspr r4,SPRN_IBAT5U ++ stw r4,SL_IBAT5(r1) ++ mfspr r4,SPRN_IBAT5L ++ stw r4,SL_IBAT5+4(r1) ++ mfspr r4,SPRN_IBAT6U ++ stw r4,SL_IBAT6(r1) ++ mfspr r4,SPRN_IBAT6L ++ stw r4,SL_IBAT6+4(r1) ++ mfspr r4,SPRN_IBAT7U ++ stw r4,SL_IBAT7(r1) ++ mfspr r4,SPRN_IBAT7L ++ stw r4,SL_IBAT7+4(r1) ++END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) ++ + /* Backup various CPU config stuffs */ + bl __save_cpu_setup + +@@ -325,22 +368,37 @@ grackle_wake_up: + mtibatl 3,r4 + + BEGIN_MMU_FTR_SECTION +- li r4,0 ++ lwz r4,SL_DBAT4(r1) + mtspr SPRN_DBAT4U,r4 ++ lwz r4,SL_DBAT4+4(r1) + mtspr SPRN_DBAT4L,r4 ++ lwz r4,SL_DBAT5(r1) + mtspr SPRN_DBAT5U,r4 ++ lwz r4,SL_DBAT5+4(r1) + mtspr SPRN_DBAT5L,r4 ++ lwz r4,SL_DBAT6(r1) + mtspr SPRN_DBAT6U,r4 ++ lwz r4,SL_DBAT6+4(r1) + mtspr SPRN_DBAT6L,r4 ++ lwz r4,SL_DBAT7(r1) + mtspr SPRN_DBAT7U,r4 ++ lwz r4,SL_DBAT7+4(r1) + mtspr SPRN_DBAT7L,r4 ++ lwz r4,SL_IBAT4(r1) + mtspr SPRN_IBAT4U,r4 ++ lwz r4,SL_IBAT4+4(r1) + mtspr SPRN_IBAT4L,r4 ++ lwz r4,SL_IBAT5(r1) + mtspr SPRN_IBAT5U,r4 ++ lwz r4,SL_IBAT5+4(r1) + mtspr SPRN_IBAT5L,r4 ++ lwz r4,SL_IBAT6(r1) + mtspr SPRN_IBAT6U,r4 ++ lwz r4,SL_IBAT6+4(r1) + mtspr SPRN_IBAT6L,r4 ++ lwz r4,SL_IBAT7(r1) + mtspr SPRN_IBAT7U,r4 ++ lwz r4,SL_IBAT7+4(r1) + mtspr SPRN_IBAT7L,r4 + END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) + diff --git a/queue-3.16/powerpc-watchpoint-restore-nv-gprs-while-returning-from-exception.patch b/queue-3.16/powerpc-watchpoint-restore-nv-gprs-while-returning-from-exception.patch new file mode 100644 index 00000000..31486b73 --- /dev/null +++ b/queue-3.16/powerpc-watchpoint-restore-nv-gprs-while-returning-from-exception.patch @@ -0,0 +1,111 @@ +From: Ravi Bangoria <ravi.bangoria@linux.ibm.com> +Date: Thu, 13 Jun 2019 09:00:14 +0530 +Subject: powerpc/watchpoint: Restore NV GPRs while returning from exception + +commit f474c28fbcbe42faca4eb415172c07d76adcb819 upstream. + +powerpc hardware triggers watchpoint before executing the instruction. +To make trigger-after-execute behavior, kernel emulates the +instruction. If the instruction is 'load something into non-volatile +register', exception handler should restore emulated register state +while returning back, otherwise there will be register state +corruption. eg, adding a watchpoint on a list can corrput the list: + + # cat /proc/kallsyms | grep kthread_create_list + c00000000121c8b8 d kthread_create_list + +Add watchpoint on kthread_create_list->prev: + + # perf record -e mem:0xc00000000121c8c0 + +Run some workload such that new kthread gets invoked. eg, I just +logged out from console: + + list_add corruption. next->prev should be prev (c000000001214e00), \ + but was c00000000121c8b8. (next=c00000000121c8b8). + WARNING: CPU: 59 PID: 309 at lib/list_debug.c:25 __list_add_valid+0xb4/0xc0 + CPU: 59 PID: 309 Comm: kworker/59:0 Kdump: loaded Not tainted 5.1.0-rc7+ #69 + ... + NIP __list_add_valid+0xb4/0xc0 + LR __list_add_valid+0xb0/0xc0 + Call Trace: + __list_add_valid+0xb0/0xc0 (unreliable) + __kthread_create_on_node+0xe0/0x260 + kthread_create_on_node+0x34/0x50 + create_worker+0xe8/0x260 + worker_thread+0x444/0x560 + kthread+0x160/0x1a0 + ret_from_kernel_thread+0x5c/0x70 + +List corruption happened because it uses 'load into non-volatile +register' instruction: + +Snippet from __kthread_create_on_node: + + c000000000136be8: addis r29,r2,-19 + c000000000136bec: ld r29,31424(r29) + if (!__list_add_valid(new, prev, next)) + c000000000136bf0: mr r3,r30 + c000000000136bf4: mr r5,r28 + c000000000136bf8: mr r4,r29 + c000000000136bfc: bl c00000000059a2f8 <__list_add_valid+0x8> + +Register state from WARN_ON(): + + GPR00: c00000000059a3a0 c000007ff23afb50 c000000001344e00 0000000000000075 + GPR04: 0000000000000000 0000000000000000 0000001852af8bc1 0000000000000000 + GPR08: 0000000000000001 0000000000000007 0000000000000006 00000000000004aa + GPR12: 0000000000000000 c000007ffffeb080 c000000000137038 c000005ff62aaa00 + GPR16: 0000000000000000 0000000000000000 c000007fffbe7600 c000007fffbe7370 + GPR20: c000007fffbe7320 c000007fffbe7300 c000000001373a00 0000000000000000 + GPR24: fffffffffffffef7 c00000000012e320 c000007ff23afcb0 c000000000cb8628 + GPR28: c00000000121c8b8 c000000001214e00 c000007fef5b17e8 c000007fef5b17c0 + +Watchpoint hit at 0xc000000000136bec. + + addis r29,r2,-19 + => r29 = 0xc000000001344e00 + (-19 << 16) + => r29 = 0xc000000001214e00 + + ld r29,31424(r29) + => r29 = *(0xc000000001214e00 + 31424) + => r29 = *(0xc00000000121c8c0) + +0xc00000000121c8c0 is where we placed a watchpoint and thus this +instruction was emulated by emulate_step. But because handle_dabr_fault +did not restore emulated register state, r29 still contains stale +value in above register state. + +Fixes: 5aae8a5370802 ("powerpc, hw_breakpoints: Implement hw_breakpoints for 64-bit server processors") +Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/exceptions-64s.S | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -1630,7 +1630,7 @@ handle_page_fault: + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_page_fault + cmpdi r3,0 +- beq+ 12f ++ beq+ ret_from_except_lite + bl save_nvgprs + mr r5,r3 + addi r3,r1,STACK_FRAME_OVERHEAD +@@ -1645,7 +1645,12 @@ handle_dabr_fault: + ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_break +-12: b ret_from_except_lite ++ /* ++ * do_break() may have changed the NV GPRS while handling a breakpoint. ++ * If so, we need to restore them with their updated values. Don't use ++ * ret_from_except_lite here. ++ */ ++ b ret_from_except + + + /* We have a page fault that hash_page could handle but HV refused diff --git a/queue-3.16/s390-fix-stfle-zero-padding.patch b/queue-3.16/s390-fix-stfle-zero-padding.patch new file mode 100644 index 00000000..a7ba3c2b --- /dev/null +++ b/queue-3.16/s390-fix-stfle-zero-padding.patch @@ -0,0 +1,78 @@ +From: Heiko Carstens <heiko.carstens@de.ibm.com> +Date: Mon, 17 Jun 2019 14:02:41 +0200 +Subject: s390: fix stfle zero padding + +commit 4f18d869ffd056c7858f3d617c71345cf19be008 upstream. + +The stfle inline assembly returns the number of double words written +(condition code 0) or the double words it would have written +(condition code 3), if the memory array it got as parameter would have +been large enough. + +The current stfle implementation assumes that the array is always +large enough and clears those parts of the array that have not been +written to with a subsequent memset call. + +If however the array is not large enough memset will get a negative +length parameter, which means that memset clears memory until it gets +an exception and the kernel crashes. + +To fix this simply limit the maximum length. Move also the inline +assembly to an extra function to avoid clobbering of register 0, which +might happen because of the added min_t invocation together with code +instrumentation. + +The bug was introduced with commit 14375bc4eb8d ("[S390] cleanup +facility list handling") but was rather harmless, since it would only +write to a rather large array. It became a potential problem with +commit 3ab121ab1866 ("[S390] kernel: Add z/VM LGR detection"). Since +then it writes to an array with only four double words, while some +machines already deliver three double words. As soon as machines have +a facility bit within the fifth double a crash on IPL would happen. + +Fixes: 14375bc4eb8d ("[S390] cleanup facility list handling") +Reviewed-by: Vasily Gorbik <gor@linux.ibm.com> +Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> +Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/s390/include/asm/facility.h | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/arch/s390/include/asm/facility.h ++++ b/arch/s390/include/asm/facility.h +@@ -33,6 +33,18 @@ static inline int test_facility(unsigned + return __test_facility(nr, &S390_lowcore.stfle_fac_list); + } + ++static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size) ++{ ++ register unsigned long reg0 asm("0") = size - 1; ++ ++ asm volatile( ++ ".insn s,0xb2b00000,0(%1)" /* stfle */ ++ : "+d" (reg0) ++ : "a" (stfle_fac_list) ++ : "memory", "cc"); ++ return reg0; ++} ++ + /** + * stfle - Store facility list extended + * @stfle_fac_list: array where facility list can be stored +@@ -52,13 +64,8 @@ static inline void stfle(u64 *stfle_fac_ + memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); + if (S390_lowcore.stfl_fac_list & 0x01000000) { + /* More facility bits available with stfle */ +- register unsigned long reg0 asm("0") = size - 1; +- +- asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */ +- : "+d" (reg0) +- : "a" (stfle_fac_list) +- : "memory", "cc"); +- nr = (reg0 + 1) * 8; /* # bytes stored by stfle */ ++ nr = __stfle_asm(stfle_fac_list, size); ++ nr = min_t(unsigned long, (nr + 1) * 8, size * 8); + } + memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); + preempt_enable(); diff --git a/queue-3.16/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch b/queue-3.16/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch new file mode 100644 index 00000000..8c5ce9e2 --- /dev/null +++ b/queue-3.16/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch @@ -0,0 +1,32 @@ +From: Julian Wiedmann <jwi@linux.ibm.com> +Date: Tue, 18 Jun 2019 13:12:20 +0200 +Subject: s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + +commit ac6639cd3db607d386616487902b4cc1850a7be5 upstream. + +Current code sets the dsci to 0x00000080. Which doesn't make any sense, +as the indicator area is located in the _left-most_ byte. + +Worse: if the dsci is the _shared_ indicator, this potentially clears +the indication of activity for a _different_ device. +tiqdio_thinint_handler() will then have no reason to call that device's +IRQ handler, and the device ends up stalling. + +Fixes: d0c9d4a89fff ("[S390] qdio: set correct bit in dsci") +Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> +Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/cio/qdio_thinint.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/s390/cio/qdio_thinint.c ++++ b/drivers/s390/cio/qdio_thinint.c +@@ -80,7 +80,6 @@ void tiqdio_add_input_queues(struct qdio + mutex_lock(&tiq_list_lock); + list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list); + mutex_unlock(&tiq_list_lock); +- xchg(irq_ptr->dsci, 1 << 7); + } + + void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) diff --git a/queue-3.16/s390-qdio-handle-pending-state-for-qebsm-devices.patch b/queue-3.16/s390-qdio-handle-pending-state-for-qebsm-devices.patch new file mode 100644 index 00000000..664c3624 --- /dev/null +++ b/queue-3.16/s390-qdio-handle-pending-state-for-qebsm-devices.patch @@ -0,0 +1,33 @@ +From: Julian Wiedmann <jwi@linux.ibm.com> +Date: Mon, 3 Jun 2019 07:47:04 +0200 +Subject: s390/qdio: handle PENDING state for QEBSM devices + +commit 04310324c6f482921c071444833e70fe861b73d9 upstream. + +When a CQ-enabled device uses QEBSM for SBAL state inspection, +get_buf_states() can return the PENDING state for an Output Queue. +get_outbound_buffer_frontier() isn't prepared for this, and any PENDING +buffer will permanently stall all further completion processing on this +Queue. + +This isn't a concern for non-QEBSM devices, as get_buf_states() for such +devices will manually turn PENDING buffers into EMPTY ones. + +Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") +Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> +Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/cio/qdio_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -752,6 +752,7 @@ static int get_outbound_buffer_frontier( + + switch (state) { + case SLSB_P_OUTPUT_EMPTY: ++ case SLSB_P_OUTPUT_PENDING: + /* the adapter got it */ + DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, + "out empty:%1d %02x", q->nr, count); diff --git a/queue-3.16/s390-qdio-re-initialize-tiqdio-list-entries.patch b/queue-3.16/s390-qdio-re-initialize-tiqdio-list-entries.patch new file mode 100644 index 00000000..3ba9288b --- /dev/null +++ b/queue-3.16/s390-qdio-re-initialize-tiqdio-list-entries.patch @@ -0,0 +1,72 @@ +From: Julian Wiedmann <jwi@linux.ibm.com> +Date: Tue, 18 Jun 2019 11:25:59 +0200 +Subject: s390/qdio: (re-)initialize tiqdio list entries + +commit e54e4785cb5cb4896cf4285964aeef2125612fb2 upstream. + +When tiqdio_remove_input_queues() removes a queue from the tiq_list as +part of qdio_shutdown(), it doesn't re-initialize the queue's list entry +and the prev/next pointers go stale. + +If a subsequent qdio_establish() fails while sending the ESTABLISH cmd, +it calls qdio_shutdown() again in QDIO_IRQ_STATE_ERR state and +tiqdio_remove_input_queues() will attempt to remove the queue entry a +second time. This dereferences the stale pointers, and bad things ensue. +Fix this by re-initializing the list entry after removing it from the +list. + +For good practice also initialize the list entry when the queue is first +allocated, and remove the quirky checks that papered over this omission. +Note that prior to +commit e521813468f7 ("s390/qdio: fix access to uninitialized qdio_q fields"), +these checks were bogus anyway. + +setup_queues_misc() clears the whole queue struct, and thus needs to +re-init the prev/next pointers as well. + +Fixes: 779e6e1c724d ("[S390] qdio: new qdio driver.") +Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> +Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/cio/qdio_setup.c | 2 ++ + drivers/s390/cio/qdio_thinint.c | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -100,6 +100,7 @@ static int __qdio_allocate_qs(struct qdi + return -ENOMEM; + } + irq_ptr_qs[i] = q; ++ INIT_LIST_HEAD(&q->entry); + } + return 0; + } +@@ -128,6 +129,7 @@ static void setup_queues_misc(struct qdi + q->mask = 1 << (31 - i); + q->nr = i; + q->handler = handler; ++ INIT_LIST_HEAD(&q->entry); + } + + static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, +--- a/drivers/s390/cio/qdio_thinint.c ++++ b/drivers/s390/cio/qdio_thinint.c +@@ -88,14 +88,14 @@ void tiqdio_remove_input_queues(struct q + struct qdio_q *q; + + q = irq_ptr->input_qs[0]; +- /* if establish triggered an error */ +- if (!q || !q->entry.prev || !q->entry.next) ++ if (!q) + return; + + mutex_lock(&tiq_list_lock); + list_del_rcu(&q->entry); + mutex_unlock(&tiq_list_lock); + synchronize_rcu(); ++ INIT_LIST_HEAD(&q->entry); + } + + static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr) diff --git a/queue-3.16/series b/queue-3.16/series new file mode 100644 index 00000000..a2aa6268 --- /dev/null +++ b/queue-3.16/series @@ -0,0 +1,47 @@ +ecryptfs-fix-a-couple-type-promotion-bugs.patch +arm-riscpc-fix-dma.patch +9p-virtio-add-cleanup-path-in-p9_virtio_init.patch +tty-serial-cpm_uart-fix-init-when-smc-is-relocated.patch +signal-pid_namespace-fix-reboot_pid_ns-to-use-send_sig-not-force_sig.patch +xfrm-fix-xfrm-sel-prefix-length-validation.patch +af_key-fix-leaks-in-key_pol_get_resp-and-dump_sp.patch +crypto-talitos-check-aes-key-size.patch +crypto-ghash-fix-unaligned-memory-access-in-ghash_setkey.patch +s390-qdio-handle-pending-state-for-qebsm-devices.patch +memstick-fix-error-cleanup-path-of-memstick_init.patch +gpio-omap-fix-lack-of-irqstatus_raw0-for-omap4.patch +xfrm-fix-sa-selector-validation.patch +pci-do-not-poll-for-pme-if-the-device-is-in-d3cold.patch +usb-gadget-ether-fix-race-between-gether_disconnect-and-rx_submit.patch +powerpc-32s-fix-suspend-resume-when-ibats-4-7-are-used.patch +powerpc-watchpoint-restore-nv-gprs-while-returning-from-exception.patch +usb-serial-option-add-gosuncn-zte-welink-me3630.patch +usb-serial-option-add-support-for-gosuncn-me3630-rndis-mode.patch +s390-fix-stfle-zero-padding.patch +vmci-fix-integer-overflow-in-vmci-handle-arrays.patch +mwifiex-don-t-abort-on-small-spec-compliant-vendor-ies.patch +mwifiex-fix-802.11n-wpa-detection.patch +media-v4l2-test-type-instead-of-cfg-type-in-v4l2_ctrl_new_custom.patch +edac-fix-global-out-of-bounds-write-when-setting-edac_mc_poll_msec.patch +carl9170-fix-misuse-of-device-driver-api.patch +x86-ptrace-fix-possible-spectre-v1-in-ptrace_get_debugreg.patch +x86-tls-fix-possible-spectre-v1-in-do_get_thread_area.patch +usb-serial-ftdi_sio-add-id-for-isodebug-v1.patch +igmp-fix-memory-leak-in-igmpv3_del_delrec.patch +s390-qdio-re-initialize-tiqdio-list-entries.patch +s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch +net-bridge-stp-don-t-cache-eth-dest-pointer-before-skb-pull.patch +lib-scatterlist-fix-mapping-iterator-when-sg-offset-is-greater-than.patch +bonding-validate-ip-header-before-check-ipproto_igmp.patch +nfsv4-handle-the-special-linux-file-open-access-mode.patch +arc-hide-unused-function-unw_hdr_alloc.patch +udf-fix-incorrect-final-not_allocated-hole-extent-length.patch +mm-mmu_notifier-use-hlist_add_head_rcu.patch +net-neigh-fix-multiple-neigh-timer-scheduling.patch +alsa-seq-break-too-long-mutex-context-in-the-write-loop.patch +coda-pass-the-host-file-in-vma-vm_file-on-mmap.patch +caif-hsi-fix-possible-deadlock-in-cfhsi_exit_module.patch +parisc-fix-kernel-panic-due-invalid-values-in-iaoq0-or-iaoq1.patch +padata-use-smp_mb-in-padata_reorder-to-avoid-orphaned-padata-jobs.patch +input-psmouse-fix-build-error-of-multiple-definition.patch +kvm-x86-vpmu-refine-kvm_pmu-err-msg-when-event-creation-failed.patch diff --git a/queue-3.16/signal-pid_namespace-fix-reboot_pid_ns-to-use-send_sig-not-force_sig.patch b/queue-3.16/signal-pid_namespace-fix-reboot_pid_ns-to-use-send_sig-not-force_sig.patch new file mode 100644 index 00000000..f88239c9 --- /dev/null +++ b/queue-3.16/signal-pid_namespace-fix-reboot_pid_ns-to-use-send_sig-not-force_sig.patch @@ -0,0 +1,44 @@ +From: "Eric W. Biederman" <ebiederm@xmission.com> +Date: Wed, 15 May 2019 12:29:52 -0500 +Subject: signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig + +commit f9070dc94542093fd516ae4ccea17ef46a4362c5 upstream. + +The locking in force_sig_info is not prepared to deal with a task that +exits or execs (as sighand may change). The is not a locking problem +in force_sig as force_sig is only built to handle synchronous +exceptions. + +Further the function force_sig_info changes the signal state if the +signal is ignored, or blocked or if SIGNAL_UNKILLABLE will prevent the +delivery of the signal. The signal SIGKILL can not be ignored and can +not be blocked and SIGNAL_UNKILLABLE won't prevent it from being +delivered. + +So using force_sig rather than send_sig for SIGKILL is confusing +and pointless. + +Because it won't impact the sending of the signal and and because +using force_sig is wrong, replace force_sig with send_sig. + +Cc: Daniel Lezcano <daniel.lezcano@free.fr> +Cc: Serge Hallyn <serge@hallyn.com> +Cc: Oleg Nesterov <oleg@redhat.com> +Fixes: cf3f89214ef6 ("pidns: add reboot_pid_ns() to handle the reboot syscall") +Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/pid_namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/pid_namespace.c ++++ b/kernel/pid_namespace.c +@@ -304,7 +304,7 @@ int reboot_pid_ns(struct pid_namespace * + } + + read_lock(&tasklist_lock); +- force_sig(SIGKILL, pid_ns->child_reaper); ++ send_sig(SIGKILL, pid_ns->child_reaper, 1); + read_unlock(&tasklist_lock); + + do_exit(0); diff --git a/queue-3.16/tty-serial-cpm_uart-fix-init-when-smc-is-relocated.patch b/queue-3.16/tty-serial-cpm_uart-fix-init-when-smc-is-relocated.patch new file mode 100644 index 00000000..98262bf7 --- /dev/null +++ b/queue-3.16/tty-serial-cpm_uart-fix-init-when-smc-is-relocated.patch @@ -0,0 +1,70 @@ +From: Christophe Leroy <christophe.leroy@c-s.fr> +Date: Wed, 22 May 2019 12:17:11 +0000 +Subject: tty: serial: cpm_uart - fix init when SMC is relocated + +commit 06aaa3d066db87e8478522d910285141d44b1e58 upstream. + +SMC relocation can also be activated earlier by the bootloader, +so the driver's behaviour cannot rely on selected kernel config. + +When the SMC is relocated, CPM_CR_INIT_TRX cannot be used. + +But the only thing CPM_CR_INIT_TRX does is to clear the +rstate and tstate registers, so this can be done manually, +even when SMC is not relocated. + +Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> +Fixes: 9ab921201444 ("cpm_uart: fix non-console port startup bug") +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/serial/cpm_uart/cpm_uart_core.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c ++++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c +@@ -420,7 +420,16 @@ static int cpm_uart_startup(struct uart_ + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); + } + cpm_uart_initbd(pinfo); +- cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); ++ if (IS_SMC(pinfo)) { ++ out_be32(&pinfo->smcup->smc_rstate, 0); ++ out_be32(&pinfo->smcup->smc_tstate, 0); ++ out_be16(&pinfo->smcup->smc_rbptr, ++ in_be16(&pinfo->smcup->smc_rbase)); ++ out_be16(&pinfo->smcup->smc_tbptr, ++ in_be16(&pinfo->smcup->smc_tbase)); ++ } else { ++ cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); ++ } + } + /* Install interrupt handler. */ + retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); +@@ -871,16 +880,14 @@ static void cpm_uart_init_smc(struct uar + (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); + + /* +- * In case SMC1 is being relocated... ++ * In case SMC is being relocated... + */ +-#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) + out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); + out_be32(&up->smc_rstate, 0); + out_be32(&up->smc_tstate, 0); + out_be16(&up->smc_brkcr, 1); /* number of break chars */ + out_be16(&up->smc_brkec, 0); +-#endif + + /* Set up the uart parameters in the + * parameter ram. +@@ -894,8 +901,6 @@ static void cpm_uart_init_smc(struct uar + out_be16(&up->smc_brkec, 0); + out_be16(&up->smc_brkcr, 1); + +- cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); +- + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ diff --git a/queue-3.16/udf-fix-incorrect-final-not_allocated-hole-extent-length.patch b/queue-3.16/udf-fix-incorrect-final-not_allocated-hole-extent-length.patch new file mode 100644 index 00000000..aea77867 --- /dev/null +++ b/queue-3.16/udf-fix-incorrect-final-not_allocated-hole-extent-length.patch @@ -0,0 +1,219 @@ +From: "Steven J. Magnani" <steve.magnani@digidescorp.com> +Date: Sun, 30 Jun 2019 21:39:35 -0500 +Subject: udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + +commit fa33cdbf3eceb0206a4f844fe91aeebcf6ff2b7a upstream. + +In some cases, using the 'truncate' command to extend a UDF file results +in a mismatch between the length of the file's extents (specifically, due +to incorrect length of the final NOT_ALLOCATED extent) and the information +(file) length. The discrepancy can prevent other operating systems +(i.e., Windows 10) from opening the file. + +Two particular errors have been observed when extending a file: + +1. The final extent is larger than it should be, having been rounded up + to a multiple of the block size. + +B. The final extent is not shorter than it should be, due to not having + been updated when the file's information length was increased. + +[JK: simplified udf_do_extend_final_block(), fixed up some types] + +Fixes: 2c948b3f86e5 ("udf: Avoid IO in udf_clear_inode") +Signed-off-by: Steven J. Magnani <steve@digidescorp.com> +Link: https://lore.kernel.org/r/1561948775-5878-1-git-send-email-steve@digidescorp.com +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/udf/inode.c | 93 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 60 insertions(+), 33 deletions(-) + +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -482,13 +482,15 @@ static struct buffer_head *udf_getblk(st + return NULL; + } + +-/* Extend the file by 'blocks' blocks, return the number of extents added */ ++/* Extend the file with new blocks totaling 'new_block_bytes', ++ * return the number of extents added ++ */ + static int udf_do_extend_file(struct inode *inode, + struct extent_position *last_pos, + struct kernel_long_ad *last_ext, +- sector_t blocks) ++ loff_t new_block_bytes) + { +- sector_t add; ++ uint32_t add; + int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); + struct super_block *sb = inode->i_sb; + struct kernel_lb_addr prealloc_loc = {}; +@@ -498,7 +500,7 @@ static int udf_do_extend_file(struct ino + + /* The previous extent is fake and we should not extend by anything + * - there's nothing to do... */ +- if (!blocks && fake) ++ if (!new_block_bytes && fake) + return 0; + + iinfo = UDF_I(inode); +@@ -529,13 +531,12 @@ static int udf_do_extend_file(struct ino + /* Can we merge with the previous extent? */ + if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == + EXT_NOT_RECORDED_NOT_ALLOCATED) { +- add = ((1 << 30) - sb->s_blocksize - +- (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> +- sb->s_blocksize_bits; +- if (add > blocks) +- add = blocks; +- blocks -= add; +- last_ext->extLength += add << sb->s_blocksize_bits; ++ add = (1 << 30) - sb->s_blocksize - ++ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); ++ if (add > new_block_bytes) ++ add = new_block_bytes; ++ new_block_bytes -= add; ++ last_ext->extLength += add; + } + + if (fake) { +@@ -547,28 +548,27 @@ static int udf_do_extend_file(struct ino + last_ext->extLength, 1); + + /* Managed to do everything necessary? */ +- if (!blocks) ++ if (!new_block_bytes) + goto out; + + /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ + last_ext->extLocation.logicalBlockNum = 0; + last_ext->extLocation.partitionReferenceNum = 0; +- add = (1 << (30-sb->s_blocksize_bits)) - 1; +- last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | +- (add << sb->s_blocksize_bits); ++ add = (1 << 30) - sb->s_blocksize; ++ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | add; + + /* Create enough extents to cover the whole hole */ +- while (blocks > add) { +- blocks -= add; ++ while (new_block_bytes > add) { ++ new_block_bytes -= add; + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); + if (err) + return err; + count++; + } +- if (blocks) { ++ if (new_block_bytes) { + last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | +- (blocks << sb->s_blocksize_bits); ++ new_block_bytes; + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); + if (err) +@@ -599,6 +599,24 @@ out: + return count; + } + ++/* Extend the final block of the file to final_block_len bytes */ ++static void udf_do_extend_final_block(struct inode *inode, ++ struct extent_position *last_pos, ++ struct kernel_long_ad *last_ext, ++ uint32_t final_block_len) ++{ ++ struct super_block *sb = inode->i_sb; ++ uint32_t added_bytes; ++ ++ added_bytes = final_block_len - ++ (last_ext->extLength & (sb->s_blocksize - 1)); ++ last_ext->extLength += added_bytes; ++ UDF_I(inode)->i_lenExtents += added_bytes; ++ ++ udf_write_aext(inode, last_pos, &last_ext->extLocation, ++ last_ext->extLength, 1); ++} ++ + static int udf_extend_file(struct inode *inode, loff_t newsize) + { + +@@ -608,10 +626,12 @@ static int udf_extend_file(struct inode + int8_t etype; + struct super_block *sb = inode->i_sb; + sector_t first_block = newsize >> sb->s_blocksize_bits, offset; ++ unsigned long partial_final_block; + int adsize; + struct udf_inode_info *iinfo = UDF_I(inode); + struct kernel_long_ad extent; +- int err; ++ int err = 0; ++ int within_final_block; + + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) + adsize = sizeof(struct short_ad); +@@ -621,18 +641,8 @@ static int udf_extend_file(struct inode + BUG(); + + etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); ++ within_final_block = (etype != -1); + +- /* File has extent covering the new size (could happen when extending +- * inside a block)? */ +- if (etype != -1) +- return 0; +- if (newsize & (sb->s_blocksize - 1)) +- offset++; +- /* Extended file just to the boundary of the last file block? */ +- if (offset == 0) +- return 0; +- +- /* Truncate is extending the file by 'offset' blocks */ + if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || + (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { + /* File has no extents at all or has empty last +@@ -646,7 +656,22 @@ static int udf_extend_file(struct inode + &extent.extLength, 0); + extent.extLength |= etype << 30; + } +- err = udf_do_extend_file(inode, &epos, &extent, offset); ++ ++ partial_final_block = newsize & (sb->s_blocksize - 1); ++ ++ /* File has extent covering the new size (could happen when extending ++ * inside a block)? ++ */ ++ if (within_final_block) { ++ /* Extending file within the last file block */ ++ udf_do_extend_final_block(inode, &epos, &extent, ++ partial_final_block); ++ } else { ++ loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | ++ partial_final_block; ++ err = udf_do_extend_file(inode, &epos, &extent, add); ++ } ++ + if (err < 0) + goto out; + err = 0; +@@ -751,6 +776,7 @@ static sector_t inode_getblk(struct inod + /* Are we beyond EOF? */ + if (etype == -1) { + int ret; ++ loff_t hole_len; + isBeyondEOF = 1; + if (count) { + if (c) +@@ -766,7 +792,8 @@ static sector_t inode_getblk(struct inod + startnum = (offset > 0); + } + /* Create extents for the hole between EOF and offset */ +- ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); ++ hole_len = (loff_t)offset << inode->i_blkbits; ++ ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len); + if (ret < 0) { + brelse(prev_epos.bh); + brelse(cur_epos.bh); diff --git a/queue-3.16/usb-gadget-ether-fix-race-between-gether_disconnect-and-rx_submit.patch b/queue-3.16/usb-gadget-ether-fix-race-between-gether_disconnect-and-rx_submit.patch new file mode 100644 index 00000000..1eb25ba5 --- /dev/null +++ b/queue-3.16/usb-gadget-ether-fix-race-between-gether_disconnect-and-rx_submit.patch @@ -0,0 +1,46 @@ +From: Kiruthika Varadarajan <Kiruthika.Varadarajan@harman.com> +Date: Tue, 18 Jun 2019 08:39:06 +0000 +Subject: usb: gadget: ether: Fix race between gether_disconnect and rx_submit + +commit d29fcf7078bc8be2b6366cbd4418265b53c94fac upstream. + +On spin lock release in rx_submit, gether_disconnect get a chance to +run, it makes port_usb NULL, rx_submit access NULL port USB, hence null +pointer crash. + +Fixed by releasing the lock in rx_submit after port_usb is used. + +Fixes: 2b3d942c4878 ("usb ethernet gadget: split out network core") +Signed-off-by: Kiruthika Varadarajan <Kiruthika.Varadarajan@harman.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/u_ether.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/u_ether.c ++++ b/drivers/usb/gadget/u_ether.c +@@ -202,11 +202,12 @@ rx_submit(struct eth_dev *dev, struct us + out = dev->port_usb->out_ep; + else + out = NULL; +- spin_unlock_irqrestore(&dev->lock, flags); + + if (!out) ++ { ++ spin_unlock_irqrestore(&dev->lock, flags); + return -ENOTCONN; +- ++ } + + /* Padding up to RX_EXTRA handles minor disagreements with host. + * Normally we use the USB "terminate on short read" convention; +@@ -227,6 +228,7 @@ rx_submit(struct eth_dev *dev, struct us + + if (dev->port_usb->is_fixed) + size = max_t(size_t, size, dev->port_usb->fixed_out_len); ++ spin_unlock_irqrestore(&dev->lock, flags); + + skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); + if (skb == NULL) { diff --git a/queue-3.16/usb-serial-ftdi_sio-add-id-for-isodebug-v1.patch b/queue-3.16/usb-serial-ftdi_sio-add-id-for-isodebug-v1.patch new file mode 100644 index 00000000..11e439e6 --- /dev/null +++ b/queue-3.16/usb-serial-ftdi_sio-add-id-for-isodebug-v1.patch @@ -0,0 +1,39 @@ +From: Andreas Fritiofson <andreas.fritiofson@unjo.com> +Date: Fri, 28 Jun 2019 15:08:34 +0200 +Subject: USB: serial: ftdi_sio: add ID for isodebug v1 + +commit f8377eff548170e8ea8022c067a1fbdf9e1c46a8 upstream. + +This adds the vid:pid of the isodebug v1 isolated JTAG/SWD+UART. Only the +second channel is available for use as a serial port. + +Signed-off-by: Andreas Fritiofson <andreas.fritiofson@unjo.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ + 2 files changed, 7 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1037,6 +1037,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, + /* EZPrototypes devices */ + { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, ++ { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1542,3 +1542,9 @@ + #define CHETCO_SEASMART_DISPLAY_PID 0xA5AD /* SeaSmart NMEA2000 Display */ + #define CHETCO_SEASMART_LITE_PID 0xA5AE /* SeaSmart Lite USB Adapter */ + #define CHETCO_SEASMART_ANALOG_PID 0xA5AF /* SeaSmart Analog Adapter */ ++ ++/* ++ * Unjo AB ++ */ ++#define UNJO_VID 0x22B7 ++#define UNJO_ISODEBUG_V1_PID 0x150D diff --git a/queue-3.16/usb-serial-option-add-gosuncn-zte-welink-me3630.patch b/queue-3.16/usb-serial-option-add-gosuncn-zte-welink-me3630.patch new file mode 100644 index 00000000..9b6f0eff --- /dev/null +++ b/queue-3.16/usb-serial-option-add-gosuncn-zte-welink-me3630.patch @@ -0,0 +1,66 @@ +From: =?UTF-8?q?J=C3=B6rgen=20Storvist?= <jorgen.storvist@gmail.com> +Date: Tue, 11 Dec 2018 18:28:28 +0100 +Subject: USB: serial: option: add GosunCn ZTE WeLink ME3630 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 70a7444c550a75584ffcfae95267058817eff6a7 upstream. + +Added USB serial option driver support for GosunCn ZTE WeLink ME3630 +series cellular modules for USB modes ECM/NCM and MBIM. + +usb-devices output MBIM mode: +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=19d2 ProdID=0602 Rev=03.18 +S: Manufacturer=Android +S: Product=Android +S: SerialNumber= +C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 3 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim +I: If#= 4 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim + +usb-devices output ECM/NCM mode: +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 11 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=19d2 ProdID=1476 Rev=03.18 +S: Manufacturer=Android +S: Product=Android +S: SerialNumber= +C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 3 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether +I: If#= 4 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether + +Signed-off-by: Jörgen Storvist <jorgen.storvist@gmail.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1466,6 +1466,7 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), +@@ -1669,6 +1670,7 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, diff --git a/queue-3.16/usb-serial-option-add-support-for-gosuncn-me3630-rndis-mode.patch b/queue-3.16/usb-serial-option-add-support-for-gosuncn-me3630-rndis-mode.patch new file mode 100644 index 00000000..fc7b9b62 --- /dev/null +++ b/queue-3.16/usb-serial-option-add-support-for-gosuncn-me3630-rndis-mode.patch @@ -0,0 +1,41 @@ +From: =?UTF-8?q?J=C3=B6rgen=20Storvist?= <jorgen.storvist@gmail.com> +Date: Wed, 19 Jun 2019 00:30:19 +0200 +Subject: USB: serial: option: add support for GosunCn ME3630 RNDIS mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit aed2a26283528fb69c38e414f649411aa48fb391 upstream. + +Added USB IDs for GosunCn ME3630 cellular module in RNDIS mode. + +T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=03 Dev#= 18 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=19d2 ProdID=0601 Rev=03.18 +S: Manufacturer=Android +S: Product=Android +S: SerialNumber=b950269c +C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I: If#=0x0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host +I: If#=0x1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +I: If#=0x2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option + +Signed-off-by: Jörgen Storvist <jorgen.storvist@gmail.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1466,6 +1466,7 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0601, 0xff) }, /* GosunCn ZTE WeLink ME3630 (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, diff --git a/queue-3.16/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch b/queue-3.16/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch new file mode 100644 index 00000000..6e9897b9 --- /dev/null +++ b/queue-3.16/vmci-fix-integer-overflow-in-vmci-handle-arrays.patch @@ -0,0 +1,370 @@ +From: Vishnu DASA <vdasa@vmware.com> +Date: Fri, 24 May 2019 15:13:10 +0000 +Subject: VMCI: Fix integer overflow in VMCI handle arrays + +commit 1c2eb5b2853c9f513690ba6b71072d8eb65da16a upstream. + +The VMCI handle array has an integer overflow in +vmci_handle_arr_append_entry when it tries to expand the array. This can be +triggered from a guest, since the doorbell link hypercall doesn't impose a +limit on the number of doorbell handles that a VM can create in the +hypervisor, and these handles are stored in a handle array. + +In this change, we introduce a mandatory max capacity for handle +arrays/lists to avoid excessive memory usage. + +Signed-off-by: Vishnu Dasa <vdasa@vmware.com> +Reviewed-by: Adit Ranadive <aditr@vmware.com> +Reviewed-by: Jorgen Hansen <jhansen@vmware.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/misc/vmw_vmci/vmci_context.c | 80 +++++++++++++---------- + drivers/misc/vmw_vmci/vmci_handle_array.c | 38 +++++++---- + drivers/misc/vmw_vmci/vmci_handle_array.h | 29 +++++--- + include/linux/vmw_vmci_defs.h | 11 +++- + 4 files changed, 99 insertions(+), 59 deletions(-) + +--- a/drivers/misc/vmw_vmci/vmci_context.c ++++ b/drivers/misc/vmw_vmci/vmci_context.c +@@ -28,6 +28,9 @@ + #include "vmci_driver.h" + #include "vmci_event.h" + ++/* Use a wide upper bound for the maximum contexts. */ ++#define VMCI_MAX_CONTEXTS 2000 ++ + /* + * List of current VMCI contexts. Contexts can be added by + * vmci_ctx_create() and removed via vmci_ctx_destroy(). +@@ -124,19 +127,22 @@ struct vmci_ctx *vmci_ctx_create(u32 cid + /* Initialize host-specific VMCI context. */ + init_waitqueue_head(&context->host_context.wait_queue); + +- context->queue_pair_array = vmci_handle_arr_create(0); ++ context->queue_pair_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_QP_COUNT); + if (!context->queue_pair_array) { + error = -ENOMEM; + goto err_free_ctx; + } + +- context->doorbell_array = vmci_handle_arr_create(0); ++ context->doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->doorbell_array) { + error = -ENOMEM; + goto err_free_qp_array; + } + +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + error = -ENOMEM; + goto err_free_db_array; +@@ -211,7 +217,7 @@ static int ctx_fire_notification(u32 con + * We create an array to hold the subscribers we find when + * scanning through all contexts. + */ +- subscriber_array = vmci_handle_arr_create(0); ++ subscriber_array = vmci_handle_arr_create(0, VMCI_MAX_CONTEXTS); + if (subscriber_array == NULL) + return VMCI_ERROR_NO_MEM; + +@@ -630,20 +636,26 @@ int vmci_ctx_add_notification(u32 contex + + spin_lock(&context->lock); + +- list_for_each_entry(n, &context->notifier_list, node) { +- if (vmci_handle_is_equal(n->handle, notifier->handle)) { +- exists = true; +- break; ++ if (context->n_notifiers < VMCI_MAX_CONTEXTS) { ++ list_for_each_entry(n, &context->notifier_list, node) { ++ if (vmci_handle_is_equal(n->handle, notifier->handle)) { ++ exists = true; ++ break; ++ } + } +- } + +- if (exists) { +- kfree(notifier); +- result = VMCI_ERROR_ALREADY_EXISTS; ++ if (exists) { ++ kfree(notifier); ++ result = VMCI_ERROR_ALREADY_EXISTS; ++ } else { ++ list_add_tail_rcu(¬ifier->node, ++ &context->notifier_list); ++ context->n_notifiers++; ++ result = VMCI_SUCCESS; ++ } + } else { +- list_add_tail_rcu(¬ifier->node, &context->notifier_list); +- context->n_notifiers++; +- result = VMCI_SUCCESS; ++ kfree(notifier); ++ result = VMCI_ERROR_NO_MEM; + } + + spin_unlock(&context->lock); +@@ -728,8 +740,7 @@ static int vmci_ctx_get_chkpt_doorbells( + u32 *buf_size, void **pbuf) + { + struct dbell_cpt_state *dbells; +- size_t n_doorbells; +- int i; ++ u32 i, n_doorbells; + + n_doorbells = vmci_handle_arr_get_size(context->doorbell_array); + if (n_doorbells > 0) { +@@ -867,7 +878,8 @@ int vmci_ctx_rcv_notifications_get(u32 c + spin_lock(&context->lock); + + *db_handle_array = context->pending_doorbell_array; +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + context->pending_doorbell_array = *db_handle_array; + *db_handle_array = NULL; +@@ -949,12 +961,11 @@ int vmci_ctx_dbell_create(u32 context_id + return VMCI_ERROR_NOT_FOUND; + + spin_lock(&context->lock); +- if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) { +- vmci_handle_arr_append_entry(&context->doorbell_array, handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) ++ result = vmci_handle_arr_append_entry(&context->doorbell_array, ++ handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + spin_unlock(&context->lock); + vmci_ctx_put(context); +@@ -1090,15 +1101,16 @@ int vmci_ctx_notify_dbell(u32 src_cid, + if (!vmci_handle_arr_has_entry( + dst_context->pending_doorbell_array, + handle)) { +- vmci_handle_arr_append_entry( ++ result = vmci_handle_arr_append_entry( + &dst_context->pending_doorbell_array, + handle); +- +- ctx_signal_notify(dst_context); +- wake_up(&dst_context->host_context.wait_queue); +- ++ if (result == VMCI_SUCCESS) { ++ ctx_signal_notify(dst_context); ++ wake_up(&dst_context->host_context.wait_queue); ++ } ++ } else { ++ result = VMCI_SUCCESS; + } +- result = VMCI_SUCCESS; + } + spin_unlock(&dst_context->lock); + } +@@ -1125,13 +1137,11 @@ int vmci_ctx_qp_create(struct vmci_ctx * + if (context == NULL || vmci_handle_is_invalid(handle)) + return VMCI_ERROR_INVALID_ARGS; + +- if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) { +- vmci_handle_arr_append_entry(&context->queue_pair_array, +- handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) ++ result = vmci_handle_arr_append_entry( ++ &context->queue_pair_array, handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + return result; + } +--- a/drivers/misc/vmw_vmci/vmci_handle_array.c ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.c +@@ -16,24 +16,29 @@ + #include <linux/slab.h> + #include "vmci_handle_array.h" + +-static size_t handle_arr_calc_size(size_t capacity) ++static size_t handle_arr_calc_size(u32 capacity) + { +- return sizeof(struct vmci_handle_arr) + ++ return VMCI_HANDLE_ARRAY_HEADER_SIZE + + capacity * sizeof(struct vmci_handle); + } + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity) ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity) + { + struct vmci_handle_arr *array; + ++ if (max_capacity == 0 || capacity > max_capacity) ++ return NULL; ++ + if (capacity == 0) +- capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE; ++ capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY, ++ max_capacity); + + array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC); + if (!array) + return NULL; + + array->capacity = capacity; ++ array->max_capacity = max_capacity; + array->size = 0; + + return array; +@@ -44,27 +49,34 @@ void vmci_handle_arr_destroy(struct vmci + kfree(array); + } + +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle) ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle) + { + struct vmci_handle_arr *array = *array_ptr; + + if (unlikely(array->size >= array->capacity)) { + /* reallocate. */ + struct vmci_handle_arr *new_array; +- size_t new_capacity = array->capacity * VMCI_ARR_CAP_MULT; +- size_t new_size = handle_arr_calc_size(new_capacity); ++ u32 capacity_bump = min(array->max_capacity - array->capacity, ++ array->capacity); ++ size_t new_size = handle_arr_calc_size(array->capacity + ++ capacity_bump); ++ ++ if (array->size >= array->max_capacity) ++ return VMCI_ERROR_NO_MEM; + + new_array = krealloc(array, new_size, GFP_ATOMIC); + if (!new_array) +- return; ++ return VMCI_ERROR_NO_MEM; + +- new_array->capacity = new_capacity; ++ new_array->capacity += capacity_bump; + *array_ptr = array = new_array; + } + + array->entries[array->size] = handle; + array->size++; ++ ++ return VMCI_SUCCESS; + } + + /* +@@ -74,7 +86,7 @@ struct vmci_handle vmci_handle_arr_remov + struct vmci_handle entry_handle) + { + struct vmci_handle handle = VMCI_INVALID_HANDLE; +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) { + if (vmci_handle_is_equal(array->entries[i], entry_handle)) { +@@ -109,7 +121,7 @@ struct vmci_handle vmci_handle_arr_remov + * Handle at given index, VMCI_INVALID_HANDLE if invalid index. + */ + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index) ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index) + { + if (unlikely(index >= array->size)) + return VMCI_INVALID_HANDLE; +@@ -120,7 +132,7 @@ vmci_handle_arr_get_entry(const struct v + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle) + { +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) + if (vmci_handle_is_equal(array->entries[i], entry_handle)) +--- a/drivers/misc/vmw_vmci/vmci_handle_array.h ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.h +@@ -17,32 +17,41 @@ + #define _VMCI_HANDLE_ARRAY_H_ + + #include <linux/vmw_vmci_defs.h> ++#include <linux/limits.h> + #include <linux/types.h> + +-#define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4 +-#define VMCI_ARR_CAP_MULT 2 /* Array capacity multiplier */ +- + struct vmci_handle_arr { +- size_t capacity; +- size_t size; ++ u32 capacity; ++ u32 max_capacity; ++ u32 size; ++ u32 pad; + struct vmci_handle entries[]; + }; + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity); ++#define VMCI_HANDLE_ARRAY_HEADER_SIZE \ ++ offsetof(struct vmci_handle_arr, entries) ++/* Select a default capacity that results in a 64 byte sized array */ ++#define VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY 6 ++/* Make sure that the max array size can be expressed by a u32 */ ++#define VMCI_HANDLE_ARRAY_MAX_CAPACITY \ ++ ((U32_MAX - VMCI_HANDLE_ARRAY_HEADER_SIZE - 1) / \ ++ sizeof(struct vmci_handle)) ++ ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity); + void vmci_handle_arr_destroy(struct vmci_handle_arr *array); +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle); ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle); + struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, + struct vmci_handle + entry_handle); + struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array); + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index); ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index); + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle); + struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array); + +-static inline size_t vmci_handle_arr_get_size( ++static inline u32 vmci_handle_arr_get_size( + const struct vmci_handle_arr *array) + { + return array->size; +--- a/include/linux/vmw_vmci_defs.h ++++ b/include/linux/vmw_vmci_defs.h +@@ -75,9 +75,18 @@ enum { + + /* + * A single VMCI device has an upper limit of 128MB on the amount of +- * memory that can be used for queue pairs. ++ * memory that can be used for queue pairs. Since each queue pair ++ * consists of at least two pages, the memory limit also dictates the ++ * number of queue pairs a guest can create. + */ + #define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024) ++#define VMCI_MAX_GUEST_QP_COUNT (VMCI_MAX_GUEST_QP_MEMORY / PAGE_SIZE / 2) ++ ++/* ++ * There can be at most PAGE_SIZE doorbells since there is one doorbell ++ * per byte in the doorbell bitmap page. ++ */ ++#define VMCI_MAX_GUEST_DOORBELL_COUNT PAGE_SIZE + + /* + * Queues with pre-mapped data pages must be small, so that we don't pin diff --git a/queue-3.16/x86-ptrace-fix-possible-spectre-v1-in-ptrace_get_debugreg.patch b/queue-3.16/x86-ptrace-fix-possible-spectre-v1-in-ptrace_get_debugreg.patch new file mode 100644 index 00000000..70ccffa6 --- /dev/null +++ b/queue-3.16/x86-ptrace-fix-possible-spectre-v1-in-ptrace_get_debugreg.patch @@ -0,0 +1,48 @@ +From: Dianzhang Chen <dianzhangchen0@gmail.com> +Date: Tue, 25 Jun 2019 23:30:17 +0800 +Subject: x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + +commit 31a2fbb390fee4231281b939e1979e810f945415 upstream. + +The index to access the threads ptrace_bps is controlled by userspace via +syscall: sys_ptrace(), hence leading to a potential exploitation of the +Spectre variant 1 vulnerability. + +The index can be controlled from: + ptrace -> arch_ptrace -> ptrace_get_debugreg. + +Fix this by sanitizing the user supplied index before using it access +thread->ptrace_bps. + +Signed-off-by: Dianzhang Chen <dianzhangchen0@gmail.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: bp@alien8.de +Cc: hpa@zytor.com +Link: https://lkml.kernel.org/r/1561476617-3759-1-git-send-email-dianzhangchen0@gmail.com +[bwh: Backported to 3.16: fold in fix-up from commit 223cea6a4f05 + "Merge branch 'x86-pti-for-linus' of ..."] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/ptrace.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -24,6 +24,7 @@ + #include <linux/rcupdate.h> + #include <linux/export.h> + #include <linux/context_tracking.h> ++#include <linux/nospec.h> + + #include <asm/uaccess.h> + #include <asm/pgtable.h> +@@ -707,7 +708,8 @@ static unsigned long ptrace_get_debugreg + unsigned long val = 0; + + if (n < HBP_NUM) { +- struct perf_event *bp = thread->ptrace_bps[n]; ++ int index = array_index_nospec(n, HBP_NUM); ++ struct perf_event *bp = thread->ptrace_bps[index]; + + if (bp) + val = bp->hw.info.address; diff --git a/queue-3.16/x86-tls-fix-possible-spectre-v1-in-do_get_thread_area.patch b/queue-3.16/x86-tls-fix-possible-spectre-v1-in-do_get_thread_area.patch new file mode 100644 index 00000000..54d1d26a --- /dev/null +++ b/queue-3.16/x86-tls-fix-possible-spectre-v1-in-do_get_thread_area.patch @@ -0,0 +1,58 @@ +From: Dianzhang Chen <dianzhangchen0@gmail.com> +Date: Wed, 26 Jun 2019 12:50:30 +0800 +Subject: x86/tls: Fix possible spectre-v1 in do_get_thread_area() + +commit 993773d11d45c90cb1c6481c2638c3d9f092ea5b upstream. + +The index to access the threads tls array is controlled by userspace +via syscall: sys_ptrace(), hence leading to a potential exploitation +of the Spectre variant 1 vulnerability. + +The index can be controlled from: + ptrace -> arch_ptrace -> do_get_thread_area. + +Fix this by sanitizing the user supplied index before using it to access +the p->thread.tls_array. + +Signed-off-by: Dianzhang Chen <dianzhangchen0@gmail.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: bp@alien8.de +Cc: hpa@zytor.com +Link: https://lkml.kernel.org/r/1561524630-3642-1-git-send-email-dianzhangchen0@gmail.com +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/tls.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/tls.c ++++ b/arch/x86/kernel/tls.c +@@ -4,6 +4,7 @@ + #include <linux/user.h> + #include <linux/regset.h> + #include <linux/syscalls.h> ++#include <linux/nospec.h> + + #include <asm/uaccess.h> + #include <asm/desc.h> +@@ -177,6 +178,7 @@ int do_get_thread_area(struct task_struc + struct user_desc __user *u_info) + { + struct user_desc info; ++ int index; + + if (idx == -1 && get_user(idx, &u_info->entry_number)) + return -EFAULT; +@@ -184,8 +186,11 @@ int do_get_thread_area(struct task_struc + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + +- fill_user_desc(&info, idx, +- &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]); ++ index = idx - GDT_ENTRY_TLS_MIN; ++ index = array_index_nospec(index, ++ GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1); ++ ++ fill_user_desc(&info, idx, &p->thread.tls_array[index]); + + if (copy_to_user(u_info, &info, sizeof(info))) + return -EFAULT; diff --git a/queue-3.16/xfrm-fix-sa-selector-validation.patch b/queue-3.16/xfrm-fix-sa-selector-validation.patch new file mode 100644 index 00000000..e2059a0b --- /dev/null +++ b/queue-3.16/xfrm-fix-sa-selector-validation.patch @@ -0,0 +1,36 @@ +From: Nicolas Dichtel <nicolas.dichtel@6wind.com> +Date: Fri, 14 Jun 2019 11:13:55 +0200 +Subject: xfrm: fix sa selector validation + +commit b8d6d0079757cbd1b69724cfd1c08e2171c68cee upstream. + +After commit b38ff4075a80, the following command does not work anymore: +$ ip xfrm state add src 10.125.0.2 dst 10.125.0.1 proto esp spi 34 reqid 1 \ + mode tunnel enc 'cbc(aes)' 0xb0abdba8b782ad9d364ec81e3a7d82a1 auth-trunc \ + 'hmac(sha1)' 0xe26609ebd00acb6a4d51fca13e49ea78a72c73e6 96 flag align4 + +In fact, the selector is not mandatory, allow the user to provide an empty +selector. + +Fixes: b38ff4075a80 ("xfrm: Fix xfrm sel prefix length validation") +CC: Anirudh Gupta <anirudh.gupta@sophos.com> +Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> +Acked-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/xfrm/xfrm_user.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -165,6 +165,9 @@ static int verify_newsa_info(struct xfrm + } + + switch (p->sel.family) { ++ case AF_UNSPEC: ++ break; ++ + case AF_INET: + if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32) + goto out; diff --git a/queue-3.16/xfrm-fix-xfrm-sel-prefix-length-validation.patch b/queue-3.16/xfrm-fix-xfrm-sel-prefix-length-validation.patch new file mode 100644 index 00000000..a102e7ba --- /dev/null +++ b/queue-3.16/xfrm-fix-xfrm-sel-prefix-length-validation.patch @@ -0,0 +1,50 @@ +From: Anirudh Gupta <anirudhrudr@gmail.com> +Date: Tue, 21 May 2019 20:59:47 +0530 +Subject: xfrm: Fix xfrm sel prefix length validation + +commit b38ff4075a80b4da5cb2202d7965332ca0efb213 upstream. + +Family of src/dst can be different from family of selector src/dst. +Use xfrm selector family to validate address prefix length, +while verifying new sa from userspace. + +Validated patch with this command: +ip xfrm state add src 1.1.6.1 dst 1.1.6.2 proto esp spi 4260196 \ +reqid 20004 mode tunnel aead "rfc4106(gcm(aes))" \ +0x1111016400000000000000000000000044440001 128 \ +sel src 1011:1:4::2/128 sel dst 1021:1:4::2/128 dev Port5 + +Fixes: 07bf7908950a ("xfrm: Validate address prefix lengths in the xfrm selector.") +Signed-off-by: Anirudh Gupta <anirudh.gupta@sophos.com> +Acked-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/xfrm/xfrm_user.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -150,6 +150,22 @@ static int verify_newsa_info(struct xfrm + err = -EINVAL; + switch (p->family) { + case AF_INET: ++ break; ++ ++ case AF_INET6: ++#if IS_ENABLED(CONFIG_IPV6) ++ break; ++#else ++ err = -EAFNOSUPPORT; ++ goto out; ++#endif ++ ++ default: ++ goto out; ++ } ++ ++ switch (p->sel.family) { ++ case AF_INET: + if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32) + goto out; + diff --git a/upstream-head b/upstream-head index 6863f5ef..0604aa1b 100644 --- a/upstream-head +++ b/upstream-head @@ -1 +1 @@ -0ecfebd2b52404ae0c54a878c872bb93363ada36 +5f9e832c137075045d15cd6899ab0505cfb2ca4b |