From: Greg Kroah-Hartman Date: Sun, 30 Apr 2017 14:11:27 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.4.66~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=054486bcfaadc46a3f29724784a41810828fd1f3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: alsa-firewire-lib-fix-inappropriate-assignment-between-signed-unsigned-type.patch alsa-seq-don-t-break-snd_use_lock_sync-loop-by-timeout.patch arcv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-code-gen.patch dp83640-don-t-recieve-time-stamps-twice.patch input-i8042-add-clevo-p650rs-to-the-i8042-reset-list.patch ip6mr-fix-notification-device-destruction.patch ipv6-check-raw-payload-size-correctly-in-ioctl.patch ipv6-check-skb-protocol-before-lookup-for-nexthop.patch l2tp-fix-ppp-pseudo-wire-auto-loading.patch l2tp-purge-socket-queues-in-the-.destruct-callback.patch l2tp-take-reference-on-sessions-being-dumped.patch macvlan-fix-device-ref-leak-when-purging-bc_queue.patch mips-avoid-bug-warning-in-arch_check_elf.patch mips-kgdb-use-kernel-context-for-sleeping-threads.patch net-ipv4-fix-multipath-rtm_getroute-behavior-when-iif-is-given.patch net-ipv6-rtf_pcpu-should-not-be-settable-from-userspace.patch net-mlx5-fix-driver-load-bad-flow-when-having-fw-initializing-timeout.patch net-neigh-guard-against-null-solicit-method.patch net-packet-fix-overflow-in-check-for-tp_frame_nr.patch net-packet-fix-overflow-in-check-for-tp_reserve.patch net-phy-handle-state-correctly-in-phy_stop_machine.patch net-timestamp-avoid-use-after-free-in-ip_recv_error.patch netpoll-check-for-skb-queue_mapping.patch nfsd-check-for-oversized-nfsv2-v3-arguments.patch p9_client_readdir-fix.patch sctp-listen-on-the-sock-only-when-it-s-state-is-listening-or-closed.patch tcp-clear-saved_syn-in-tcp_disconnect.patch --- diff --git a/queue-4.4/alsa-firewire-lib-fix-inappropriate-assignment-between-signed-unsigned-type.patch b/queue-4.4/alsa-firewire-lib-fix-inappropriate-assignment-between-signed-unsigned-type.patch new file mode 100644 index 00000000000..930dcaecc54 --- /dev/null +++ b/queue-4.4/alsa-firewire-lib-fix-inappropriate-assignment-between-signed-unsigned-type.patch @@ -0,0 +1,40 @@ +From dfb00a56935186171abb5280b3407c3f910011f1 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Fri, 14 Apr 2017 12:43:01 +0900 +Subject: ALSA: firewire-lib: fix inappropriate assignment between signed/unsigned type + +From: Takashi Sakamoto + +commit dfb00a56935186171abb5280b3407c3f910011f1 upstream. + +An abstraction of asynchronous transaction for transmission of MIDI +messages was introduced in Linux v4.4. Each driver can utilize this +abstraction to transfer MIDI messages via fixed-length payload of +transaction to a certain unit address. Filling payload of the transaction +is done by callback. In this callback, each driver can return negative +error code, however current implementation assigns the return value to +unsigned variable. + +This commit changes type of the variable to fix the bug. + +Reported-by: Julia Lawall +Fixes: 585d7cba5e1f ("ALSA: firewire-lib: add helper functions for asynchronous transactions to transfer MIDI messages") +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/firewire/lib.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/firewire/lib.h ++++ b/sound/firewire/lib.h +@@ -42,7 +42,7 @@ struct snd_fw_async_midi_port { + + struct snd_rawmidi_substream *substream; + snd_fw_async_midi_port_fill fill; +- unsigned int consume_bytes; ++ int consume_bytes; + }; + + int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port, diff --git a/queue-4.4/alsa-seq-don-t-break-snd_use_lock_sync-loop-by-timeout.patch b/queue-4.4/alsa-seq-don-t-break-snd_use_lock_sync-loop-by-timeout.patch new file mode 100644 index 00000000000..d79e5f90c27 --- /dev/null +++ b/queue-4.4/alsa-seq-don-t-break-snd_use_lock_sync-loop-by-timeout.patch @@ -0,0 +1,57 @@ +From 4e7655fd4f47c23e5249ea260dc802f909a64611 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 9 Apr 2017 10:41:27 +0200 +Subject: ALSA: seq: Don't break snd_use_lock_sync() loop by timeout + +From: Takashi Iwai + +commit 4e7655fd4f47c23e5249ea260dc802f909a64611 upstream. + +The snd_use_lock_sync() (thus its implementation +snd_use_lock_sync_helper()) has the 5 seconds timeout to break out of +the sync loop. It was introduced from the beginning, just to be +"safer", in terms of avoiding the stupid bugs. + +However, as Ben Hutchings suggested, this timeout rather introduces a +potential leak or use-after-free that was apparently fixed by the +commit 2d7d54002e39 ("ALSA: seq: Fix race during FIFO resize"): +for example, snd_seq_fifo_event_in() -> snd_seq_event_dup() -> +copy_from_user() could block for a long time, and snd_use_lock_sync() +goes timeout and still leaves the cell at releasing the pool. + +For fixing such a problem, we remove the break by the timeout while +still keeping the warning. + +Suggested-by: Ben Hutchings +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_lock.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/sound/core/seq/seq_lock.c ++++ b/sound/core/seq/seq_lock.c +@@ -28,19 +28,16 @@ + /* wait until all locks are released */ + void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + { +- int max_count = 5 * HZ; ++ int warn_count = 5 * HZ; + + if (atomic_read(lockp) < 0) { + pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); + return; + } + while (atomic_read(lockp) > 0) { +- if (max_count == 0) { +- pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); +- break; +- } ++ if (warn_count-- == 0) ++ pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line); + schedule_timeout_uninterruptible(1); +- max_count--; + } + } + diff --git a/queue-4.4/arcv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-code-gen.patch b/queue-4.4/arcv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-code-gen.patch new file mode 100644 index 00000000000..907f16d140c --- /dev/null +++ b/queue-4.4/arcv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-code-gen.patch @@ -0,0 +1,49 @@ +From ecd43afdbe72017aefe48080631eb625e177ef4d Mon Sep 17 00:00:00 2001 +From: Vineet Gupta +Date: Sun, 8 Jan 2017 19:45:48 -0800 +Subject: ARCv2: save r30 on kernel entry as gcc uses it for code-gen + +From: Vineet Gupta + +commit ecd43afdbe72017aefe48080631eb625e177ef4d upstream. + +This is not exposed to userspace debugers yet, which can be done +independently as a seperate patch ! + +Signed-off-by: Vineet Gupta +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arc/include/asm/entry-arcv2.h | 2 ++ + arch/arc/include/asm/ptrace.h | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/arc/include/asm/entry-arcv2.h ++++ b/arch/arc/include/asm/entry-arcv2.h +@@ -16,6 +16,7 @@ + ; + ; Now manually save: r12, sp, fp, gp, r25 + ++ PUSH r30 + PUSH r12 + + ; Saving pt_regs->sp correctly requires some extra work due to the way +@@ -72,6 +73,7 @@ + POPAX AUX_USER_SP + 1: + POP r12 ++ POP r30 + + .endm + +--- a/arch/arc/include/asm/ptrace.h ++++ b/arch/arc/include/asm/ptrace.h +@@ -84,7 +84,7 @@ struct pt_regs { + unsigned long fp; + unsigned long sp; /* user/kernel sp depending on where we came from */ + +- unsigned long r12; ++ unsigned long r12, r30; + + /*------- Below list auto saved by h/w -----------*/ + unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; diff --git a/queue-4.4/dp83640-don-t-recieve-time-stamps-twice.patch b/queue-4.4/dp83640-don-t-recieve-time-stamps-twice.patch new file mode 100644 index 00000000000..454d73ef7df --- /dev/null +++ b/queue-4.4/dp83640-don-t-recieve-time-stamps-twice.patch @@ -0,0 +1,41 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Dan Carpenter +Date: Tue, 18 Apr 2017 22:14:26 +0300 +Subject: dp83640: don't recieve time stamps twice + +From: Dan Carpenter + + +[ Upstream commit 9d386cd9a755c8293e8916264d4d053878a7c9c7 ] + +This patch is prompted by a static checker warning about a potential +use after free. The concern is that netif_rx_ni() can free "skb" and we +call it twice. + +When I look at the commit that added this, it looks like some stray +lines were added accidentally. It doesn't make sense to me that we +would recieve the same data two times. I asked the author but never +recieved a response. + +I can't test this code, but I'm pretty sure my patch is correct. + +Fixes: 4b063258ab93 ("dp83640: Delay scheduled work.") +Signed-off-by: Dan Carpenter +Acked-by: Stefan Sørensen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83640.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -1436,8 +1436,6 @@ static bool dp83640_rxtstamp(struct phy_ + skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT; + skb_queue_tail(&dp83640->rx_queue, skb); + schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT); +- } else { +- netif_rx_ni(skb); + } + + return true; diff --git a/queue-4.4/input-i8042-add-clevo-p650rs-to-the-i8042-reset-list.patch b/queue-4.4/input-i8042-add-clevo-p650rs-to-the-i8042-reset-list.patch new file mode 100644 index 00000000000..3715687f03a --- /dev/null +++ b/queue-4.4/input-i8042-add-clevo-p650rs-to-the-i8042-reset-list.patch @@ -0,0 +1,41 @@ +From 7c5bb4ac2b76d2a09256aec8a7d584bf3e2b0466 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Thu, 13 Apr 2017 15:36:31 -0700 +Subject: Input: i8042 - add Clevo P650RS to the i8042 reset list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dmitry Torokhov + +commit 7c5bb4ac2b76d2a09256aec8a7d584bf3e2b0466 upstream. + +Clevo P650RS and other similar devices require i8042 to be reset in order +to detect Synaptics touchpad. + +Reported-by: Paweł Bylica +Tested-by: Ed Bordin +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=190301 +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -685,6 +685,13 @@ static const struct dmi_system_id __init + DMI_MATCH(DMI_PRODUCT_NAME, "20046"), + }, + }, ++ { ++ /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), ++ }, ++ }, + { } + }; + diff --git a/queue-4.4/ip6mr-fix-notification-device-destruction.patch b/queue-4.4/ip6mr-fix-notification-device-destruction.patch new file mode 100644 index 00000000000..13d3dacc501 --- /dev/null +++ b/queue-4.4/ip6mr-fix-notification-device-destruction.patch @@ -0,0 +1,131 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Nikolay Aleksandrov +Date: Fri, 21 Apr 2017 20:42:16 +0300 +Subject: ip6mr: fix notification device destruction + +From: Nikolay Aleksandrov + + +[ Upstream commit 723b929ca0f79c0796f160c2eeda4597ee98d2b8 ] + +Andrey Konovalov reported a BUG caused by the ip6mr code which is caused +because we call unregister_netdevice_many for a device that is already +being destroyed. In IPv4's ipmr that has been resolved by two commits +long time ago by introducing the "notify" parameter to the delete +function and avoiding the unregister when called from a notifier, so +let's do the same for ip6mr. + +The trace from Andrey: +------------[ cut here ]------------ +kernel BUG at net/core/dev.c:6813! +invalid opcode: 0000 [#1] SMP KASAN +Modules linked in: +CPU: 1 PID: 1165 Comm: kworker/u4:3 Not tainted 4.11.0-rc7+ #251 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs +01/01/2011 +Workqueue: netns cleanup_net +task: ffff880069208000 task.stack: ffff8800692d8000 +RIP: 0010:rollback_registered_many+0x348/0xeb0 net/core/dev.c:6813 +RSP: 0018:ffff8800692de7f0 EFLAGS: 00010297 +RAX: ffff880069208000 RBX: 0000000000000002 RCX: 0000000000000001 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88006af90569 +RBP: ffff8800692de9f0 R08: ffff8800692dec60 R09: 0000000000000000 +R10: 0000000000000006 R11: 0000000000000000 R12: ffff88006af90070 +R13: ffff8800692debf0 R14: dffffc0000000000 R15: ffff88006af90000 +FS: 0000000000000000(0000) GS:ffff88006cb00000(0000) +knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007fe7e897d870 CR3: 00000000657e7000 CR4: 00000000000006e0 +Call Trace: + unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881 + unregister_netdevice_many+0xc8/0x120 net/core/dev.c:7880 + ip6mr_device_event+0x362/0x3f0 net/ipv6/ip6mr.c:1346 + notifier_call_chain+0x145/0x2f0 kernel/notifier.c:93 + __raw_notifier_call_chain kernel/notifier.c:394 + raw_notifier_call_chain+0x2d/0x40 kernel/notifier.c:401 + call_netdevice_notifiers_info+0x51/0x90 net/core/dev.c:1647 + call_netdevice_notifiers net/core/dev.c:1663 + rollback_registered_many+0x919/0xeb0 net/core/dev.c:6841 + unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881 + unregister_netdevice_many net/core/dev.c:7880 + default_device_exit_batch+0x4fa/0x640 net/core/dev.c:8333 + ops_exit_list.isra.4+0x100/0x150 net/core/net_namespace.c:144 + cleanup_net+0x5a8/0xb40 net/core/net_namespace.c:463 + process_one_work+0xc04/0x1c10 kernel/workqueue.c:2097 + worker_thread+0x223/0x19c0 kernel/workqueue.c:2231 + kthread+0x35e/0x430 kernel/kthread.c:231 + ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430 +Code: 3c 32 00 0f 85 70 0b 00 00 48 b8 00 02 00 00 00 00 ad de 49 89 +47 78 e9 93 fe ff ff 49 8d 57 70 49 8d 5f 78 eb 9e e8 88 7a 14 fe <0f> +0b 48 8b 9d 28 fe ff ff e8 7a 7a 14 fe 48 b8 00 00 00 00 00 +RIP: rollback_registered_many+0x348/0xeb0 RSP: ffff8800692de7f0 +---[ end trace e0b29c57e9b3292c ]--- + +Reported-by: Andrey Konovalov +Signed-off-by: Nikolay Aleksandrov +Tested-by: Andrey Konovalov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6mr.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -774,7 +774,8 @@ failure: + * Delete a VIF entry + */ + +-static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) ++static int mif6_delete(struct mr6_table *mrt, int vifi, int notify, ++ struct list_head *head) + { + struct mif_device *v; + struct net_device *dev; +@@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table + dev->ifindex, &in6_dev->cnf); + } + +- if (v->flags & MIFF_REGISTER) ++ if ((v->flags & MIFF_REGISTER) && !notify) + unregister_netdevice_queue(dev, head); + + dev_put(dev); +@@ -1330,7 +1331,6 @@ static int ip6mr_device_event(struct not + struct mr6_table *mrt; + struct mif_device *v; + int ct; +- LIST_HEAD(list); + + if (event != NETDEV_UNREGISTER) + return NOTIFY_DONE; +@@ -1339,10 +1339,9 @@ static int ip6mr_device_event(struct not + v = &mrt->vif6_table[0]; + for (ct = 0; ct < mrt->maxvif; ct++, v++) { + if (v->dev == dev) +- mif6_delete(mrt, ct, &list); ++ mif6_delete(mrt, ct, 1, NULL); + } + } +- unregister_netdevice_many(&list); + + return NOTIFY_DONE; + } +@@ -1551,7 +1550,7 @@ static void mroute_clean_tables(struct m + for (i = 0; i < mrt->maxvif; i++) { + if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) + continue; +- mif6_delete(mrt, i, &list); ++ mif6_delete(mrt, i, 0, &list); + } + unregister_netdevice_many(&list); + +@@ -1704,7 +1703,7 @@ int ip6_mroute_setsockopt(struct sock *s + if (copy_from_user(&mifi, optval, sizeof(mifi_t))) + return -EFAULT; + rtnl_lock(); +- ret = mif6_delete(mrt, mifi, NULL); ++ ret = mif6_delete(mrt, mifi, 0, NULL); + rtnl_unlock(); + return ret; + diff --git a/queue-4.4/ipv6-check-raw-payload-size-correctly-in-ioctl.patch b/queue-4.4/ipv6-check-raw-payload-size-correctly-in-ioctl.patch new file mode 100644 index 00000000000..eb4f7f9ab55 --- /dev/null +++ b/queue-4.4/ipv6-check-raw-payload-size-correctly-in-ioctl.patch @@ -0,0 +1,39 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Jamie Bainbridge +Date: Wed, 26 Apr 2017 10:43:27 +1000 +Subject: ipv6: check raw payload size correctly in ioctl + +From: Jamie Bainbridge + + +[ Upstream commit 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 ] + +In situations where an skb is paged, the transport header pointer and +tail pointer can be the same because the skb contents are in frags. + +This results in ioctl(SIOCINQ/FIONREAD) incorrectly returning a +length of 0 when the length to receive is actually greater than zero. + +skb->len is already correctly set in ip6_input_finish() with +pskb_pull(), so use skb->len as it always returns the correct result +for both linear and paged data. + +Signed-off-by: Jamie Bainbridge +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/raw.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -1144,8 +1144,7 @@ static int rawv6_ioctl(struct sock *sk, + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + if (skb) +- amount = skb_tail_pointer(skb) - +- skb_transport_header(skb); ++ amount = skb->len; + spin_unlock_bh(&sk->sk_receive_queue.lock); + return put_user(amount, (int __user *)arg); + } diff --git a/queue-4.4/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch b/queue-4.4/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch new file mode 100644 index 00000000000..259567fda38 --- /dev/null +++ b/queue-4.4/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch @@ -0,0 +1,108 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: WANG Cong +Date: Tue, 25 Apr 2017 14:37:15 -0700 +Subject: ipv6: check skb->protocol before lookup for nexthop + +From: WANG Cong + + +[ Upstream commit 199ab00f3cdb6f154ea93fa76fd80192861a821d ] + +Andrey reported a out-of-bound access in ip6_tnl_xmit(), this +is because we use an ipv4 dst in ip6_tnl_xmit() and cast an IPv4 +neigh key as an IPv6 address: + + neigh = dst_neigh_lookup(skb_dst(skb), + &ipv6_hdr(skb)->daddr); + if (!neigh) + goto tx_err_link_failure; + + addr6 = (struct in6_addr *)&neigh->primary_key; // <=== HERE + addr_type = ipv6_addr_type(addr6); + + if (addr_type == IPV6_ADDR_ANY) + addr6 = &ipv6_hdr(skb)->daddr; + + memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); + +Also the network header of the skb at this point should be still IPv4 +for 4in6 tunnels, we shold not just use it as IPv6 header. + +This patch fixes it by checking if skb->protocol is ETH_P_IPV6: if it +is, we are safe to do the nexthop lookup using skb_dst() and +ipv6_hdr(skb)->daddr; if not (aka IPv4), we have no clue about which +dest address we can pick here, we have to rely on callers to fill it +from tunnel config, so just fall to ip6_route_output() to make the +decision. + +Fixes: ea3dc9601bda ("ip6_tunnel: Add support for wildcard tunnel endpoints.") +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Cc: Steffen Klassert +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_tunnel.c | 44 +++++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1049,7 +1049,7 @@ static int ip6_tnl_xmit2(struct sk_buff + struct ip6_tnl *t = netdev_priv(dev); + struct net *net = t->net; + struct net_device_stats *stats = &t->dev->stats; +- struct ipv6hdr *ipv6h = ipv6_hdr(skb); ++ struct ipv6hdr *ipv6h; + struct ipv6_tel_txoption opt; + struct dst_entry *dst = NULL, *ndst = NULL; + struct net_device *tdev; +@@ -1061,26 +1061,28 @@ static int ip6_tnl_xmit2(struct sk_buff + + /* NBMA tunnel */ + if (ipv6_addr_any(&t->parms.raddr)) { +- struct in6_addr *addr6; +- struct neighbour *neigh; +- int addr_type; +- +- if (!skb_dst(skb)) +- goto tx_err_link_failure; +- +- neigh = dst_neigh_lookup(skb_dst(skb), +- &ipv6_hdr(skb)->daddr); +- if (!neigh) +- goto tx_err_link_failure; +- +- addr6 = (struct in6_addr *)&neigh->primary_key; +- addr_type = ipv6_addr_type(addr6); +- +- if (addr_type == IPV6_ADDR_ANY) +- addr6 = &ipv6_hdr(skb)->daddr; +- +- memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); +- neigh_release(neigh); ++ if (skb->protocol == htons(ETH_P_IPV6)) { ++ struct in6_addr *addr6; ++ struct neighbour *neigh; ++ int addr_type; ++ ++ if (!skb_dst(skb)) ++ goto tx_err_link_failure; ++ ++ neigh = dst_neigh_lookup(skb_dst(skb), ++ &ipv6_hdr(skb)->daddr); ++ if (!neigh) ++ goto tx_err_link_failure; ++ ++ addr6 = (struct in6_addr *)&neigh->primary_key; ++ addr_type = ipv6_addr_type(addr6); ++ ++ if (addr_type == IPV6_ADDR_ANY) ++ addr6 = &ipv6_hdr(skb)->daddr; ++ ++ memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); ++ neigh_release(neigh); ++ } + } else if (!(t->parms.flags & + (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { + /* enable the cache only only if the routing decision does diff --git a/queue-4.4/l2tp-fix-ppp-pseudo-wire-auto-loading.patch b/queue-4.4/l2tp-fix-ppp-pseudo-wire-auto-loading.patch new file mode 100644 index 00000000000..281c52332e8 --- /dev/null +++ b/queue-4.4/l2tp-fix-ppp-pseudo-wire-auto-loading.patch @@ -0,0 +1,28 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Guillaume Nault +Date: Mon, 3 Apr 2017 13:23:15 +0200 +Subject: l2tp: fix PPP pseudo-wire auto-loading + +From: Guillaume Nault + + +[ Upstream commit 249ee819e24c180909f43c1173c8ef6724d21faf ] + +PPP pseudo-wire type is 7 (11 is L2TP_PWTYPE_IP). + +Fixes: f1f39f911027 ("l2tp: auto load type modules") +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1868,4 +1868,4 @@ MODULE_DESCRIPTION("PPP over L2TP over U + MODULE_LICENSE("GPL"); + MODULE_VERSION(PPPOL2TP_DRV_VERSION); + MODULE_ALIAS("pppox-proto-" __stringify(PX_PROTO_OL2TP)); +-MODULE_ALIAS_L2TP_PWTYPE(11); ++MODULE_ALIAS_L2TP_PWTYPE(7); diff --git a/queue-4.4/l2tp-purge-socket-queues-in-the-.destruct-callback.patch b/queue-4.4/l2tp-purge-socket-queues-in-the-.destruct-callback.patch new file mode 100644 index 00000000000..9bd56e0358f --- /dev/null +++ b/queue-4.4/l2tp-purge-socket-queues-in-the-.destruct-callback.patch @@ -0,0 +1,49 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Guillaume Nault +Date: Wed, 29 Mar 2017 08:45:29 +0200 +Subject: l2tp: purge socket queues in the .destruct() callback + +From: Guillaume Nault + + +[ Upstream commit e91793bb615cf6cdd59c0b6749fe173687bb0947 ] + +The Rx path may grab the socket right before pppol2tp_release(), but +nothing guarantees that it will enqueue packets before +skb_queue_purge(). Therefore, the socket can be destroyed without its +queues fully purged. + +Fix this by purging queues in pppol2tp_session_destruct() where we're +guaranteed nothing is still referencing the socket. + +Fixes: 9e9cb6221aa7 ("l2tp: fix userspace reception on plain L2TP sockets") +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -467,6 +467,10 @@ static void pppol2tp_session_close(struc + static void pppol2tp_session_destruct(struct sock *sk) + { + struct l2tp_session *session = sk->sk_user_data; ++ ++ skb_queue_purge(&sk->sk_receive_queue); ++ skb_queue_purge(&sk->sk_write_queue); ++ + if (session) { + sk->sk_user_data = NULL; + BUG_ON(session->magic != L2TP_SESSION_MAGIC); +@@ -505,9 +509,6 @@ static int pppol2tp_release(struct socke + l2tp_session_queue_purge(session); + sock_put(sk); + } +- skb_queue_purge(&sk->sk_receive_queue); +- skb_queue_purge(&sk->sk_write_queue); +- + release_sock(sk); + + /* This will delete the session context via diff --git a/queue-4.4/l2tp-take-reference-on-sessions-being-dumped.patch b/queue-4.4/l2tp-take-reference-on-sessions-being-dumped.patch new file mode 100644 index 00000000000..4e855eae8b9 --- /dev/null +++ b/queue-4.4/l2tp-take-reference-on-sessions-being-dumped.patch @@ -0,0 +1,159 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Guillaume Nault +Date: Mon, 3 Apr 2017 12:03:13 +0200 +Subject: l2tp: take reference on sessions being dumped + +From: Guillaume Nault + + +[ Upstream commit e08293a4ccbcc993ded0fdc46f1e57926b833d63 ] + +Take a reference on the sessions returned by l2tp_session_find_nth() +(and rename it l2tp_session_get_nth() to reflect this change), so that +caller is assured that the session isn't going to disappear while +processing it. + +For procfs and debugfs handlers, the session is held in the .start() +callback and dropped in .show(). Given that pppol2tp_seq_session_show() +dereferences the associated PPPoL2TP socket and that +l2tp_dfs_seq_session_show() might call pppol2tp_show(), we also need to +call the session's .ref() callback to prevent the socket from going +away from under us. + +Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") +Fixes: 0ad6614048cf ("l2tp: Add debugfs files for dumping l2tp debug info") +Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 8 ++++++-- + net/l2tp/l2tp_core.h | 3 ++- + net/l2tp/l2tp_debugfs.c | 10 +++++++--- + net/l2tp/l2tp_netlink.c | 7 +++++-- + net/l2tp/l2tp_ppp.c | 10 +++++++--- + 5 files changed, 27 insertions(+), 11 deletions(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -278,7 +278,8 @@ struct l2tp_session *l2tp_session_find(s + } + EXPORT_SYMBOL_GPL(l2tp_session_find); + +-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth) ++struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, ++ bool do_ref) + { + int hash; + struct l2tp_session *session; +@@ -288,6 +289,9 @@ struct l2tp_session *l2tp_session_find_n + for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { + hlist_for_each_entry(session, &tunnel->session_hlist[hash], hlist) { + if (++count > nth) { ++ l2tp_session_inc_refcount(session); ++ if (do_ref && session->ref) ++ session->ref(session); + read_unlock_bh(&tunnel->hlist_lock); + return session; + } +@@ -298,7 +302,7 @@ struct l2tp_session *l2tp_session_find_n + + return NULL; + } +-EXPORT_SYMBOL_GPL(l2tp_session_find_nth); ++EXPORT_SYMBOL_GPL(l2tp_session_get_nth); + + /* Lookup a session by interface name. + * This is very inefficient but is only used by management interfaces. +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -243,7 +243,8 @@ out: + struct l2tp_session *l2tp_session_find(struct net *net, + struct l2tp_tunnel *tunnel, + u32 session_id); +-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); ++struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, ++ bool do_ref); + struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname); + struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); + struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth); +--- a/net/l2tp/l2tp_debugfs.c ++++ b/net/l2tp/l2tp_debugfs.c +@@ -53,7 +53,7 @@ static void l2tp_dfs_next_tunnel(struct + + static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd) + { +- pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); ++ pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true); + pd->session_idx++; + + if (pd->session == NULL) { +@@ -238,10 +238,14 @@ static int l2tp_dfs_seq_show(struct seq_ + } + + /* Show the tunnel or session context */ +- if (pd->session == NULL) ++ if (!pd->session) { + l2tp_dfs_seq_tunnel_show(m, pd->tunnel); +- else ++ } else { + l2tp_dfs_seq_session_show(m, pd->session); ++ if (pd->session->deref) ++ pd->session->deref(pd->session); ++ l2tp_session_dec_refcount(pd->session); ++ } + + out: + return 0; +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -827,7 +827,7 @@ static int l2tp_nl_cmd_session_dump(stru + goto out; + } + +- session = l2tp_session_find_nth(tunnel, si); ++ session = l2tp_session_get_nth(tunnel, si, false); + if (session == NULL) { + ti++; + tunnel = NULL; +@@ -837,8 +837,11 @@ static int l2tp_nl_cmd_session_dump(stru + + if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, +- session, L2TP_CMD_SESSION_GET) < 0) ++ session, L2TP_CMD_SESSION_GET) < 0) { ++ l2tp_session_dec_refcount(session); + break; ++ } ++ l2tp_session_dec_refcount(session); + + si++; + } +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1575,7 +1575,7 @@ static void pppol2tp_next_tunnel(struct + + static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd) + { +- pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); ++ pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true); + pd->session_idx++; + + if (pd->session == NULL) { +@@ -1702,10 +1702,14 @@ static int pppol2tp_seq_show(struct seq_ + + /* Show the tunnel or session context. + */ +- if (pd->session == NULL) ++ if (!pd->session) { + pppol2tp_seq_tunnel_show(m, pd->tunnel); +- else ++ } else { + pppol2tp_seq_session_show(m, pd->session); ++ if (pd->session->deref) ++ pd->session->deref(pd->session); ++ l2tp_session_dec_refcount(pd->session); ++ } + + out: + return 0; diff --git a/queue-4.4/macvlan-fix-device-ref-leak-when-purging-bc_queue.patch b/queue-4.4/macvlan-fix-device-ref-leak-when-purging-bc_queue.patch new file mode 100644 index 00000000000..76be7d098c7 --- /dev/null +++ b/queue-4.4/macvlan-fix-device-ref-leak-when-purging-bc_queue.patch @@ -0,0 +1,52 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Herbert Xu +Date: Thu, 20 Apr 2017 20:55:12 +0800 +Subject: macvlan: Fix device ref leak when purging bc_queue + +From: Herbert Xu + + +[ Upstream commit f6478218e6edc2a587b8f132f66373baa7b2497c ] + +When a parent macvlan device is destroyed we end up purging its +broadcast queue without dropping the device reference count on +the packet source device. This causes the source device to linger. + +This patch drops that reference count. + +Fixes: 260916dfb48c ("macvlan: Fix potential use-after free for...") +Reported-by: Joe Ghalam +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvlan.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1110,6 +1110,7 @@ static int macvlan_port_create(struct ne + static void macvlan_port_destroy(struct net_device *dev) + { + struct macvlan_port *port = macvlan_port_get_rtnl(dev); ++ struct sk_buff *skb; + + dev->priv_flags &= ~IFF_MACVLAN_PORT; + netdev_rx_handler_unregister(dev); +@@ -1118,7 +1119,15 @@ static void macvlan_port_destroy(struct + * but we need to cancel it and purge left skbs if any. + */ + cancel_work_sync(&port->bc_work); +- __skb_queue_purge(&port->bc_queue); ++ ++ while ((skb = __skb_dequeue(&port->bc_queue))) { ++ const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src; ++ ++ if (src) ++ dev_put(src->dev); ++ ++ kfree_skb(skb); ++ } + + kfree_rcu(port, rcu); + } diff --git a/queue-4.4/mips-avoid-bug-warning-in-arch_check_elf.patch b/queue-4.4/mips-avoid-bug-warning-in-arch_check_elf.patch new file mode 100644 index 00000000000..93e51c7a0e5 --- /dev/null +++ b/queue-4.4/mips-avoid-bug-warning-in-arch_check_elf.patch @@ -0,0 +1,46 @@ +From c46f59e90226fa5bfcc83650edebe84ae47d454b Mon Sep 17 00:00:00 2001 +From: James Cowgill +Date: Tue, 11 Apr 2017 13:51:07 +0100 +Subject: MIPS: Avoid BUG warning in arch_check_elf + +From: James Cowgill + +commit c46f59e90226fa5bfcc83650edebe84ae47d454b upstream. + +arch_check_elf contains a usage of current_cpu_data that will call +smp_processor_id() with preemption enabled and therefore triggers a +"BUG: using smp_processor_id() in preemptible" warning when an fpxx +executable is loaded. + +As a follow-up to commit b244614a60ab ("MIPS: Avoid a BUG warning during +prctl(PR_SET_FP_MODE, ...)"), apply the same fix to arch_check_elf by +using raw_current_cpu_data instead. The rationale quoted from the previous +commit: + +"It is assumed throughout the kernel that if any CPU has an FPU, then +all CPUs would have an FPU as well, so it is safe to perform the check +with preemption enabled - change the code to use raw_ variant of the +check to avoid the warning." + +Fixes: 46490b572544 ("MIPS: kernel: elf: Improve the overall ABI and FPU mode checks") +Signed-off-by: James Cowgill +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15951/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/elf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/kernel/elf.c ++++ b/arch/mips/kernel/elf.c +@@ -206,7 +206,7 @@ int arch_check_elf(void *_ehdr, bool has + else if ((prog_req.fr1 && prog_req.frdefault) || + (prog_req.single && !prog_req.frdefault)) + /* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */ +- state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) && ++ state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) && + cpu_has_mips_r2_r6) ? + FP_FR1 : FP_FR0; + else if (prog_req.fr1) diff --git a/queue-4.4/mips-kgdb-use-kernel-context-for-sleeping-threads.patch b/queue-4.4/mips-kgdb-use-kernel-context-for-sleeping-threads.patch new file mode 100644 index 00000000000..22f985ab3f9 --- /dev/null +++ b/queue-4.4/mips-kgdb-use-kernel-context-for-sleeping-threads.patch @@ -0,0 +1,125 @@ +From 162b270c664dca2e0944308e92f9fcc887151a72 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Thu, 30 Mar 2017 16:06:02 +0100 +Subject: MIPS: KGDB: Use kernel context for sleeping threads + +From: James Hogan + +commit 162b270c664dca2e0944308e92f9fcc887151a72 upstream. + +KGDB is a kernel debug stub and it can't be used to debug userland as it +can only safely access kernel memory. + +On MIPS however KGDB has always got the register state of sleeping +processes from the userland register context at the beginning of the +kernel stack. This is meaningless for kernel threads (which never enter +userland), and for user threads it prevents the user seeing what it is +doing while in the kernel: + +(gdb) info threads + Id Target Id Frame + ... + 3 Thread 2 (kthreadd) 0x0000000000000000 in ?? () + 2 Thread 1 (init) 0x000000007705c4b4 in ?? () + 1 Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201 + +Get the register state instead from the (partial) kernel register +context stored in the task's thread_struct for resume() to restore. All +threads now correctly appear to be in context_switch(): + +(gdb) info threads + Id Target Id Frame + ... + 3 Thread 2 (kthreadd) context_switch (rq=, cookie=..., next=, prev=0x0) at kernel/sched/core.c:2903 + 2 Thread 1 (init) context_switch (rq=, cookie=..., next=, prev=0x0) at kernel/sched/core.c:2903 + 1 Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201 + +Call clobbered registers which aren't saved and exception registers +(BadVAddr & Cause) which can't be easily determined without stack +unwinding are reported as 0. The PC is taken from the return address, +such that the state presented matches that found immediately after +returning from resume(). + +Fixes: 8854700115ec ("[MIPS] kgdb: add arch support for the kernel's kgdb core") +Signed-off-by: James Hogan +Cc: Jason Wessel +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15829/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/kgdb.c | 48 +++++++++++++++++++++++++++++++++--------------- + 1 file changed, 33 insertions(+), 15 deletions(-) + +--- a/arch/mips/kernel/kgdb.c ++++ b/arch/mips/kernel/kgdb.c +@@ -244,9 +244,6 @@ static int compute_signal(int tt) + void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) + { + int reg; +- struct thread_info *ti = task_thread_info(p); +- unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32; +- struct pt_regs *regs = (struct pt_regs *)ksp - 1; + #if (KGDB_GDB_REG_SIZE == 32) + u32 *ptr = (u32 *)gdb_regs; + #else +@@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigne + #endif + + for (reg = 0; reg < 16; reg++) +- *(ptr++) = regs->regs[reg]; ++ *(ptr++) = 0; + + /* S0 - S7 */ +- for (reg = 16; reg < 24; reg++) +- *(ptr++) = regs->regs[reg]; ++ *(ptr++) = p->thread.reg16; ++ *(ptr++) = p->thread.reg17; ++ *(ptr++) = p->thread.reg18; ++ *(ptr++) = p->thread.reg19; ++ *(ptr++) = p->thread.reg20; ++ *(ptr++) = p->thread.reg21; ++ *(ptr++) = p->thread.reg22; ++ *(ptr++) = p->thread.reg23; + + for (reg = 24; reg < 28; reg++) + *(ptr++) = 0; + + /* GP, SP, FP, RA */ +- for (reg = 28; reg < 32; reg++) +- *(ptr++) = regs->regs[reg]; +- +- *(ptr++) = regs->cp0_status; +- *(ptr++) = regs->lo; +- *(ptr++) = regs->hi; +- *(ptr++) = regs->cp0_badvaddr; +- *(ptr++) = regs->cp0_cause; +- *(ptr++) = regs->cp0_epc; ++ *(ptr++) = (long)p; ++ *(ptr++) = p->thread.reg29; ++ *(ptr++) = p->thread.reg30; ++ *(ptr++) = p->thread.reg31; ++ ++ *(ptr++) = p->thread.cp0_status; ++ ++ /* lo, hi */ ++ *(ptr++) = 0; ++ *(ptr++) = 0; ++ ++ /* ++ * BadVAddr, Cause ++ * Ideally these would come from the last exception frame up the stack ++ * but that requires unwinding, otherwise we can't know much for sure. ++ */ ++ *(ptr++) = 0; ++ *(ptr++) = 0; ++ ++ /* ++ * PC ++ * use return address (RA), i.e. the moment after return from resume() ++ */ ++ *(ptr++) = p->thread.reg31; + } + + void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) diff --git a/queue-4.4/net-ipv4-fix-multipath-rtm_getroute-behavior-when-iif-is-given.patch b/queue-4.4/net-ipv4-fix-multipath-rtm_getroute-behavior-when-iif-is-given.patch new file mode 100644 index 00000000000..a0d5596bfff --- /dev/null +++ b/queue-4.4/net-ipv4-fix-multipath-rtm_getroute-behavior-when-iif-is-given.patch @@ -0,0 +1,37 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Florian Larysch +Date: Mon, 3 Apr 2017 16:46:09 +0200 +Subject: net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given + +From: Florian Larysch + + +[ Upstream commit a8801799c6975601fd58ae62f48964caec2eb83f ] + +inet_rtm_getroute synthesizes a skeletal ICMP skb, which is passed to +ip_route_input when iif is given. If a multipath route is present for +the designated destination, ip_multipath_icmp_hash ends up being called, +which uses the source/destination addresses within the skb to calculate +a hash. However, those are not set in the synthetic skb, causing it to +return an arbitrary and incorrect result. + +Instead, use UDP, which gets no such special treatment. + +Signed-off-by: Florian Larysch +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/route.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2559,7 +2559,7 @@ static int inet_rtm_getroute(struct sk_b + skb_reset_network_header(skb); + + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ +- ip_hdr(skb)->protocol = IPPROTO_ICMP; ++ ip_hdr(skb)->protocol = IPPROTO_UDP; + skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); + + src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0; diff --git a/queue-4.4/net-ipv6-rtf_pcpu-should-not-be-settable-from-userspace.patch b/queue-4.4/net-ipv6-rtf_pcpu-should-not-be-settable-from-userspace.patch new file mode 100644 index 00000000000..6d2d3c13a8c --- /dev/null +++ b/queue-4.4/net-ipv6-rtf_pcpu-should-not-be-settable-from-userspace.patch @@ -0,0 +1,79 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: David Ahern +Date: Wed, 19 Apr 2017 14:19:43 -0700 +Subject: net: ipv6: RTF_PCPU should not be settable from userspace + +From: David Ahern + + +[ Upstream commit 557c44be917c322860665be3d28376afa84aa936 ] + +Andrey reported a fault in the IPv6 route code: + +kasan: GPF could be caused by NULL-ptr deref or user memory access +general protection fault: 0000 [#1] SMP KASAN +Modules linked in: +CPU: 1 PID: 4035 Comm: a.out Not tainted 4.11.0-rc7+ #250 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +task: ffff880069809600 task.stack: ffff880062dc8000 +RIP: 0010:ip6_rt_cache_alloc+0xa6/0x560 net/ipv6/route.c:975 +RSP: 0018:ffff880062dced30 EFLAGS: 00010206 +RAX: dffffc0000000000 RBX: ffff8800670561c0 RCX: 0000000000000006 +RDX: 0000000000000003 RSI: ffff880062dcfb28 RDI: 0000000000000018 +RBP: ffff880062dced68 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffff880062dcfb28 R14: dffffc0000000000 R15: 0000000000000000 +FS: 00007feebe37e7c0(0000) GS:ffff88006cb00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000205a0fe4 CR3: 000000006b5c9000 CR4: 00000000000006e0 +Call Trace: + ip6_pol_route+0x1512/0x1f20 net/ipv6/route.c:1128 + ip6_pol_route_output+0x4c/0x60 net/ipv6/route.c:1212 +... + +Andrey's syzkaller program passes rtmsg.rtmsg_flags with the RTF_PCPU bit +set. Flags passed to the kernel are blindly copied to the allocated +rt6_info by ip6_route_info_create making a newly inserted route appear +as though it is a per-cpu route. ip6_rt_cache_alloc sees the flag set +and expects rt->dst.from to be set - which it is not since it is not +really a per-cpu copy. The subsequent call to __ip6_dst_alloc then +generates the fault. + +Fix by checking for the flag and failing with EINVAL. + +Fixes: d52d3997f843f ("ipv6: Create percpu rt6_info") +Reported-by: Andrey Konovalov +Signed-off-by: David Ahern +Acked-by: Martin KaFai Lau +Tested-by: Andrey Konovalov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/ipv6_route.h | 2 +- + net/ipv6/route.c | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/include/uapi/linux/ipv6_route.h ++++ b/include/uapi/linux/ipv6_route.h +@@ -34,7 +34,7 @@ + #define RTF_PREF(pref) ((pref) << 27) + #define RTF_PREF_MASK 0x18000000 + +-#define RTF_PCPU 0x40000000 ++#define RTF_PCPU 0x40000000 /* read-only: can not be set by user */ + #define RTF_LOCAL 0x80000000 + + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1758,6 +1758,10 @@ static struct rt6_info *ip6_route_info_c + int addr_type; + int err = -EINVAL; + ++ /* RTF_PCPU is an internal flag; can not be set by userspace */ ++ if (cfg->fc_flags & RTF_PCPU) ++ goto out; ++ + if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128) + goto out; + #ifndef CONFIG_IPV6_SUBTREES diff --git a/queue-4.4/net-mlx5-fix-driver-load-bad-flow-when-having-fw-initializing-timeout.patch b/queue-4.4/net-mlx5-fix-driver-load-bad-flow-when-having-fw-initializing-timeout.patch new file mode 100644 index 00000000000..9398bbc94d9 --- /dev/null +++ b/queue-4.4/net-mlx5-fix-driver-load-bad-flow-when-having-fw-initializing-timeout.patch @@ -0,0 +1,33 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Mohamad Haj Yahia +Date: Thu, 30 Mar 2017 17:00:25 +0300 +Subject: net/mlx5: Fix driver load bad flow when having fw initializing timeout + +From: Mohamad Haj Yahia + + +[ Upstream commit 55378a238e04b39cc82957d91d16499704ea719b ] + +If FW is stuck in initializing state we will skip the driver load, but +current error handling flow doesn't clean previously allocated command +interface resources. + +Fixes: e3297246c2c8 ('net/mlx5_core: Wait for FW readiness on startup') +Signed-off-by: Mohamad Haj Yahia +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -944,7 +944,7 @@ static int mlx5_load_one(struct mlx5_cor + if (err) { + dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n", + FW_INIT_TIMEOUT_MILI); +- goto out_err; ++ goto err_cmd_cleanup; + } + + mlx5_pagealloc_init(dev); diff --git a/queue-4.4/net-neigh-guard-against-null-solicit-method.patch b/queue-4.4/net-neigh-guard-against-null-solicit-method.patch new file mode 100644 index 00000000000..0469253d7ce --- /dev/null +++ b/queue-4.4/net-neigh-guard-against-null-solicit-method.patch @@ -0,0 +1,38 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Eric Dumazet +Date: Thu, 23 Mar 2017 12:39:21 -0700 +Subject: net: neigh: guard against NULL solicit() method + +From: Eric Dumazet + + +[ Upstream commit 48481c8fa16410ffa45939b13b6c53c2ca609e5f ] + +Dmitry posted a nice reproducer of a bug triggering in neigh_probe() +when dereferencing a NULL neigh->ops->solicit method. + +This can happen for arp_direct_ops/ndisc_direct_ops and similar, +which can be used for NUD_NOARP neighbours (created when dev->header_ops +is NULL). Admin can then force changing nud_state to some other state +that would fire neigh timer. + +Signed-off-by: Eric Dumazet +Reported-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/neighbour.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -859,7 +859,8 @@ static void neigh_probe(struct neighbour + if (skb) + skb = skb_clone(skb, GFP_ATOMIC); + write_unlock(&neigh->lock); +- neigh->ops->solicit(neigh, skb); ++ if (neigh->ops->solicit) ++ neigh->ops->solicit(neigh, skb); + atomic_inc(&neigh->probes); + kfree_skb(skb); + } diff --git a/queue-4.4/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch b/queue-4.4/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch new file mode 100644 index 00000000000..2a8149cd841 --- /dev/null +++ b/queue-4.4/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch @@ -0,0 +1,37 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Andrey Konovalov +Date: Wed, 29 Mar 2017 16:11:21 +0200 +Subject: net/packet: fix overflow in check for tp_frame_nr + +From: Andrey Konovalov + + +[ Upstream commit 8f8d28e4d6d815a391285e121c3a53a0b6cb9e7b ] + +When calculating rb->frames_per_block * req->tp_block_nr the result +can overflow. + +Add a check that tp_block_size * tp_block_nr <= UINT_MAX. + +Since frames_per_block <= tp_block_size, the expression would +never overflow. + +Signed-off-by: Andrey Konovalov +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4150,6 +4150,8 @@ static int packet_set_ring(struct sock * + rb->frames_per_block = req->tp_block_size / req->tp_frame_size; + if (unlikely(rb->frames_per_block == 0)) + goto out; ++ if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr)) ++ goto out; + if (unlikely((rb->frames_per_block * req->tp_block_nr) != + req->tp_frame_nr)) + goto out; diff --git a/queue-4.4/net-packet-fix-overflow-in-check-for-tp_reserve.patch b/queue-4.4/net-packet-fix-overflow-in-check-for-tp_reserve.patch new file mode 100644 index 00000000000..eb491d451f1 --- /dev/null +++ b/queue-4.4/net-packet-fix-overflow-in-check-for-tp_reserve.patch @@ -0,0 +1,33 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Andrey Konovalov +Date: Wed, 29 Mar 2017 16:11:22 +0200 +Subject: net/packet: fix overflow in check for tp_reserve + +From: Andrey Konovalov + + +[ Upstream commit bcc5364bdcfe131e6379363f089e7b4108d35b70 ] + +When calculating po->tp_hdrlen + po->tp_reserve the result can overflow. + +Fix by checking that tp_reserve <= INT_MAX on assign. + +Signed-off-by: Andrey Konovalov +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3626,6 +3626,8 @@ packet_setsockopt(struct socket *sock, i + return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; ++ if (val > INT_MAX) ++ return -EINVAL; + po->tp_reserve = val; + return 0; + } diff --git a/queue-4.4/net-phy-handle-state-correctly-in-phy_stop_machine.patch b/queue-4.4/net-phy-handle-state-correctly-in-phy_stop_machine.patch new file mode 100644 index 00000000000..8bc26442bfd --- /dev/null +++ b/queue-4.4/net-phy-handle-state-correctly-in-phy_stop_machine.patch @@ -0,0 +1,37 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Nathan Sullivan +Date: Wed, 22 Mar 2017 15:27:01 -0500 +Subject: net: phy: handle state correctly in phy_stop_machine + +From: Nathan Sullivan + + +[ Upstream commit 49d52e8108a21749dc2114b924c907db43358984 ] + +If the PHY is halted on stop, then do not set the state to PHY_UP. This +ensures the phy will be restarted later in phy_start when the machine is +started again. + +Fixes: 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details.") +Signed-off-by: Nathan Sullivan +Signed-off-by: Brad Mouring +Acked-by: Xander Huff +Acked-by: Kyle Roeschley +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -538,7 +538,7 @@ void phy_stop_machine(struct phy_device + cancel_delayed_work_sync(&phydev->state_queue); + + mutex_lock(&phydev->lock); +- if (phydev->state > PHY_UP) ++ if (phydev->state > PHY_UP && phydev->state != PHY_HALTED) + phydev->state = PHY_UP; + mutex_unlock(&phydev->lock); + } diff --git a/queue-4.4/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch b/queue-4.4/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch new file mode 100644 index 00000000000..cb431181d90 --- /dev/null +++ b/queue-4.4/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch @@ -0,0 +1,105 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Willem de Bruijn +Date: Wed, 12 Apr 2017 19:24:35 -0400 +Subject: net-timestamp: avoid use-after-free in ip_recv_error + +From: Willem de Bruijn + + +[ Upstream commit 1862d6208db0aeca9c8ace44915b08d5ab2cd667 ] + +Syzkaller reported a use-after-free in ip_recv_error at line + + info->ipi_ifindex = skb->dev->ifindex; + +This function is called on dequeue from the error queue, at which +point the device pointer may no longer be valid. + +Save ifindex on enqueue in __skb_complete_tx_timestamp, when the +pointer is valid or NULL. Store it in temporary storage skb->cb. + +It is safe to reference skb->dev here, as called from device drivers +or dev_queue_xmit. The exception is when called from tcp_ack_tstamp; +in that case it is NULL and ifindex is set to 0 (invalid). + +Do not return a pktinfo cmsg if ifindex is 0. This maintains the +current behavior of not returning a cmsg if skb->dev was NULL. + +On dequeue, the ipv4 path will cast from sock_exterr_skb to +in_pktinfo. Both have ifindex as their first element, so no explicit +conversion is needed. This is by design, introduced in commit +0b922b7a829c ("net: original ingress device index in PKTINFO"). For +ipv6 ip6_datagram_support_cmsg converts to in6_pktinfo. + +Fixes: 829ae9d61165 ("net-timestamp: allow reading recv cmsg on errqueue with origin tstamp") +Reported-by: Andrey Konovalov +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 1 + + net/ipv4/ip_sockglue.c | 9 ++++----- + net/ipv6/datagram.c | 10 +--------- + 3 files changed, 6 insertions(+), 14 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3643,6 +3643,7 @@ static void __skb_complete_tx_timestamp( + serr->ee.ee_errno = ENOMSG; + serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; + serr->ee.ee_info = tstype; ++ serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; + if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { + serr->ee.ee_data = skb_shinfo(skb)->tskey; + if (sk->sk_protocol == IPPROTO_TCP && +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -463,16 +463,15 @@ static bool ipv4_datagram_support_cmsg(c + return false; + + /* Support IP_PKTINFO on tstamp packets if requested, to correlate +- * timestamp with egress dev. Not possible for packets without dev ++ * timestamp with egress dev. Not possible for packets without iif + * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). + */ +- if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || +- (!skb->dev)) ++ info = PKTINFO_SKB_CB(skb); ++ if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) || ++ !info->ipi_ifindex) + return false; + +- info = PKTINFO_SKB_CB(skb); + info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; +- info->ipi_ifindex = skb->dev->ifindex; + return true; + } + +--- a/net/ipv6/datagram.c ++++ b/net/ipv6/datagram.c +@@ -355,9 +355,6 @@ static inline bool ipv6_datagram_support + * At one point, excluding local errors was a quick test to identify icmp/icmp6 + * errors. This is no longer true, but the test remained, so the v6 stack, + * unlike v4, also honors cmsg requests on all wifi and timestamp errors. +- * +- * Timestamp code paths do not initialize the fields expected by cmsg: +- * the PKTINFO fields in skb->cb[]. Fill those in here. + */ + static bool ip6_datagram_support_cmsg(struct sk_buff *skb, + struct sock_exterr_skb *serr) +@@ -369,14 +366,9 @@ static bool ip6_datagram_support_cmsg(st + if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) + return false; + +- if (!skb->dev) ++ if (!IP6CB(skb)->iif) + return false; + +- if (skb->protocol == htons(ETH_P_IPV6)) +- IP6CB(skb)->iif = skb->dev->ifindex; +- else +- PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; +- + return true; + } + diff --git a/queue-4.4/netpoll-check-for-skb-queue_mapping.patch b/queue-4.4/netpoll-check-for-skb-queue_mapping.patch new file mode 100644 index 00000000000..5ae07328fe8 --- /dev/null +++ b/queue-4.4/netpoll-check-for-skb-queue_mapping.patch @@ -0,0 +1,104 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Tushar Dave +Date: Thu, 20 Apr 2017 15:57:31 -0700 +Subject: netpoll: Check for skb->queue_mapping + +From: Tushar Dave + + +[ Upstream commit c70b17b775edb21280e9de7531acf6db3b365274 ] + +Reducing real_num_tx_queues needs to be in sync with skb queue_mapping +otherwise skbs with queue_mapping greater than real_num_tx_queues +can be sent to the underlying driver and can result in kernel panic. + +One such event is running netconsole and enabling VF on the same +device. Or running netconsole and changing number of tx queues via +ethtool on same device. + +e.g. +Unable to handle kernel NULL pointer dereference +tsk->{mm,active_mm}->context = 0000000000001525 +tsk->{mm,active_mm}->pgd = fff800130ff9a000 + \|/ ____ \|/ + "@'/ .. \`@" + /_| \__/ |_\ + \__U_/ +kworker/48:1(475): Oops [#1] +CPU: 48 PID: 475 Comm: kworker/48:1 Tainted: G OE +4.11.0-rc3-davem-net+ #7 +Workqueue: events queue_process +task: fff80013113299c0 task.stack: fff800131132c000 +TSTATE: 0000004480e01600 TPC: 00000000103f9e3c TNPC: 00000000103f9e40 Y: +00000000 Tainted: G OE +TPC: +g0: 0000000000000000 g1: 0000000000003fff g2: 0000000000000000 g3: +0000000000000001 +g4: fff80013113299c0 g5: fff8001fa6808000 g6: fff800131132c000 g7: +00000000000000c0 +o0: fff8001fa760c460 o1: fff8001311329a50 o2: fff8001fa7607504 o3: +0000000000000003 +o4: fff8001f96e63a40 o5: fff8001311d77ec0 sp: fff800131132f0e1 ret_pc: +000000000049ed94 +RPC: +l0: 0000000000000000 l1: 0000000000000800 l2: 0000000000000000 l3: +0000000000000000 +l4: 000b2aa30e34b10d l5: 0000000000000000 l6: 0000000000000000 l7: +fff8001fa7605028 +i0: fff80013111a8a00 i1: fff80013155a0780 i2: 0000000000000000 i3: +0000000000000000 +i4: 0000000000000000 i5: 0000000000100000 i6: fff800131132f1a1 i7: +00000000103fa4b0 +I7: +Call Trace: + [00000000103fa4b0] ixgbe_xmit_frame+0x30/0xa0 [ixgbe] + [0000000000998c74] netpoll_start_xmit+0xf4/0x200 + [0000000000998e10] queue_process+0x90/0x160 + [0000000000485fa8] process_one_work+0x188/0x480 + [0000000000486410] worker_thread+0x170/0x4c0 + [000000000048c6b8] kthread+0xd8/0x120 + [0000000000406064] ret_from_fork+0x1c/0x2c + [0000000000000000] (null) +Disabling lock debugging due to kernel taint +Caller[00000000103fa4b0]: ixgbe_xmit_frame+0x30/0xa0 [ixgbe] +Caller[0000000000998c74]: netpoll_start_xmit+0xf4/0x200 +Caller[0000000000998e10]: queue_process+0x90/0x160 +Caller[0000000000485fa8]: process_one_work+0x188/0x480 +Caller[0000000000486410]: worker_thread+0x170/0x4c0 +Caller[000000000048c6b8]: kthread+0xd8/0x120 +Caller[0000000000406064]: ret_from_fork+0x1c/0x2c +Caller[0000000000000000]: (null) + +Signed-off-by: Tushar Dave +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -105,15 +105,21 @@ static void queue_process(struct work_st + while ((skb = skb_dequeue(&npinfo->txq))) { + struct net_device *dev = skb->dev; + struct netdev_queue *txq; ++ unsigned int q_index; + + if (!netif_device_present(dev) || !netif_running(dev)) { + kfree_skb(skb); + continue; + } + +- txq = skb_get_tx_queue(dev, skb); +- + local_irq_save(flags); ++ /* check if skb->queue_mapping is still valid */ ++ q_index = skb_get_queue_mapping(skb); ++ if (unlikely(q_index >= dev->real_num_tx_queues)) { ++ q_index = q_index % dev->real_num_tx_queues; ++ skb_set_queue_mapping(skb, q_index); ++ } ++ txq = netdev_get_tx_queue(dev, q_index); + HARD_TX_LOCK(dev, txq, smp_processor_id()); + if (netif_xmit_frozen_or_stopped(txq) || + netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) { diff --git a/queue-4.4/nfsd-check-for-oversized-nfsv2-v3-arguments.patch b/queue-4.4/nfsd-check-for-oversized-nfsv2-v3-arguments.patch new file mode 100644 index 00000000000..b5558b58343 --- /dev/null +++ b/queue-4.4/nfsd-check-for-oversized-nfsv2-v3-arguments.patch @@ -0,0 +1,103 @@ +From e6838a29ecb484c97e4efef9429643b9851fba6e Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Fri, 21 Apr 2017 16:10:18 -0400 +Subject: nfsd: check for oversized NFSv2/v3 arguments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: J. Bruce Fields + +commit e6838a29ecb484c97e4efef9429643b9851fba6e upstream. + +A client can append random data to the end of an NFSv2 or NFSv3 RPC call +without our complaining; we'll just stop parsing at the end of the +expected data and ignore the rest. + +Encoded arguments and replies are stored together in an array of pages, +and if a call is too large it could leave inadequate space for the +reply. This is normally OK because NFS RPC's typically have either +short arguments and long replies (like READ) or long arguments and short +replies (like WRITE). But a client that sends an incorrectly long reply +can violate those assumptions. This was observed to cause crashes. + +Also, several operations increment rq_next_page in the decode routine +before checking the argument size, which can leave rq_next_page pointing +well past the end of the page array, causing trouble later in +svc_free_pages. + +So, following a suggestion from Neil Brown, add a central check to +enforce our expectation that no NFSv2/v3 call has both a large call and +a large reply. + +As followup we may also want to rewrite the encoding routines to check +more carefully that they aren't running off the end of the page array. + +We may also consider rejecting calls that have any extra garbage +appended. That would be safer, and within our rights by spec, but given +the age of our server and the NFS protocol, and the fact that we've +never enforced this before, we may need to balance that against the +possibility of breaking some oddball client. + +Reported-by: Tuomas Haanpää +Reported-by: Ari Kauppi +Reviewed-by: NeilBrown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfssvc.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -656,6 +656,37 @@ static __be32 map_new_errors(u32 vers, _ + return nfserr; + } + ++/* ++ * A write procedure can have a large argument, and a read procedure can ++ * have a large reply, but no NFSv2 or NFSv3 procedure has argument and ++ * reply that can both be larger than a page. The xdr code has taken ++ * advantage of this assumption to be a sloppy about bounds checking in ++ * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that ++ * problem, we enforce these assumptions here: ++ */ ++static bool nfs_request_too_big(struct svc_rqst *rqstp, ++ struct svc_procedure *proc) ++{ ++ /* ++ * The ACL code has more careful bounds-checking and is not ++ * susceptible to this problem: ++ */ ++ if (rqstp->rq_prog != NFS_PROGRAM) ++ return false; ++ /* ++ * Ditto NFSv4 (which can in theory have argument and reply both ++ * more than a page): ++ */ ++ if (rqstp->rq_vers >= 4) ++ return false; ++ /* The reply will be small, we're OK: */ ++ if (proc->pc_xdrressize > 0 && ++ proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE)) ++ return false; ++ ++ return rqstp->rq_arg.len > PAGE_SIZE; ++} ++ + int + nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) + { +@@ -668,6 +699,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __ + rqstp->rq_vers, rqstp->rq_proc); + proc = rqstp->rq_procinfo; + ++ if (nfs_request_too_big(rqstp, proc)) { ++ dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers); ++ *statp = rpc_garbage_args; ++ return 1; ++ } + /* + * Give the xdr decoder a chance to change this if it wants + * (necessary in the NFSv4.0 compound case) diff --git a/queue-4.4/p9_client_readdir-fix.patch b/queue-4.4/p9_client_readdir-fix.patch new file mode 100644 index 00000000000..b82f59e0a43 --- /dev/null +++ b/queue-4.4/p9_client_readdir-fix.patch @@ -0,0 +1,32 @@ +From 71d6ad08379304128e4bdfaf0b4185d54375423e Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 14 Apr 2017 17:22:18 -0400 +Subject: p9_client_readdir() fix + +From: Al Viro + +commit 71d6ad08379304128e4bdfaf0b4185d54375423e upstream. + +Don't assume that server is sane and won't return more data than +asked for. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + net/9p/client.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -2101,6 +2101,10 @@ int p9_client_readdir(struct p9_fid *fid + trace_9p_protocol_dump(clnt, req->rc); + goto free_and_error; + } ++ if (rsize < count) { ++ pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize); ++ count = rsize; ++ } + + p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); + diff --git a/queue-4.4/sctp-listen-on-the-sock-only-when-it-s-state-is-listening-or-closed.patch b/queue-4.4/sctp-listen-on-the-sock-only-when-it-s-state-is-listening-or-closed.patch new file mode 100644 index 00000000000..28ebb749080 --- /dev/null +++ b/queue-4.4/sctp-listen-on-the-sock-only-when-it-s-state-is-listening-or-closed.patch @@ -0,0 +1,39 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Xin Long +Date: Thu, 6 Apr 2017 13:10:52 +0800 +Subject: sctp: listen on the sock only when it's state is listening or closed + +From: Xin Long + + +[ Upstream commit 34b2789f1d9bf8dcca9b5cb553d076ca2cd898ee ] + +Now sctp doesn't check sock's state before listening on it. It could +even cause changing a sock with any state to become a listening sock +when doing sctp_listen. + +This patch is to fix it by checking sock's state in sctp_listen, so +that it will listen on the sock with right state. + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -6394,6 +6394,9 @@ int sctp_inet_listen(struct socket *sock + if (sock->state != SS_UNCONNECTED) + goto out; + ++ if (!sctp_sstate(sk, LISTENING) && !sctp_sstate(sk, CLOSED)) ++ goto out; ++ + /* If backlog is zero, disable listening. */ + if (!backlog) { + if (sctp_sstate(sk, CLOSED)) diff --git a/queue-4.4/series b/queue-4.4/series index cc1e879ec82..b74ff62c247 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -15,3 +15,30 @@ usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch xen-x86-don-t-lose-event-interrupts.patch sparc64-kern_addr_valid-regression.patch sparc64-fix-kernel-panic-due-to-erroneous-ifdef-surrounding-pmd_write.patch +net-neigh-guard-against-null-solicit-method.patch +net-phy-handle-state-correctly-in-phy_stop_machine.patch +l2tp-purge-socket-queues-in-the-.destruct-callback.patch +net-packet-fix-overflow-in-check-for-tp_frame_nr.patch +net-packet-fix-overflow-in-check-for-tp_reserve.patch +l2tp-take-reference-on-sessions-being-dumped.patch +l2tp-fix-ppp-pseudo-wire-auto-loading.patch +net-ipv4-fix-multipath-rtm_getroute-behavior-when-iif-is-given.patch +sctp-listen-on-the-sock-only-when-it-s-state-is-listening-or-closed.patch +tcp-clear-saved_syn-in-tcp_disconnect.patch +net-timestamp-avoid-use-after-free-in-ip_recv_error.patch +dp83640-don-t-recieve-time-stamps-twice.patch +net-ipv6-rtf_pcpu-should-not-be-settable-from-userspace.patch +netpoll-check-for-skb-queue_mapping.patch +ip6mr-fix-notification-device-destruction.patch +net-mlx5-fix-driver-load-bad-flow-when-having-fw-initializing-timeout.patch +macvlan-fix-device-ref-leak-when-purging-bc_queue.patch +ipv6-check-skb-protocol-before-lookup-for-nexthop.patch +ipv6-check-raw-payload-size-correctly-in-ioctl.patch +alsa-firewire-lib-fix-inappropriate-assignment-between-signed-unsigned-type.patch +alsa-seq-don-t-break-snd_use_lock_sync-loop-by-timeout.patch +mips-kgdb-use-kernel-context-for-sleeping-threads.patch +mips-avoid-bug-warning-in-arch_check_elf.patch +p9_client_readdir-fix.patch +input-i8042-add-clevo-p650rs-to-the-i8042-reset-list.patch +nfsd-check-for-oversized-nfsv2-v3-arguments.patch +arcv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-code-gen.patch diff --git a/queue-4.4/tcp-clear-saved_syn-in-tcp_disconnect.patch b/queue-4.4/tcp-clear-saved_syn-in-tcp_disconnect.patch new file mode 100644 index 00000000000..eecfa3cc20b --- /dev/null +++ b/queue-4.4/tcp-clear-saved_syn-in-tcp_disconnect.patch @@ -0,0 +1,56 @@ +From foo@baz Sun Apr 30 15:46:17 CEST 2017 +From: Eric Dumazet +Date: Sat, 8 Apr 2017 08:07:33 -0700 +Subject: tcp: clear saved_syn in tcp_disconnect() + +From: Eric Dumazet + + +[ Upstream commit 17c3060b1701fc69daedb4c90be6325d3d9fca8e ] + +In the (very unlikely) case a passive socket becomes a listener, +we do not want to duplicate its saved SYN headers. + +This would lead to double frees, use after free, and please hackers and +various fuzzers + +Tested: + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, IPPROTO_TCP, TCP_SAVE_SYN, [1], 4) = 0 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 + + +0 bind(3, ..., ...) = 0 + +0 listen(3, 5) = 0 + + +0 < S 0:0(0) win 32972 + +0 > S. 0:0(0) ack 1 <...> + +.1 < . 1:1(0) ack 1 win 257 + +0 accept(3, ..., ...) = 4 + + +0 connect(4, AF_UNSPEC, ...) = 0 + +0 close(3) = 0 + +0 bind(4, ..., ...) = 0 + +0 listen(4, 5) = 0 + + +0 < S 0:0(0) win 32972 + +0 > S. 0:0(0) ack 1 <...> + +.1 < . 1:1(0) ack 1 win 257 + +Fixes: cd8ae85299d5 ("tcp: provide SYN headers for passive connections") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2260,6 +2260,7 @@ int tcp_disconnect(struct sock *sk, int + tcp_init_send_head(sk); + memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); + __sk_dst_reset(sk); ++ tcp_saved_syn_free(tp); + + WARN_ON(inet->inet_num && !icsk->icsk_bind_hash); +