]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Nov 2017 14:22:12 +0000 (15:22 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Nov 2017 14:22:12 +0000 (15:22 +0100)
added patches:
ip6_gre-only-increase-err_count-for-some-certain-type-icmpv6-in-ip6gre_err.patch
ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch
l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch
net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch
packet-avoid-panic-in-packet_getsockopt.patch
ppp-fix-race-in-ppp-device-destruction.patch
sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch
sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch
tcp-fix-tcp_mtu_probe-vs-highest_sack.patch
tun-allow-positive-return-values-on-dev_get_valid_name-call.patch
tun-call-dev_get_valid_name-before-register_netdevice.patch
tun-tap-sanitize-tunsetsndbuf-input.patch

13 files changed:
queue-4.4/ip6_gre-only-increase-err_count-for-some-certain-type-icmpv6-in-ip6gre_err.patch [new file with mode: 0644]
queue-4.4/ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch [new file with mode: 0644]
queue-4.4/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch [new file with mode: 0644]
queue-4.4/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch [new file with mode: 0644]
queue-4.4/packet-avoid-panic-in-packet_getsockopt.patch [new file with mode: 0644]
queue-4.4/ppp-fix-race-in-ppp-device-destruction.patch [new file with mode: 0644]
queue-4.4/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch [new file with mode: 0644]
queue-4.4/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch [new file with mode: 0644]
queue-4.4/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch [new file with mode: 0644]
queue-4.4/tun-call-dev_get_valid_name-before-register_netdevice.patch [new file with mode: 0644]
queue-4.4/tun-tap-sanitize-tunsetsndbuf-input.patch [new file with mode: 0644]

diff --git a/queue-4.4/ip6_gre-only-increase-err_count-for-some-certain-type-icmpv6-in-ip6gre_err.patch b/queue-4.4/ip6_gre-only-increase-err_count-for-some-certain-type-icmpv6-in-ip6gre_err.patch
new file mode 100644 (file)
index 0000000..2bc5987
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Thu, 26 Oct 2017 19:23:27 +0800
+Subject: ip6_gre: only increase err_count for some certain type icmpv6 in ip6gre_err
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit f8d20b46ce55cf40afb30dcef6d9288f7ef46d9b ]
+
+The similar fix in patch 'ipip: only increase err_count for some
+certain type icmp in ipip_err' is needed for ip6gre_err.
+
+In Jianlin's case, udp netperf broke even when receiving a TooBig
+icmpv6 packet.
+
+Fixes: c12b395a4664 ("gre: Support GRE over IPv6")
+Reported-by: Jianlin Shi <jishi@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_gre.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -409,13 +409,16 @@ static void ip6gre_err(struct sk_buff *s
+       case ICMPV6_DEST_UNREACH:
+               net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
+                                   t->parms.name);
+-              break;
++              if (code != ICMPV6_PORT_UNREACH)
++                      break;
++              return;
+       case ICMPV6_TIME_EXCEED:
+               if (code == ICMPV6_EXC_HOPLIMIT) {
+                       net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
+                                           t->parms.name);
++                      break;
+               }
+-              break;
++              return;
+       case ICMPV6_PARAMPROB:
+               teli = 0;
+               if (code == ICMPV6_HDR_FIELD)
+@@ -431,13 +434,13 @@ static void ip6gre_err(struct sk_buff *s
+                       net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
+                                           t->parms.name);
+               }
+-              break;
++              return;
+       case ICMPV6_PKT_TOOBIG:
+               mtu = be32_to_cpu(info) - offset;
+               if (mtu < IPV6_MIN_MTU)
+                       mtu = IPV6_MIN_MTU;
+               t->dev->mtu = mtu;
+-              break;
++              return;
+       }
+       if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
diff --git a/queue-4.4/ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch b/queue-4.4/ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch
new file mode 100644 (file)
index 0000000..a4000bc
--- /dev/null
@@ -0,0 +1,104 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Sat, 21 Oct 2017 12:26:23 -0700
+Subject: ipv6: flowlabel: do not leave opt->tot_len with garbage
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ Upstream commit 864e2a1f8aac05effac6063ce316b480facb46ff ]
+
+When syzkaller team brought us a C repro for the crash [1] that
+had been reported many times in the past, I finally could find
+the root cause.
+
+If FlowLabel info is merged by fl6_merge_options(), we leave
+part of the opt_space storage provided by udp/raw/l2tp with random value
+in opt_space.tot_len, unless a control message was provided at sendmsg()
+time.
+
+Then ip6_setup_cork() would use this random value to perform a kzalloc()
+call. Undefined behavior and crashes.
+
+Fix is to properly set tot_len in fl6_merge_options()
+
+At the same time, we can also avoid consuming memory and cpu cycles
+to clear it, if every option is copied via a kmemdup(). This is the
+change in ip6_setup_cork().
+
+[1]
+kasan: CONFIG_KASAN_INLINE enabled
+kasan: GPF could be caused by NULL-ptr deref or user memory access
+general protection fault: 0000 [#1] SMP KASAN
+Dumping ftrace buffer:
+   (ftrace buffer empty)
+Modules linked in:
+CPU: 0 PID: 6613 Comm: syz-executor0 Not tainted 4.14.0-rc4+ #127
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+task: ffff8801cb64a100 task.stack: ffff8801cc350000
+RIP: 0010:ip6_setup_cork+0x274/0x15c0 net/ipv6/ip6_output.c:1168
+RSP: 0018:ffff8801cc357550 EFLAGS: 00010203
+RAX: dffffc0000000000 RBX: ffff8801cc357748 RCX: 0000000000000010
+RDX: 0000000000000002 RSI: ffffffff842bd1d9 RDI: 0000000000000014
+RBP: ffff8801cc357620 R08: ffff8801cb17f380 R09: ffff8801cc357b10
+R10: ffff8801cb64a100 R11: 0000000000000000 R12: ffff8801cc357ab0
+R13: ffff8801cc357b10 R14: 0000000000000000 R15: ffff8801c3bbf0c0
+FS:  00007f9c5c459700(0000) GS:ffff8801db200000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000020324000 CR3: 00000001d1cf2000 CR4: 00000000001406f0
+DR0: 0000000020001010 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
+Call Trace:
+ ip6_make_skb+0x282/0x530 net/ipv6/ip6_output.c:1729
+ udpv6_sendmsg+0x2769/0x3380 net/ipv6/udp.c:1340
+ inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:762
+ sock_sendmsg_nosec net/socket.c:633 [inline]
+ sock_sendmsg+0xca/0x110 net/socket.c:643
+ SYSC_sendto+0x358/0x5a0 net/socket.c:1750
+ SyS_sendto+0x40/0x50 net/socket.c:1718
+ entry_SYSCALL_64_fastpath+0x1f/0xbe
+RIP: 0033:0x4520a9
+RSP: 002b:00007f9c5c458c08 EFLAGS: 00000216 ORIG_RAX: 000000000000002c
+RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 00000000004520a9
+RDX: 0000000000000001 RSI: 0000000020fd1000 RDI: 0000000000000016
+RBP: 0000000000000086 R08: 0000000020e0afe4 R09: 000000000000001c
+R10: 0000000000000000 R11: 0000000000000216 R12: 00000000004bb1ee
+R13: 00000000ffffffff R14: 0000000000000016 R15: 0000000000000029
+Code: e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 ea 0f 00 00 48 8d 79 04 48 b8 00 00 00 00 00 fc ff df 45 8b 74 24 04 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85
+RIP: ip6_setup_cork+0x274/0x15c0 net/ipv6/ip6_output.c:1168 RSP: ffff8801cc357550
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_flowlabel.c |    1 +
+ net/ipv6/ip6_output.c    |    4 ++--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/ip6_flowlabel.c
++++ b/net/ipv6/ip6_flowlabel.c
+@@ -315,6 +315,7 @@ struct ipv6_txoptions *fl6_merge_options
+       }
+       opt_space->dst1opt = fopt->dst1opt;
+       opt_space->opt_flen = fopt->opt_flen;
++      opt_space->tot_len = fopt->tot_len;
+       return opt_space;
+ }
+ EXPORT_SYMBOL_GPL(fl6_merge_options);
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1201,11 +1201,11 @@ static int ip6_setup_cork(struct sock *s
+               if (WARN_ON(v6_cork->opt))
+                       return -EINVAL;
+-              v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
++              v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation);
+               if (unlikely(!v6_cork->opt))
+                       return -ENOBUFS;
+-              v6_cork->opt->tot_len = opt->tot_len;
++              v6_cork->opt->tot_len = sizeof(*opt);
+               v6_cork->opt->opt_flen = opt->opt_flen;
+               v6_cork->opt->opt_nflen = opt->opt_nflen;
diff --git a/queue-4.4/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch b/queue-4.4/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch
new file mode 100644 (file)
index 0000000..e4513d4
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Fri, 13 Oct 2017 19:22:35 +0200
+Subject: l2tp: check ps->sock before running pppol2tp_session_ioctl()
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+
+[ Upstream commit 5903f594935a3841137c86b9d5b75143a5b7121c ]
+
+When pppol2tp_session_ioctl() is called by pppol2tp_tunnel_ioctl(),
+the session may be unconnected. That is, it was created by
+pppol2tp_session_create() and hasn't been connected with
+pppol2tp_connect(). In this case, ps->sock is NULL, so we need to check
+for this case in order to avoid dereferencing a NULL pointer.
+
+Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_ppp.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -1015,6 +1015,9 @@ static int pppol2tp_session_ioctl(struct
+                session->name, cmd, arg);
+       sk = ps->sock;
++      if (!sk)
++              return -EBADR;
++
+       sock_hold(sk);
+       switch (cmd) {
diff --git a/queue-4.4/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch b/queue-4.4/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch
new file mode 100644 (file)
index 0000000..564cb9d
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Andrei Vagin <avagin@openvz.org>
+Date: Wed, 25 Oct 2017 10:16:42 -0700
+Subject: net/unix: don't show information about sockets from other namespaces
+
+From: Andrei Vagin <avagin@openvz.org>
+
+
+[ Upstream commit 0f5da659d8f1810f44de14acf2c80cd6499623a0 ]
+
+socket_diag shows information only about sockets from a namespace where
+a diag socket lives.
+
+But if we request information about one unix socket, the kernel don't
+check that its netns is matched with a diag socket namespace, so any
+user can get information about any unix socket in a system. This looks
+like a bug.
+
+v2: add a Fixes tag
+
+Fixes: 51d7cccf0723 ("net: make sock diag per-namespace")
+Signed-off-by: Andrei Vagin <avagin@openvz.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/unix/diag.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -257,6 +257,8 @@ static int unix_diag_get_exact(struct sk
+       err = -ENOENT;
+       if (sk == NULL)
+               goto out_nosk;
++      if (!net_eq(sock_net(sk), net))
++              goto out;
+       err = sock_diag_check_cookie(sk, req->udiag_cookie);
+       if (err)
diff --git a/queue-4.4/packet-avoid-panic-in-packet_getsockopt.patch b/queue-4.4/packet-avoid-panic-in-packet_getsockopt.patch
new file mode 100644 (file)
index 0000000..3a2857f
--- /dev/null
@@ -0,0 +1,86 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 18 Oct 2017 16:14:52 -0700
+Subject: packet: avoid panic in packet_getsockopt()
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ Upstream commit 509c7a1ecc8601f94ffba8a00889fefb239c00c6 ]
+
+syzkaller got crashes in packet_getsockopt() processing
+PACKET_ROLLOVER_STATS command while another thread was managing
+to change po->rollover
+
+Using RCU will fix this bug. We might later add proper RCU annotations
+for sparse sake.
+
+In v2: I replaced kfree(rollover) in fanout_add() to kfree_rcu()
+variant, as spotted by John.
+
+Fixes: a9b6391814d5 ("packet: rollover statistics")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: John Sperbeck <jsperbeck@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/packet/af_packet.c |   24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1724,7 +1724,7 @@ static int fanout_add(struct sock *sk, u
+ out:
+       if (err && rollover) {
+-              kfree(rollover);
++              kfree_rcu(rollover, rcu);
+               po->rollover = NULL;
+       }
+       mutex_unlock(&fanout_mutex);
+@@ -1751,8 +1751,10 @@ static struct packet_fanout *fanout_rele
+               else
+                       f = NULL;
+-              if (po->rollover)
++              if (po->rollover) {
+                       kfree_rcu(po->rollover, rcu);
++                      po->rollover = NULL;
++              }
+       }
+       mutex_unlock(&fanout_mutex);
+@@ -3769,6 +3771,7 @@ static int packet_getsockopt(struct sock
+       void *data = &val;
+       union tpacket_stats_u st;
+       struct tpacket_rollover_stats rstats;
++      struct packet_rollover *rollover;
+       if (level != SOL_PACKET)
+               return -ENOPROTOOPT;
+@@ -3847,13 +3850,18 @@ static int packet_getsockopt(struct sock
+                      0);
+               break;
+       case PACKET_ROLLOVER_STATS:
+-              if (!po->rollover)
++              rcu_read_lock();
++              rollover = rcu_dereference(po->rollover);
++              if (rollover) {
++                      rstats.tp_all = atomic_long_read(&rollover->num);
++                      rstats.tp_huge = atomic_long_read(&rollover->num_huge);
++                      rstats.tp_failed = atomic_long_read(&rollover->num_failed);
++                      data = &rstats;
++                      lv = sizeof(rstats);
++              }
++              rcu_read_unlock();
++              if (!rollover)
+                       return -EINVAL;
+-              rstats.tp_all = atomic_long_read(&po->rollover->num);
+-              rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
+-              rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
+-              data = &rstats;
+-              lv = sizeof(rstats);
+               break;
+       case PACKET_TX_HAS_OFF:
+               val = po->tp_tx_has_off;
diff --git a/queue-4.4/ppp-fix-race-in-ppp-device-destruction.patch b/queue-4.4/ppp-fix-race-in-ppp-device-destruction.patch
new file mode 100644 (file)
index 0000000..25a6ca0
--- /dev/null
@@ -0,0 +1,113 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Fri, 6 Oct 2017 17:05:49 +0200
+Subject: ppp: fix race in ppp device destruction
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+
+[ Upstream commit 6151b8b37b119e8e3a8401b080d532520c95faf4 ]
+
+ppp_release() tries to ensure that netdevices are unregistered before
+decrementing the unit refcount and running ppp_destroy_interface().
+
+This is all fine as long as the the device is unregistered by
+ppp_release(): the unregister_netdevice() call, followed by
+rtnl_unlock(), guarantee that the unregistration process completes
+before rtnl_unlock() returns.
+
+However, the device may be unregistered by other means (like
+ppp_nl_dellink()). If this happens right before ppp_release() calling
+rtnl_lock(), then ppp_release() has to wait for the concurrent
+unregistration code to release the lock.
+But rtnl_unlock() releases the lock before completing the device
+unregistration process. This allows ppp_release() to proceed and
+eventually call ppp_destroy_interface() before the unregistration
+process completes. Calling free_netdev() on this partially unregistered
+device will BUG():
+
+ ------------[ cut here ]------------
+ kernel BUG at net/core/dev.c:8141!
+ invalid opcode: 0000 [#1] SMP
+
+ CPU: 1 PID: 1557 Comm: pppd Not tainted 4.14.0-rc2+ #4
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1.fc26 04/01/2014
+
+ Call Trace:
+  ppp_destroy_interface+0xd8/0xe0 [ppp_generic]
+  ppp_disconnect_channel+0xda/0x110 [ppp_generic]
+  ppp_unregister_channel+0x5e/0x110 [ppp_generic]
+  pppox_unbind_sock+0x23/0x30 [pppox]
+  pppoe_connect+0x130/0x440 [pppoe]
+  SYSC_connect+0x98/0x110
+  ? do_fcntl+0x2c0/0x5d0
+  SyS_connect+0xe/0x10
+  entry_SYSCALL_64_fastpath+0x1a/0xa5
+
+ RIP: free_netdev+0x107/0x110 RSP: ffffc28a40573d88
+ ---[ end trace ed294ff0cc40eeff ]---
+
+We could set the ->needs_free_netdev flag on PPP devices and move the
+ppp_destroy_interface() logic in the ->priv_destructor() callback. But
+that'd be quite intrusive as we'd first need to unlink from the other
+channels and units that depend on the device (the ones that used the
+PPPIOCCONNECT and PPPIOCATTACH ioctls).
+
+Instead, we can just let the netdevice hold a reference on its
+ppp_file. This reference is dropped in ->priv_destructor(), at the very
+end of the unregistration process, so that neither ppp_release() nor
+ppp_disconnect_channel() can call ppp_destroy_interface() in the interim.
+
+Reported-by: Beniamino Galvani <bgalvani@redhat.com>
+Fixes: 8cb775bc0a34 ("ppp: fix device unregistration upon netns deletion")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ppp/ppp_generic.c |   20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -1110,7 +1110,17 @@ ppp_get_stats64(struct net_device *dev,
+ static struct lock_class_key ppp_tx_busylock;
+ static int ppp_dev_init(struct net_device *dev)
+ {
++      struct ppp *ppp;
++
+       dev->qdisc_tx_busylock = &ppp_tx_busylock;
++
++      ppp = netdev_priv(dev);
++      /* Let the netdevice take a reference on the ppp file. This ensures
++       * that ppp_destroy_interface() won't run before the device gets
++       * unregistered.
++       */
++      atomic_inc(&ppp->file.refcnt);
++
+       return 0;
+ }
+@@ -1133,6 +1143,15 @@ static void ppp_dev_uninit(struct net_de
+       wake_up_interruptible(&ppp->file.rwait);
+ }
++static void ppp_dev_priv_destructor(struct net_device *dev)
++{
++      struct ppp *ppp;
++
++      ppp = netdev_priv(dev);
++      if (atomic_dec_and_test(&ppp->file.refcnt))
++              ppp_destroy_interface(ppp);
++}
++
+ static const struct net_device_ops ppp_netdev_ops = {
+       .ndo_init        = ppp_dev_init,
+       .ndo_uninit      = ppp_dev_uninit,
+@@ -1150,6 +1169,7 @@ static void ppp_setup(struct net_device
+       dev->tx_queue_len = 3;
+       dev->type = ARPHRD_PPP;
+       dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++      dev->destructor = ppp_dev_priv_destructor;
+       netif_keep_dst(dev);
+ }
diff --git a/queue-4.4/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch b/queue-4.4/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch
new file mode 100644 (file)
index 0000000..1c56708
--- /dev/null
@@ -0,0 +1,48 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Wed, 18 Oct 2017 21:37:49 +0800
+Subject: sctp: add the missing sock_owned_by_user check in sctp_icmp_redirect
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 1cc276cec9ec574d41cf47dfc0f51406b6f26ab4 ]
+
+Now sctp processes icmp redirect packet in sctp_icmp_redirect where
+it calls sctp_transport_dst_check in which tp->dst can be released.
+
+The problem is before calling sctp_transport_dst_check, it doesn't
+check sock_owned_by_user, which means tp->dst could be freed while
+a process is accessing it with owning the socket.
+
+An use-after-free issue could be triggered by this.
+
+This patch is to fix it by checking sock_owned_by_user before calling
+sctp_transport_dst_check in sctp_icmp_redirect, so that it would not
+release tp->dst if users still hold sock lock.
+
+Besides, the same issue fixed in commit 45caeaa5ac0b ("dccp/tcp: fix
+routing redirect race") on sctp also needs this check.
+
+Fixes: 55be7a9c6074 ("ipv4: Add redirect support to all protocol icmp error handlers")
+Reported-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/input.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -420,7 +420,7 @@ void sctp_icmp_redirect(struct sock *sk,
+ {
+       struct dst_entry *dst;
+-      if (!t)
++      if (sock_owned_by_user(sk) || !t)
+               return;
+       dst = sctp_transport_dst_check(t);
+       if (dst)
diff --git a/queue-4.4/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch b/queue-4.4/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch
new file mode 100644 (file)
index 0000000..1565761
--- /dev/null
@@ -0,0 +1,100 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Sat, 28 Oct 2017 02:13:29 +0800
+Subject: sctp: reset owner sk for data chunks on out queues when migrating a sock
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit d04adf1b355181e737b6b1e23d801b07f0b7c4c0 ]
+
+Now when migrating sock to another one in sctp_sock_migrate(), it only
+resets owner sk for the data in receive queues, not the chunks on out
+queues.
+
+It would cause that data chunks length on the sock is not consistent
+with sk sk_wmem_alloc. When closing the sock or freeing these chunks,
+the old sk would never be freed, and the new sock may crash due to
+the overflow sk_wmem_alloc.
+
+syzbot found this issue with this series:
+
+  r0 = socket$inet_sctp()
+  sendto$inet(r0)
+  listen(r0)
+  accept4(r0)
+  close(r0)
+
+Although listen() should have returned error when one TCP-style socket
+is in connecting (I may fix this one in another patch), it could also
+be reproduced by peeling off an assoc.
+
+This issue is there since very beginning.
+
+This patch is to reset owner sk for the chunks on out queues so that
+sk sk_wmem_alloc has correct value after accept one sock or peeloff
+an assoc to one sock.
+
+Note that when resetting owner sk for chunks on outqueue, it has to
+sctp_clear_owner_w/skb_orphan chunks before changing assoc->base.sk
+first and then sctp_set_owner_w them after changing assoc->base.sk,
+due to that sctp_wfree and it's callees are using assoc->base.sk.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/socket.c |   32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -168,6 +168,36 @@ static inline void sctp_set_owner_w(stru
+       sk_mem_charge(sk, chunk->skb->truesize);
+ }
++static void sctp_clear_owner_w(struct sctp_chunk *chunk)
++{
++      skb_orphan(chunk->skb);
++}
++
++static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
++                                     void (*cb)(struct sctp_chunk *))
++
++{
++      struct sctp_outq *q = &asoc->outqueue;
++      struct sctp_transport *t;
++      struct sctp_chunk *chunk;
++
++      list_for_each_entry(t, &asoc->peer.transport_addr_list, transports)
++              list_for_each_entry(chunk, &t->transmitted, transmitted_list)
++                      cb(chunk);
++
++      list_for_each_entry(chunk, &q->retransmit, list)
++              cb(chunk);
++
++      list_for_each_entry(chunk, &q->sacked, list)
++              cb(chunk);
++
++      list_for_each_entry(chunk, &q->abandoned, list)
++              cb(chunk);
++
++      list_for_each_entry(chunk, &q->out_chunk_list, list)
++              cb(chunk);
++}
++
+ /* Verify that this is a valid address. */
+ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
+                                  int len)
+@@ -7362,7 +7392,9 @@ static void sctp_sock_migrate(struct soc
+        * paths won't try to lock it and then oldsk.
+        */
+       lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
++      sctp_for_each_tx_datachunk(assoc, sctp_clear_owner_w);
+       sctp_assoc_migrate(assoc, newsk);
++      sctp_for_each_tx_datachunk(assoc, sctp_set_owner_w);
+       /* If the association on the newsk is already closed before accept()
+        * is called, set RCV_SHUTDOWN flag.
index e3bd503baee531c28ef65480282ebad0ba428efb..27d49fda24053691101f2f08f03467a460440243 100644 (file)
@@ -4,3 +4,15 @@ mac80211-don-t-compare-tkip-tx-mic-key-in-reinstall-prevention.patch
 usb-usbtest-fix-null-pointer-dereference.patch
 input-ims-psu-check-if-cdc-union-descriptor-is-sane.patch
 alsa-seq-cancel-pending-autoload-work-at-unbinding-device.patch
+tun-tap-sanitize-tunsetsndbuf-input.patch
+tcp-fix-tcp_mtu_probe-vs-highest_sack.patch
+l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch
+tun-call-dev_get_valid_name-before-register_netdevice.patch
+sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch
+packet-avoid-panic-in-packet_getsockopt.patch
+ipv6-flowlabel-do-not-leave-opt-tot_len-with-garbage.patch
+net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch
+ip6_gre-only-increase-err_count-for-some-certain-type-icmpv6-in-ip6gre_err.patch
+tun-allow-positive-return-values-on-dev_get_valid_name-call.patch
+sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch
+ppp-fix-race-in-ppp-device-destruction.patch
diff --git a/queue-4.4/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch b/queue-4.4/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch
new file mode 100644 (file)
index 0000000..88c7357
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 30 Oct 2017 23:08:20 -0700
+Subject: tcp: fix tcp_mtu_probe() vs highest_sack
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ Upstream commit 2b7cda9c35d3b940eb9ce74b30bbd5eb30db493d ]
+
+Based on SNMP values provided by Roman, Yuchung made the observation
+that some crashes in tcp_sacktag_walk() might be caused by MTU probing.
+
+Looking at tcp_mtu_probe(), I found that when a new skb was placed
+in front of the write queue, we were not updating tcp highest sack.
+
+If one skb is freed because all its content was copied to the new skb
+(for MTU probing), then tp->highest_sack could point to a now freed skb.
+
+Bad things would then happen, including infinite loops.
+
+This patch renames tcp_highest_sack_combine() and uses it
+from tcp_mtu_probe() to fix the bug.
+
+Note that I also removed one test against tp->sacked_out,
+since we want to replace tp->highest_sack regardless of whatever
+condition, since keeping a stale pointer to freed skb is a recipe
+for disaster.
+
+Fixes: a47e5a988a57 ("[TCP]: Convert highest_sack to sk_buff to allow direct access")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Reported-by: Roman Gushchin <guro@fb.com>
+Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Acked-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/tcp.h     |    6 +++---
+ net/ipv4/tcp_output.c |    3 ++-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1612,12 +1612,12 @@ static inline void tcp_highest_sack_rese
+       tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+ }
+-/* Called when old skb is about to be deleted (to be combined with new skb) */
+-static inline void tcp_highest_sack_combine(struct sock *sk,
++/* Called when old skb is about to be deleted and replaced by new skb */
++static inline void tcp_highest_sack_replace(struct sock *sk,
+                                           struct sk_buff *old,
+                                           struct sk_buff *new)
+ {
+-      if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
++      if (old == tcp_highest_sack(sk))
+               tcp_sk(sk)->highest_sack = new;
+ }
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1951,6 +1951,7 @@ static int tcp_mtu_probe(struct sock *sk
+       nskb->ip_summed = skb->ip_summed;
+       tcp_insert_write_queue_before(nskb, skb, sk);
++      tcp_highest_sack_replace(sk, skb, nskb);
+       len = 0;
+       tcp_for_write_queue_from_safe(skb, next, sk) {
+@@ -2464,7 +2465,7 @@ static void tcp_collapse_retrans(struct
+       BUG_ON(tcp_skb_pcount(skb) != 1 || tcp_skb_pcount(next_skb) != 1);
+-      tcp_highest_sack_combine(sk, next_skb, skb);
++      tcp_highest_sack_replace(sk, next_skb, skb);
+       tcp_unlink_write_queue(next_skb, sk);
diff --git a/queue-4.4/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch b/queue-4.4/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch
new file mode 100644 (file)
index 0000000..9d65440
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Julien Gomes <julien@arista.com>
+Date: Wed, 25 Oct 2017 11:50:50 -0700
+Subject: tun: allow positive return values on dev_get_valid_name() call
+
+From: Julien Gomes <julien@arista.com>
+
+
+[ Upstream commit 5c25f65fd1e42685f7ccd80e0621829c105785d9 ]
+
+If the name argument of dev_get_valid_name() contains "%d", it will try
+to assign it a unit number in __dev__alloc_name() and return either the
+unit number (>= 0) or an error code (< 0).
+Considering positive values as error values prevent tun device creations
+relying this mechanism, therefor we should only consider negative values
+as errors here.
+
+Signed-off-by: Julien Gomes <julien@arista.com>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1685,7 +1685,7 @@ static int tun_set_iff(struct net *net,
+               if (!dev)
+                       return -ENOMEM;
+               err = dev_get_valid_name(net, dev, name);
+-              if (err)
++              if (err < 0)
+                       goto err_free_dev;
+               dev_net_set(dev, net);
diff --git a/queue-4.4/tun-call-dev_get_valid_name-before-register_netdevice.patch b/queue-4.4/tun-call-dev_get_valid_name-before-register_netdevice.patch
new file mode 100644 (file)
index 0000000..f2095e1
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Fri, 13 Oct 2017 11:58:53 -0700
+Subject: tun: call dev_get_valid_name() before register_netdevice()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+
+[ Upstream commit 0ad646c81b2182f7fa67ec0c8c825e0ee165696d ]
+
+register_netdevice() could fail early when we have an invalid
+dev name, in which case ->ndo_uninit() is not called. For tun
+device, this is a problem because a timer etc. are already
+initialized and it expects ->ndo_uninit() to clean them up.
+
+We could move these initializations into a ->ndo_init() so
+that register_netdevice() knows better, however this is still
+complicated due to the logic in tun_detach().
+
+Therefore, I choose to just call dev_get_valid_name() before
+register_netdevice(), which is quicker and much easier to audit.
+And for this specific case, it is already enough.
+
+Fixes: 96442e42429e ("tuntap: choose the txq based on rxq")
+Reported-by: Dmitry Alexeev <avekceeb@gmail.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c         |    3 +++
+ include/linux/netdevice.h |    3 +++
+ net/core/dev.c            |    6 +++---
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1684,6 +1684,9 @@ static int tun_set_iff(struct net *net,
+               if (!dev)
+                       return -ENOMEM;
++              err = dev_get_valid_name(net, dev, name);
++              if (err)
++                      goto err_free_dev;
+               dev_net_set(dev, net);
+               dev->rtnl_link_ops = &tun_link_ops;
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -3469,6 +3469,9 @@ struct net_device *alloc_netdev_mqs(int
+                                   unsigned char name_assign_type,
+                                   void (*setup)(struct net_device *),
+                                   unsigned int txqs, unsigned int rxqs);
++int dev_get_valid_name(struct net *net, struct net_device *dev,
++                     const char *name);
++
+ #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \
+       alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1)
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1111,9 +1111,8 @@ static int dev_alloc_name_ns(struct net
+       return ret;
+ }
+-static int dev_get_valid_name(struct net *net,
+-                            struct net_device *dev,
+-                            const char *name)
++int dev_get_valid_name(struct net *net, struct net_device *dev,
++                     const char *name)
+ {
+       BUG_ON(!net);
+@@ -1129,6 +1128,7 @@ static int dev_get_valid_name(struct net
+       return 0;
+ }
++EXPORT_SYMBOL(dev_get_valid_name);
+ /**
+  *    dev_change_name - change name of a device
diff --git a/queue-4.4/tun-tap-sanitize-tunsetsndbuf-input.patch b/queue-4.4/tun-tap-sanitize-tunsetsndbuf-input.patch
new file mode 100644 (file)
index 0000000..6394c12
--- /dev/null
@@ -0,0 +1,88 @@
+From foo@baz Thu Nov 16 15:08:14 CET 2017
+From: Craig Gallek <kraig@google.com>
+Date: Mon, 30 Oct 2017 18:50:11 -0400
+Subject: tun/tap: sanitize TUNSETSNDBUF input
+
+From: Craig Gallek <kraig@google.com>
+
+
+[ Upstream commit 93161922c658c714715686cd0cf69b090cb9bf1d ]
+
+Syzkaller found several variants of the lockup below by setting negative
+values with the TUNSETSNDBUF ioctl.  This patch adds a sanity check
+to both the tun and tap versions of this ioctl.
+
+  watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [repro:2389]
+  Modules linked in:
+  irq event stamp: 329692056
+  hardirqs last  enabled at (329692055): [<ffffffff824b8381>] _raw_spin_unlock_irqrestore+0x31/0x75
+  hardirqs last disabled at (329692056): [<ffffffff824b9e58>] apic_timer_interrupt+0x98/0xb0
+  softirqs last  enabled at (35659740): [<ffffffff824bc958>] __do_softirq+0x328/0x48c
+  softirqs last disabled at (35659731): [<ffffffff811c796c>] irq_exit+0xbc/0xd0
+  CPU: 0 PID: 2389 Comm: repro Not tainted 4.14.0-rc7 #23
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+  task: ffff880009452140 task.stack: ffff880006a20000
+  RIP: 0010:_raw_spin_lock_irqsave+0x11/0x80
+  RSP: 0018:ffff880006a27c50 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff10
+  RAX: ffff880009ac68d0 RBX: ffff880006a27ce0 RCX: 0000000000000000
+  RDX: 0000000000000001 RSI: ffff880006a27ce0 RDI: ffff880009ac6900
+  RBP: ffff880006a27c60 R08: 0000000000000000 R09: 0000000000000000
+  R10: 0000000000000001 R11: 000000000063ff00 R12: ffff880009ac6900
+  R13: ffff880006a27cf8 R14: 0000000000000001 R15: ffff880006a27cf8
+  FS:  00007f4be4838700(0000) GS:ffff88000cc00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 0000000020101000 CR3: 0000000009616000 CR4: 00000000000006f0
+  Call Trace:
+   prepare_to_wait+0x26/0xc0
+   sock_alloc_send_pskb+0x14e/0x270
+   ? remove_wait_queue+0x60/0x60
+   tun_get_user+0x2cc/0x19d0
+   ? __tun_get+0x60/0x1b0
+   tun_chr_write_iter+0x57/0x86
+   __vfs_write+0x156/0x1e0
+   vfs_write+0xf7/0x230
+   SyS_write+0x57/0xd0
+   entry_SYSCALL_64_fastpath+0x1f/0xbe
+  RIP: 0033:0x7f4be4356df9
+  RSP: 002b:00007ffc18101c08 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
+  RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f4be4356df9
+  RDX: 0000000000000046 RSI: 0000000020101000 RDI: 0000000000000005
+  RBP: 00007ffc18101c40 R08: 0000000000000001 R09: 0000000000000001
+  R10: 0000000000000001 R11: 0000000000000293 R12: 0000559c75f64780
+  R13: 00007ffc18101d30 R14: 0000000000000000 R15: 0000000000000000
+
+Fixes: 33dccbb050bb ("tun: Limit amount of queued packets per device")
+Fixes: 20d29d7a916a ("net: macvtap driver")
+Signed-off-by: Craig Gallek <kraig@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c |    2 ++
+ drivers/net/tun.c     |    4 ++++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -1117,6 +1117,8 @@ static long macvtap_ioctl(struct file *f
+       case TUNSETSNDBUF:
+               if (get_user(s, sp))
+                       return -EFAULT;
++              if (s <= 0)
++                      return -EINVAL;
+               q->sk.sk_sndbuf = s;
+               return 0;
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2065,6 +2065,10 @@ static long __tun_chr_ioctl(struct file
+                       ret = -EFAULT;
+                       break;
+               }
++              if (sndbuf <= 0) {
++                      ret = -EINVAL;
++                      break;
++              }
+               tun->sndbuf = sndbuf;
+               tun_set_sndbuf(tun);