From: Greg Kroah-Hartman Date: Thu, 16 Nov 2017 14:49:16 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v3.18.82~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9afce6c5c3c820cf2d361b7442db8bea1787191b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..bd4096fc878 --- /dev/null +++ b/queue-3.18/l2tp-check-ps-sock-before-running-pppol2tp_session_ioctl.patch @@ -0,0 +1,36 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Guillaume Nault +Date: Fri, 13 Oct 2017 19:22:35 +0200 +Subject: l2tp: check ps->sock before running pppol2tp_session_ioctl() + +From: Guillaume Nault + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f0fd0c97c32 --- /dev/null +++ b/queue-3.18/net-unix-don-t-show-information-about-sockets-from-other-namespaces.patch @@ -0,0 +1,39 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Andrei Vagin +Date: Wed, 25 Oct 2017 10:16:42 -0700 +Subject: net/unix: don't show information about sockets from other namespaces + +From: Andrei Vagin + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..d09809275d7 --- /dev/null +++ b/queue-3.18/sctp-add-the-missing-sock_owned_by_user-check-in-sctp_icmp_redirect.patch @@ -0,0 +1,48 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Xin Long +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 + + +[ 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 +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..893e70a0699 --- /dev/null +++ b/queue-3.18/sctp-reset-owner-sk-for-data-chunks-on-out-queues-when-migrating-a-sock.patch @@ -0,0 +1,100 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Xin Long +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 + + +[ 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 +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 | 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. diff --git a/queue-3.18/series b/queue-3.18/series index 404ddd7ff4d..7a4c8de8f87 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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 index 00000000000..50683909bdf --- /dev/null +++ b/queue-3.18/tcp-fix-tcp_mtu_probe-vs-highest_sack.patch @@ -0,0 +1,81 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Eric Dumazet +Date: Mon, 30 Oct 2017 23:08:20 -0700 +Subject: tcp: fix tcp_mtu_probe() vs highest_sack + +From: Eric Dumazet + + +[ 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 +Reported-by: Alexei Starovoitov +Reported-by: Roman Gushchin +Reported-by: Oleksandr Natalenko +Acked-by: Alexei Starovoitov +Acked-by: Neal Cardwell +Acked-by: Yuchung Cheng +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..af43a74a3db --- /dev/null +++ b/queue-3.18/tun-allow-positive-return-values-on-dev_get_valid_name-call.patch @@ -0,0 +1,36 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Julien Gomes +Date: Wed, 25 Oct 2017 11:50:50 -0700 +Subject: tun: allow positive return values on dev_get_valid_name() call + +From: Julien Gomes + + +[ 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 +Acked-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..64e5b911694 --- /dev/null +++ b/queue-3.18/tun-call-dev_get_valid_name-before-register_netdevice.patch @@ -0,0 +1,82 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Cong Wang +Date: Fri, 13 Oct 2017 11:58:53 -0700 +Subject: tun: call dev_get_valid_name() before register_netdevice() + +From: Cong Wang + + +[ 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 +Cc: Jason Wang +Cc: "Michael S. Tsirkin" +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f4754ac4004 --- /dev/null +++ b/queue-3.18/tun-tap-sanitize-tunsetsndbuf-input.patch @@ -0,0 +1,88 @@ +From foo@baz Thu Nov 16 15:48:06 CET 2017 +From: Craig Gallek +Date: Mon, 30 Oct 2017 18:50:11 -0400 +Subject: tun/tap: sanitize TUNSETSNDBUF input + +From: Craig Gallek + + +[ 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): [] _raw_spin_unlock_irqrestore+0x31/0x75 + hardirqs last disabled at (329692056): [] apic_timer_interrupt+0x98/0xb0 + softirqs last enabled at (35659740): [] __do_softirq+0x328/0x48c + softirqs last disabled at (35659731): [] 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 +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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);