]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Nov 2017 14:49:16 +0000 (15:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Nov 2017 14:49:16 +0000 (15:49 +0100)
added patches:
l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch
net-unix-don-t-show-information-about-sockets-from-other-namespaces.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

queue-3.18/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch [new file with mode: 0644]
queue-3.18/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch [new file with mode: 0644]
queue-3.18/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch [new file with mode: 0644]
queue-3.18/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch [new file with mode: 0644]
queue-3.18/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch [new file with mode: 0644]
queue-3.18/tun-call-dev_get_valid_name-before-register_netdevice.patch [new file with mode: 0644]
queue-3.18/tun-tap-sanitize-tunsetsndbuf-input.patch [new file with mode: 0644]

diff --git a/queue-3.18/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch b/queue-3.18/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch
new file mode 100644 (file)
index 0000000..bd4096f
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -1017,6 +1017,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-3.18/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch b/queue-3.18/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch
new file mode 100644 (file)
index 0000000..f0fd0c9
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -256,6 +256,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-3.18/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch b/queue-3.18/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch
new file mode 100644 (file)
index 0000000..d098092
--- /dev/null
@@ -0,0 +1,48 @@
+From foo@baz Thu Nov 16 15:48:06 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-3.18/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch b/queue-3.18/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch
new file mode 100644 (file)
index 0000000..893e70a
--- /dev/null
@@ -0,0 +1,100 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -173,6 +173,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)
+@@ -7367,7 +7397,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 404ddd7ff4d11431f21ab60c8322d0aaf1ba4905..7a4c8de8f871878065f97db28ac2375235a9c206 100644 (file)
@@ -5,3 +5,11 @@ 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
 revert-arm-dts-imx53-qsb-common-fix-fec-pinmux-config.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
+net-unix-don-t-show-information-about-sockets-from-other-namespaces.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
diff --git a/queue-3.18/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch b/queue-3.18/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch
new file mode 100644 (file)
index 0000000..5068390
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -1532,12 +1532,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
+@@ -1870,6 +1870,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) {
+@@ -2374,7 +2375,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-3.18/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch b/queue-3.18/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch
new file mode 100644 (file)
index 0000000..af43a74
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -1657,7 +1657,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-3.18/tun-call-dev_get_valid_name-before-register_netdevice.patch b/queue-3.18/tun-call-dev_get_valid_name-before-register_netdevice.patch
new file mode 100644 (file)
index 0000000..64e5b91
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -1656,6 +1656,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
+@@ -3245,6 +3245,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
+@@ -1059,9 +1059,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);
+@@ -1077,6 +1076,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-3.18/tun-tap-sanitize-tunsetsndbuf-input.patch b/queue-3.18/tun-tap-sanitize-tunsetsndbuf-input.patch
new file mode 100644 (file)
index 0000000..f4754ac
--- /dev/null
@@ -0,0 +1,88 @@
+From foo@baz Thu Nov 16 15:48:06 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
+@@ -1047,6 +1047,8 @@ static long macvtap_ioctl(struct file *f
+       case TUNSETSNDBUF:
+               if (get_user(u, up))
+                       return -EFAULT;
++              if (s <= 0)
++                      return -EINVAL;
+               q->sk.sk_sndbuf = u;
+               return 0;
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2054,6 +2054,10 @@ static long __tun_chr_ioctl(struct file
+                       ret = -EFAULT;
+                       break;
+               }
++              if (sndbuf <= 0) {
++                      ret = -EINVAL;
++                      break;
++              }
+               tun->sndbuf = sndbuf;
+               tun_set_sndbuf(tun);