]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Sep 2019 11:01:24 +0000 (13:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Sep 2019 11:01:24 +0000 (13:01 +0200)
added patches:
bridge-mdb-remove-wrong-use-of-nlm_f_multi.patch
cdc_ether-fix-rndis-support-for-mediatek-based-smartphones.patch
ipv6-addrconf_f6i_alloc-fix-non-null-pointer-check-to-is_err.patch
ipv6-fix-the-link-time-qualifier-of-ping_v6_proc_exit_net.patch
isdn-capi-check-message-length-in-capi_write.patch
ixgbe-fix-secpath-usage-for-ipsec-tx-offload.patch
ixgbevf-fix-secpath-usage-for-ipsec-tx-offload.patch
net-fix-null-de-reference-of-device-refcount.patch
net-fixed_phy-add-forward-declaration-for-struct-gpio_desc.patch
net-gso-fix-skb_segment-splat-when-splitting-gso_size-mangled-skb-having-linear-headed-frag_list.patch
net-ipv6-fix-excessive-rtf_addrconf-flag-on-1-128-local-route-and-others.patch
net-phylink-fix-flow-control-resolution.patch
net-sched-fix-reordering-issues.patch
net-sock_map-fix-missing-ulp-check-in-sock-hash-case.patch
sch_hhf-ensure-quantum-and-hhf_non_hh_weight-are-non-zero.patch
sctp-fix-the-link-time-qualifier-of-sctp_ctrlsock_exit.patch
sctp-fix-the-missing-put_user-when-dumping-transport-thresholds.patch
sctp-use-transport-pf_retrans-in-sctp_do_8_2_transport_strike.patch
tcp-fix-tcp_ecn_withdraw_cwr-to-clear-tcp_ecn_queue_cwr.patch
tipc-add-null-pointer-check-before-calling-kfree_rcu.patch
tun-fix-use-after-free-when-register-netdev-failed.patch

21 files changed:
queue-5.2/bridge-mdb-remove-wrong-use-of-nlm_f_multi.patch [new file with mode: 0644]
queue-5.2/cdc_ether-fix-rndis-support-for-mediatek-based-smartphones.patch [new file with mode: 0644]
queue-5.2/ipv6-addrconf_f6i_alloc-fix-non-null-pointer-check-to-is_err.patch [new file with mode: 0644]
queue-5.2/ipv6-fix-the-link-time-qualifier-of-ping_v6_proc_exit_net.patch [new file with mode: 0644]
queue-5.2/isdn-capi-check-message-length-in-capi_write.patch [new file with mode: 0644]
queue-5.2/ixgbe-fix-secpath-usage-for-ipsec-tx-offload.patch [new file with mode: 0644]
queue-5.2/ixgbevf-fix-secpath-usage-for-ipsec-tx-offload.patch [new file with mode: 0644]
queue-5.2/net-fix-null-de-reference-of-device-refcount.patch [new file with mode: 0644]
queue-5.2/net-fixed_phy-add-forward-declaration-for-struct-gpio_desc.patch [new file with mode: 0644]
queue-5.2/net-gso-fix-skb_segment-splat-when-splitting-gso_size-mangled-skb-having-linear-headed-frag_list.patch [new file with mode: 0644]
queue-5.2/net-ipv6-fix-excessive-rtf_addrconf-flag-on-1-128-local-route-and-others.patch [new file with mode: 0644]
queue-5.2/net-phylink-fix-flow-control-resolution.patch [new file with mode: 0644]
queue-5.2/net-sched-fix-reordering-issues.patch [new file with mode: 0644]
queue-5.2/net-sock_map-fix-missing-ulp-check-in-sock-hash-case.patch [new file with mode: 0644]
queue-5.2/sch_hhf-ensure-quantum-and-hhf_non_hh_weight-are-non-zero.patch [new file with mode: 0644]
queue-5.2/sctp-fix-the-link-time-qualifier-of-sctp_ctrlsock_exit.patch [new file with mode: 0644]
queue-5.2/sctp-fix-the-missing-put_user-when-dumping-transport-thresholds.patch [new file with mode: 0644]
queue-5.2/sctp-use-transport-pf_retrans-in-sctp_do_8_2_transport_strike.patch [new file with mode: 0644]
queue-5.2/tcp-fix-tcp_ecn_withdraw_cwr-to-clear-tcp_ecn_queue_cwr.patch [new file with mode: 0644]
queue-5.2/tipc-add-null-pointer-check-before-calling-kfree_rcu.patch [new file with mode: 0644]
queue-5.2/tun-fix-use-after-free-when-register-netdev-failed.patch [new file with mode: 0644]

diff --git a/queue-5.2/bridge-mdb-remove-wrong-use-of-nlm_f_multi.patch b/queue-5.2/bridge-mdb-remove-wrong-use-of-nlm_f_multi.patch
new file mode 100644 (file)
index 0000000..cc13f16
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Fri, 6 Sep 2019 11:47:02 +0200
+Subject: bridge/mdb: remove wrong use of NLM_F_MULTI
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+[ Upstream commit 94a72b3f024fc7e9ab640897a1e38583a470659d ]
+
+NLM_F_MULTI must be used only when a NLMSG_DONE message is sent at the end.
+In fact, NLMSG_DONE is sent only at the end of a dump.
+
+Libraries like libnl will wait forever for NLMSG_DONE.
+
+Fixes: 949f1e39a617 ("bridge: mdb: notify on router port add and del")
+CC: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_mdb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bridge/br_mdb.c
++++ b/net/bridge/br_mdb.c
+@@ -437,7 +437,7 @@ static int nlmsg_populate_rtr_fill(struc
+       struct nlmsghdr *nlh;
+       struct nlattr *nest;
+-      nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI);
++      nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), 0);
+       if (!nlh)
+               return -EMSGSIZE;
diff --git a/queue-5.2/cdc_ether-fix-rndis-support-for-mediatek-based-smartphones.patch b/queue-5.2/cdc_ether-fix-rndis-support-for-mediatek-based-smartphones.patch
new file mode 100644 (file)
index 0000000..d744362
--- /dev/null
@@ -0,0 +1,102 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: "Bjørn Mork" <bjorn@mork.no>
+Date: Thu, 12 Sep 2019 10:42:00 +0200
+Subject: cdc_ether: fix rndis support for Mediatek based smartphones
+
+From: "Bjørn Mork" <bjorn@mork.no>
+
+[ Upstream commit 4d7ffcf3bf1be98d876c570cab8fc31d9fa92725 ]
+
+A Mediatek based smartphone owner reports problems with USB
+tethering in Linux.  The verbose USB listing shows a rndis_host
+interface pair (e0/01/03 + 10/00/00), but the driver fails to
+bind with
+
+[  355.960428] usb 1-4: bad CDC descriptors
+
+The problem is a failsafe test intended to filter out ACM serial
+functions using the same 02/02/ff class/subclass/protocol as RNDIS.
+The serial functions are recognized by their non-zero bmCapabilities.
+
+No RNDIS function with non-zero bmCapabilities were known at the time
+this failsafe was added. But it turns out that some Wireless class
+RNDIS functions are using the bmCapabilities field. These functions
+are uniquely identified as RNDIS by their class/subclass/protocol, so
+the failing test can safely be disabled.  The same applies to the two
+types of Misc class RNDIS functions.
+
+Applying the failsafe to Communication class functions only retains
+the original functionality, and fixes the problem for the Mediatek based
+smartphone.
+
+Tow examples of CDC functional descriptors with non-zero bmCapabilities
+from Wireless class RNDIS functions are:
+
+0e8d:000a  Mediatek Crosscall Spider X5 3G Phone
+
+      CDC Header:
+        bcdCDC               1.10
+      CDC ACM:
+        bmCapabilities       0x0f
+          connection notifications
+          sends break
+          line coding and serial state
+          get/set/clear comm features
+      CDC Union:
+        bMasterInterface        0
+        bSlaveInterface         1
+      CDC Call Management:
+        bmCapabilities       0x03
+          call management
+          use DataInterface
+        bDataInterface          1
+
+and
+
+19d2:1023  ZTE K4201-z
+
+      CDC Header:
+        bcdCDC               1.10
+      CDC ACM:
+        bmCapabilities       0x02
+          line coding and serial state
+      CDC Call Management:
+        bmCapabilities       0x03
+          call management
+          use DataInterface
+        bDataInterface          1
+      CDC Union:
+        bMasterInterface        0
+        bSlaveInterface         1
+
+The Mediatek example is believed to apply to most smartphones with
+Mediatek firmware.  The ZTE example is most likely also part of a larger
+family of devices/firmwares.
+
+Suggested-by: Lars Melin <larsm17@gmail.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ether.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -206,7 +206,15 @@ int usbnet_generic_cdc_bind(struct usbne
+               goto bad_desc;
+       }
+ skip:
+-      if (rndis && header.usb_cdc_acm_descriptor &&
++      /* Communcation class functions with bmCapabilities are not
++       * RNDIS.  But some Wireless class RNDIS functions use
++       * bmCapabilities for their own purpose. The failsafe is
++       * therefore applied only to Communication class RNDIS
++       * functions.  The rndis test is redundant, but a cheap
++       * optimization.
++       */
++      if (rndis && is_rndis(&intf->cur_altsetting->desc) &&
++          header.usb_cdc_acm_descriptor &&
+           header.usb_cdc_acm_descriptor->bmCapabilities) {
+               dev_dbg(&intf->dev,
+                       "ACM capabilities %02x, not really RNDIS?\n",
diff --git a/queue-5.2/ipv6-addrconf_f6i_alloc-fix-non-null-pointer-check-to-is_err.patch b/queue-5.2/ipv6-addrconf_f6i_alloc-fix-non-null-pointer-check-to-is_err.patch
new file mode 100644 (file)
index 0000000..bcf5fdd
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: "Maciej Żenczykowski" <maze@google.com>
+Date: Thu, 5 Sep 2019 20:56:37 -0700
+Subject: ipv6: addrconf_f6i_alloc - fix non-null pointer check to !IS_ERR()
+
+From: "Maciej Żenczykowski" <maze@google.com>
+
+[ Upstream commit 8652f17c658d03f5c87b8dee6e8e52480c6cd37d ]
+
+Fixes a stupid bug I recently introduced...
+ip6_route_info_create() returns an ERR_PTR(err) and not a NULL on error.
+
+Fixes: d55a2e374a94 ("net-ipv6: fix excessive RTF_ADDRCONF flag on ::1/128 local route (and others)'")
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Lorenzo Colitti <lorenzo@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -3859,7 +3859,7 @@ struct fib6_info *addrconf_f6i_alloc(str
+       }
+       f6i = ip6_route_info_create(&cfg, gfp_flags, NULL);
+-      if (f6i)
++      if (!IS_ERR(f6i))
+               f6i->dst_nocount = true;
+       return f6i;
+ }
diff --git a/queue-5.2/ipv6-fix-the-link-time-qualifier-of-ping_v6_proc_exit_net.patch b/queue-5.2/ipv6-fix-the-link-time-qualifier-of-ping_v6_proc_exit_net.patch
new file mode 100644 (file)
index 0000000..13dd52f
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Tue, 10 Sep 2019 13:29:59 +0200
+Subject: ipv6: Fix the link time qualifier of 'ping_v6_proc_exit_net()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d23dbc479a8e813db4161a695d67da0e36557846 ]
+
+The '.exit' functions from 'pernet_operations' structure should be marked
+as __net_exit, not __net_init.
+
+Fixes: d862e5461423 ("net: ipv6: Implement /proc/net/icmp6.")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ping.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/ping.c
++++ b/net/ipv6/ping.c
+@@ -223,7 +223,7 @@ static int __net_init ping_v6_proc_init_
+       return 0;
+ }
+-static void __net_init ping_v6_proc_exit_net(struct net *net)
++static void __net_exit ping_v6_proc_exit_net(struct net *net)
+ {
+       remove_proc_entry("icmp6", net->proc_net);
+ }
diff --git a/queue-5.2/isdn-capi-check-message-length-in-capi_write.patch b/queue-5.2/isdn-capi-check-message-length-in-capi_write.patch
new file mode 100644 (file)
index 0000000..4c2608e
--- /dev/null
@@ -0,0 +1,86 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 5 Sep 2019 19:36:37 -0700
+Subject: isdn/capi: check message length in capi_write()
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit fe163e534e5eecdfd7b5920b0dfd24c458ee85d6 ]
+
+syzbot reported:
+
+    BUG: KMSAN: uninit-value in capi_write+0x791/0xa90 drivers/isdn/capi/capi.c:700
+    CPU: 0 PID: 10025 Comm: syz-executor379 Not tainted 4.20.0-rc7+ #2
+    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+    Call Trace:
+      __dump_stack lib/dump_stack.c:77 [inline]
+      dump_stack+0x173/0x1d0 lib/dump_stack.c:113
+      kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
+      __msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:313
+      capi_write+0x791/0xa90 drivers/isdn/capi/capi.c:700
+      do_loop_readv_writev fs/read_write.c:703 [inline]
+      do_iter_write+0x83e/0xd80 fs/read_write.c:961
+      vfs_writev fs/read_write.c:1004 [inline]
+      do_writev+0x397/0x840 fs/read_write.c:1039
+      __do_sys_writev fs/read_write.c:1112 [inline]
+      __se_sys_writev+0x9b/0xb0 fs/read_write.c:1109
+      __x64_sys_writev+0x4a/0x70 fs/read_write.c:1109
+      do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
+      entry_SYSCALL_64_after_hwframe+0x63/0xe7
+    [...]
+
+The problem is that capi_write() is reading past the end of the message.
+Fix it by checking the message's length in the needed places.
+
+Reported-and-tested-by: syzbot+0849c524d9c634f5ae66@syzkaller.appspotmail.com
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/isdn/capi/capi.c          |   10 +++++++++-
+ include/uapi/linux/isdn/capicmd.h |    1 +
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/isdn/capi/capi.c
++++ b/drivers/isdn/capi/capi.c
+@@ -688,6 +688,9 @@ capi_write(struct file *file, const char
+       if (!cdev->ap.applid)
+               return -ENODEV;
++      if (count < CAPIMSG_BASELEN)
++              return -EINVAL;
++
+       skb = alloc_skb(count, GFP_USER);
+       if (!skb)
+               return -ENOMEM;
+@@ -698,7 +701,8 @@ capi_write(struct file *file, const char
+       }
+       mlen = CAPIMSG_LEN(skb->data);
+       if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+-              if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
++              if (count < CAPI_DATA_B3_REQ_LEN ||
++                  (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
+                       kfree_skb(skb);
+                       return -EINVAL;
+               }
+@@ -711,6 +715,10 @@ capi_write(struct file *file, const char
+       CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
+       if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
++              if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
++                      kfree_skb(skb);
++                      return -EINVAL;
++              }
+               mutex_lock(&cdev->lock);
+               capincci_free(cdev, CAPIMSG_NCCI(skb->data));
+               mutex_unlock(&cdev->lock);
+--- a/include/uapi/linux/isdn/capicmd.h
++++ b/include/uapi/linux/isdn/capicmd.h
+@@ -16,6 +16,7 @@
+ #define CAPI_MSG_BASELEN              8
+ #define CAPI_DATA_B3_REQ_LEN          (CAPI_MSG_BASELEN+4+4+2+2+2)
+ #define CAPI_DATA_B3_RESP_LEN         (CAPI_MSG_BASELEN+4+2)
++#define CAPI_DISCONNECT_B3_RESP_LEN   (CAPI_MSG_BASELEN+4)
+ /*----- CAPI commands -----*/
+ #define CAPI_ALERT                0x01
diff --git a/queue-5.2/ixgbe-fix-secpath-usage-for-ipsec-tx-offload.patch b/queue-5.2/ixgbe-fix-secpath-usage-for-ipsec-tx-offload.patch
new file mode 100644 (file)
index 0000000..2a119e5
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Steffen Klassert <steffen.klassert@secunet.com>
+Date: Thu, 12 Sep 2019 13:01:44 +0200
+Subject: ixgbe: Fix secpath usage for IPsec TX offload.
+
+From: Steffen Klassert <steffen.klassert@secunet.com>
+
+[ Upstream commit f39b683d35dfa93a58f1b400a8ec0ff81296b37c ]
+
+The ixgbe driver currently does IPsec TX offloading
+based on an existing secpath. However, the secpath
+can also come from the RX side, in this case it is
+misinterpreted for TX offload and the packets are
+dropped with a "bad sa_idx" error. Fix this by using
+the xfrm_offload() function to test for TX offload.
+
+Fixes: 592594704761 ("ixgbe: process the Tx ipsec offload")
+Reported-by: Michael Marley <michael@michaelmarley.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -36,6 +36,7 @@
+ #include <net/vxlan.h>
+ #include <net/mpls.h>
+ #include <net/xdp_sock.h>
++#include <net/xfrm.h>
+ #include "ixgbe.h"
+ #include "ixgbe_common.h"
+@@ -8691,7 +8692,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct
+ #endif /* IXGBE_FCOE */
+ #ifdef CONFIG_IXGBE_IPSEC
+-      if (secpath_exists(skb) &&
++      if (xfrm_offload(skb) &&
+           !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
+               goto out_drop;
+ #endif
diff --git a/queue-5.2/ixgbevf-fix-secpath-usage-for-ipsec-tx-offload.patch b/queue-5.2/ixgbevf-fix-secpath-usage-for-ipsec-tx-offload.patch
new file mode 100644 (file)
index 0000000..5899bea
--- /dev/null
@@ -0,0 +1,48 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Date: Thu, 12 Sep 2019 12:07:34 -0700
+Subject: ixgbevf: Fix secpath usage for IPsec Tx offload
+
+From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+
+[ Upstream commit 8f6617badcc96a582678ea36ea96490c5ff26eb4 ]
+
+Port the same fix for ixgbe to ixgbevf.
+
+The ixgbevf driver currently does IPsec Tx offloading
+based on an existing secpath. However, the secpath
+can also come from the Rx side, in this case it is
+misinterpreted for Tx offload and the packets are
+dropped with a "bad sa_idx" error. Fix this by using
+the xfrm_offload() function to test for Tx offload.
+
+CC: Shannon Nelson <snelson@pensando.io>
+Fixes: 7f68d4306701 ("ixgbevf: enable VF IPsec offload operations")
+Reported-by: Jonathan Tooker <jonathan@reliablehosting.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Acked-by: Shannon Nelson <snelson@pensando.io>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+@@ -30,6 +30,7 @@
+ #include <linux/bpf.h>
+ #include <linux/bpf_trace.h>
+ #include <linux/atomic.h>
++#include <net/xfrm.h>
+ #include "ixgbevf.h"
+@@ -4158,7 +4159,7 @@ static int ixgbevf_xmit_frame_ring(struc
+       first->protocol = vlan_get_protocol(skb);
+ #ifdef CONFIG_IXGBEVF_IPSEC
+-      if (secpath_exists(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
++      if (xfrm_offload(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
+               goto out_drop;
+ #endif
+       tso = ixgbevf_tso(tx_ring, first, &hdr_len, &ipsec_tx);
diff --git a/queue-5.2/net-fix-null-de-reference-of-device-refcount.patch b/queue-5.2/net-fix-null-de-reference-of-device-refcount.patch
new file mode 100644 (file)
index 0000000..b60ab57
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+Date: Tue, 10 Sep 2019 14:02:57 -0600
+Subject: net: Fix null de-reference of device refcount
+
+From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+
+[ Upstream commit 10cc514f451a0f239aa34f91bc9dc954a9397840 ]
+
+In event of failure during register_netdevice, free_netdev is
+invoked immediately. free_netdev assumes that all the netdevice
+refcounts have been dropped prior to it being called and as a
+result frees and clears out the refcount pointer.
+
+However, this is not necessarily true as some of the operations
+in the NETDEV_UNREGISTER notifier handlers queue RCU callbacks for
+invocation after a grace period. The IPv4 callback in_dev_rcu_put
+tries to access the refcount after free_netdev is called which
+leads to a null de-reference-
+
+44837.761523:   <6> Unable to handle kernel paging request at
+                    virtual address 0000004a88287000
+44837.761651:   <2> pc : in_dev_finish_destroy+0x4c/0xc8
+44837.761654:   <2> lr : in_dev_finish_destroy+0x2c/0xc8
+44837.762393:   <2> Call trace:
+44837.762398:   <2>  in_dev_finish_destroy+0x4c/0xc8
+44837.762404:   <2>  in_dev_rcu_put+0x24/0x30
+44837.762412:   <2>  rcu_nocb_kthread+0x43c/0x468
+44837.762418:   <2>  kthread+0x118/0x128
+44837.762424:   <2>  ret_from_fork+0x10/0x1c
+
+Fix this by waiting for the completion of the call_rcu() in
+case of register_netdevice errors.
+
+Fixes: 93ee31f14f6f ("[NET]: Fix free_netdev on register_netdev failure.")
+Cc: Sean Tranchetti <stranche@codeaurora.org>
+Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -8768,6 +8768,8 @@ int register_netdevice(struct net_device
+       ret = notifier_to_errno(ret);
+       if (ret) {
+               rollback_registered(dev);
++              rcu_barrier();
++
+               dev->reg_state = NETREG_UNREGISTERED;
+       }
+       /*
diff --git a/queue-5.2/net-fixed_phy-add-forward-declaration-for-struct-gpio_desc.patch b/queue-5.2/net-fixed_phy-add-forward-declaration-for-struct-gpio_desc.patch
new file mode 100644 (file)
index 0000000..ff119cb
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Moritz Fischer <mdf@kernel.org>
+Date: Tue, 3 Sep 2019 11:46:52 -0700
+Subject: net: fixed_phy: Add forward declaration for struct gpio_desc;
+
+From: Moritz Fischer <mdf@kernel.org>
+
+[ Upstream commit ebe26aca98fcf9fbe5017b5cbe216413cee69df5 ]
+
+Add forward declaration for struct gpio_desc in order to address
+the following:
+
+./include/linux/phy_fixed.h:48:17: error: 'struct gpio_desc' declared inside parameter list [-Werror]
+./include/linux/phy_fixed.h:48:17: error: its scope is only this definition or declaration, which is probably not what you want [-Werror]
+
+Fixes: 71bd106d2567 ("net: fixed-phy: Add fixed_phy_register_with_gpiod() API")
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/phy_fixed.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/linux/phy_fixed.h
++++ b/include/linux/phy_fixed.h
+@@ -11,6 +11,7 @@ struct fixed_phy_status {
+ };
+ struct device_node;
++struct gpio_desc;
+ #if IS_ENABLED(CONFIG_FIXED_PHY)
+ extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier);
diff --git a/queue-5.2/net-gso-fix-skb_segment-splat-when-splitting-gso_size-mangled-skb-having-linear-headed-frag_list.patch b/queue-5.2/net-gso-fix-skb_segment-splat-when-splitting-gso_size-mangled-skb-having-linear-headed-frag_list.patch
new file mode 100644 (file)
index 0000000..b51191c
--- /dev/null
@@ -0,0 +1,105 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Shmulik Ladkani <shmulik@metanetworks.com>
+Date: Fri, 6 Sep 2019 12:23:50 +0300
+Subject: net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list
+
+From: Shmulik Ladkani <shmulik@metanetworks.com>
+
+[ Upstream commit 3dcbdb134f329842a38f0e6797191b885ab00a00 ]
+
+Historically, support for frag_list packets entering skb_segment() was
+limited to frag_list members terminating on exact same gso_size
+boundaries. This is verified with a BUG_ON since commit 89319d3801d1
+("net: Add frag_list support to skb_segment"), quote:
+
+    As such we require all frag_list members terminate on exact MSS
+    boundaries.  This is checked using BUG_ON.
+    As there should only be one producer in the kernel of such packets,
+    namely GRO, this requirement should not be difficult to maintain.
+
+However, since commit 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper"),
+the "exact MSS boundaries" assumption no longer holds:
+An eBPF program using bpf_skb_change_proto() DOES modify 'gso_size', but
+leaves the frag_list members as originally merged by GRO with the
+original 'gso_size'. Example of such programs are bpf-based NAT46 or
+NAT64.
+
+This lead to a kernel BUG_ON for flows involving:
+ - GRO generating a frag_list skb
+ - bpf program performing bpf_skb_change_proto() or bpf_skb_adjust_room()
+ - skb_segment() of the skb
+
+See example BUG_ON reports in [0].
+
+In commit 13acc94eff12 ("net: permit skb_segment on head_frag frag_list skb"),
+skb_segment() was modified to support the "gso_size mangling" case of
+a frag_list GRO'ed skb, but *only* for frag_list members having
+head_frag==true (having a page-fragment head).
+
+Alas, GRO packets having frag_list members with a linear kmalloced head
+(head_frag==false) still hit the BUG_ON.
+
+This commit adds support to skb_segment() for a 'head_skb' packet having
+a frag_list whose members are *non* head_frag, with gso_size mangled, by
+disabling SG and thus falling-back to copying the data from the given
+'head_skb' into the generated segmented skbs - as suggested by Willem de
+Bruijn [1].
+
+Since this approach involves the penalty of skb_copy_and_csum_bits()
+when building the segments, care was taken in order to enable this
+solution only when required:
+ - untrusted gso_size, by testing SKB_GSO_DODGY is set
+   (SKB_GSO_DODGY is set by any gso_size mangling functions in
+    net/core/filter.c)
+ - the frag_list is non empty, its item is a non head_frag, *and* the
+   headlen of the given 'head_skb' does not match the gso_size.
+
+[0]
+https://lore.kernel.org/netdev/20190826170724.25ff616f@pixies/
+https://lore.kernel.org/netdev/9265b93f-253d-6b8c-f2b8-4b54eff1835c@fb.com/
+
+[1]
+https://lore.kernel.org/netdev/CA+FuTSfVsgNDi7c=GUU8nMg2hWxF2SjCNLXetHeVPdnxAW5K-w@mail.gmail.com/
+
+Fixes: 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper")
+Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: Alexander Duyck <alexander.duyck@gmail.com>
+Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Alexander Duyck <alexander.h.duyck@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/skbuff.c |   19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3531,6 +3531,25 @@ struct sk_buff *skb_segment(struct sk_bu
+       int pos;
+       int dummy;
++      if (list_skb && !list_skb->head_frag && skb_headlen(list_skb) &&
++          (skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY)) {
++              /* gso_size is untrusted, and we have a frag_list with a linear
++               * non head_frag head.
++               *
++               * (we assume checking the first list_skb member suffices;
++               * i.e if either of the list_skb members have non head_frag
++               * head, then the first one has too).
++               *
++               * If head_skb's headlen does not fit requested gso_size, it
++               * means that the frag_list members do NOT terminate on exact
++               * gso_size boundaries. Hence we cannot perform skb_frag_t page
++               * sharing. Therefore we must fallback to copying the frag_list
++               * skbs; we do so by disabling SG.
++               */
++              if (mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb))
++                      features &= ~NETIF_F_SG;
++      }
++
+       __skb_push(head_skb, doffset);
+       proto = skb_network_protocol(head_skb, &dummy);
+       if (unlikely(!proto))
diff --git a/queue-5.2/net-ipv6-fix-excessive-rtf_addrconf-flag-on-1-128-local-route-and-others.patch b/queue-5.2/net-ipv6-fix-excessive-rtf_addrconf-flag-on-1-128-local-route-and-others.patch
new file mode 100644 (file)
index 0000000..c50498f
--- /dev/null
@@ -0,0 +1,66 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: "Maciej Żenczykowski" <maze@google.com>
+Date: Mon, 2 Sep 2019 09:23:36 -0700
+Subject: net-ipv6: fix excessive RTF_ADDRCONF flag on ::1/128 local route (and others)
+
+From: "Maciej Żenczykowski" <maze@google.com>
+
+[ Upstream commit d55a2e374a94fa34a3048c6a2be535266e506d97 ]
+
+There is a subtle change in behaviour introduced by:
+  commit c7a1ce397adacaf5d4bb2eab0a738b5f80dc3e43
+  'ipv6: Change addrconf_f6i_alloc to use ip6_route_info_create'
+
+Before that patch /proc/net/ipv6_route includes:
+00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000003 00000000 80200001 lo
+
+Afterwards /proc/net/ipv6_route includes:
+00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000002 00000000 80240001 lo
+
+ie. the above commit causes the ::1/128 local (automatic) route to be flagged with RTF_ADDRCONF (0x040000).
+
+AFAICT, this is incorrect since these routes are *not* coming from RA's.
+
+As such, this patch restores the old behaviour.
+
+Fixes: c7a1ce397ada ("ipv6: Change addrconf_f6i_alloc to use ip6_route_info_create")
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Lorenzo Colitti <lorenzo@google.com>
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Reviewed-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -3841,13 +3841,14 @@ struct fib6_info *addrconf_f6i_alloc(str
+       struct fib6_config cfg = {
+               .fc_table = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL,
+               .fc_ifindex = idev->dev->ifindex,
+-              .fc_flags = RTF_UP | RTF_ADDRCONF | RTF_NONEXTHOP,
++              .fc_flags = RTF_UP | RTF_NONEXTHOP,
+               .fc_dst = *addr,
+               .fc_dst_len = 128,
+               .fc_protocol = RTPROT_KERNEL,
+               .fc_nlinfo.nl_net = net,
+               .fc_ignore_dev_down = true,
+       };
++      struct fib6_info *f6i;
+       if (anycast) {
+               cfg.fc_type = RTN_ANYCAST;
+@@ -3857,7 +3858,10 @@ struct fib6_info *addrconf_f6i_alloc(str
+               cfg.fc_flags |= RTF_LOCAL;
+       }
+-      return ip6_route_info_create(&cfg, gfp_flags, NULL);
++      f6i = ip6_route_info_create(&cfg, gfp_flags, NULL);
++      if (f6i)
++              f6i->dst_nocount = true;
++      return f6i;
+ }
+ /* remove deleted ip from prefsrc entries */
diff --git a/queue-5.2/net-phylink-fix-flow-control-resolution.patch b/queue-5.2/net-phylink-fix-flow-control-resolution.patch
new file mode 100644 (file)
index 0000000..264788e
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Stefan Chulski <stefanc@marvell.com>
+Date: Thu, 5 Sep 2019 19:46:18 +0300
+Subject: net: phylink: Fix flow control resolution
+
+From: Stefan Chulski <stefanc@marvell.com>
+
+[ Upstream commit 63b2ed4e10b2e6c913e1d8cdd728e7fba4115a3d ]
+
+Regarding to IEEE 802.3-2015 standard section 2
+28B.3 Priority resolution - Table 28-3 - Pause resolution
+
+In case of Local device Pause=1 AsymDir=0, Link partner
+Pause=1 AsymDir=1, Local device resolution should be enable PAUSE
+transmit, disable PAUSE receive.
+And in case of Local device Pause=1 AsymDir=1, Link partner
+Pause=1 AsymDir=0, Local device resolution should be enable PAUSE
+receive, disable PAUSE transmit.
+
+Fixes: 9525ae83959b ("phylink: add phylink infrastructure")
+Signed-off-by: Stefan Chulski <stefanc@marvell.com>
+Reported-by: Shaul Ben-Mayor <shaulb@marvell.com>
+Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phylink.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -356,8 +356,8 @@ static void phylink_get_fixed_state(stru
+  *  Local device  Link partner
+  *  Pause AsymDir Pause AsymDir Result
+  *    1     X       1     X     TX+RX
+- *    0     1       1     1     RX
+- *    1     1       0     1     TX
++ *    0     1       1     1     TX
++ *    1     1       0     1     RX
+  */
+ static void phylink_resolve_flow(struct phylink *pl,
+                                struct phylink_link_state *state)
+@@ -378,7 +378,7 @@ static void phylink_resolve_flow(struct
+                       new_pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
+               else if (pause & MLO_PAUSE_ASYM)
+                       new_pause = state->pause & MLO_PAUSE_SYM ?
+-                               MLO_PAUSE_RX : MLO_PAUSE_TX;
++                               MLO_PAUSE_TX : MLO_PAUSE_RX;
+       } else {
+               new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK;
+       }
diff --git a/queue-5.2/net-sched-fix-reordering-issues.patch b/queue-5.2/net-sched-fix-reordering-issues.patch
new file mode 100644 (file)
index 0000000..2226fe2
--- /dev/null
@@ -0,0 +1,86 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 5 Sep 2019 05:20:22 -0700
+Subject: net: sched: fix reordering issues
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b88dd52c62bb5c5d58f0963287f41fd084352c57 ]
+
+Whenever MQ is not used on a multiqueue device, we experience
+serious reordering problems. Bisection found the cited
+commit.
+
+The issue can be described this way :
+
+- A single qdisc hierarchy is shared by all transmit queues.
+  (eg : tc qdisc replace dev eth0 root fq_codel)
+
+- When/if try_bulk_dequeue_skb_slow() dequeues a packet targetting
+  a different transmit queue than the one used to build a packet train,
+  we stop building the current list and save the 'bad' skb (P1) in a
+  special queue. (bad_txq)
+
+- When dequeue_skb() calls qdisc_dequeue_skb_bad_txq() and finds this
+  skb (P1), it checks if the associated transmit queues is still in frozen
+  state. If the queue is still blocked (by BQL or NIC tx ring full),
+  we leave the skb in bad_txq and return NULL.
+
+- dequeue_skb() calls q->dequeue() to get another packet (P2)
+
+  The other packet can target the problematic queue (that we found
+  in frozen state for the bad_txq packet), but another cpu just ran
+  TX completion and made room in the txq that is now ready to accept
+  new packets.
+
+- Packet P2 is sent while P1 is still held in bad_txq, P1 might be sent
+  at next round. In practice P2 is the lead of a big packet train
+  (P2,P3,P4 ...) filling the BQL budget and delaying P1 by many packets :/
+
+To solve this problem, we have to block the dequeue process as long
+as the first packet in bad_txq can not be sent. Reordering issues
+disappear and no side effects have been seen.
+
+Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_generic.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -46,6 +46,8 @@ EXPORT_SYMBOL(default_qdisc_ops);
+  * - updates to tree and tree walking are only done under the rtnl mutex.
+  */
++#define SKB_XOFF_MAGIC ((struct sk_buff *)1UL)
++
+ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
+ {
+       const struct netdev_queue *txq = q->dev_queue;
+@@ -71,7 +73,7 @@ static inline struct sk_buff *__skb_dequ
+                               q->q.qlen--;
+                       }
+               } else {
+-                      skb = NULL;
++                      skb = SKB_XOFF_MAGIC;
+               }
+       }
+@@ -253,8 +255,11 @@ validate:
+               return skb;
+       skb = qdisc_dequeue_skb_bad_txq(q);
+-      if (unlikely(skb))
++      if (unlikely(skb)) {
++              if (skb == SKB_XOFF_MAGIC)
++                      return NULL;
+               goto bulk;
++      }
+       skb = q->dequeue(q);
+       if (skb) {
+ bulk:
diff --git a/queue-5.2/net-sock_map-fix-missing-ulp-check-in-sock-hash-case.patch b/queue-5.2/net-sock_map-fix-missing-ulp-check-in-sock-hash-case.patch
new file mode 100644 (file)
index 0000000..9fdc68b
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: John Fastabend <john.fastabend@gmail.com>
+Date: Tue, 3 Sep 2019 13:24:50 -0700
+Subject: net: sock_map, fix missing ulp check in sock hash case
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit 44580a0118d3ede95fec4dce32df5f75f73cd663 ]
+
+sock_map and ULP only work together when ULP is loaded after the sock
+map is loaded. In the sock_map case we added a check for this to fail
+the load if ULP is already set. However, we missed the check on the
+sock_hash side.
+
+Add a ULP check to the sock_hash update path.
+
+Fixes: 604326b41a6fb ("bpf, sockmap: convert to generic sk_msg interface")
+Reported-by: syzbot+7a6ee4d0078eac6bf782@syzkaller.appspotmail.com
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/sock_map.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -661,6 +661,7 @@ static int sock_hash_update_common(struc
+                                  struct sock *sk, u64 flags)
+ {
+       struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
++      struct inet_connection_sock *icsk = inet_csk(sk);
+       u32 key_size = map->key_size, hash;
+       struct bpf_htab_elem *elem, *elem_new;
+       struct bpf_htab_bucket *bucket;
+@@ -671,6 +672,8 @@ static int sock_hash_update_common(struc
+       WARN_ON_ONCE(!rcu_read_lock_held());
+       if (unlikely(flags > BPF_EXIST))
+               return -EINVAL;
++      if (unlikely(icsk->icsk_ulp_data))
++              return -EINVAL;
+       link = sk_psock_init_link();
+       if (!link)
diff --git a/queue-5.2/sch_hhf-ensure-quantum-and-hhf_non_hh_weight-are-non-zero.patch b/queue-5.2/sch_hhf-ensure-quantum-and-hhf_non_hh_weight-are-non-zero.patch
new file mode 100644 (file)
index 0000000..cd6907a
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Sun, 8 Sep 2019 13:40:51 -0700
+Subject: sch_hhf: ensure quantum and hhf_non_hh_weight are non-zero
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit d4d6ec6dac07f263f06d847d6f732d6855522845 ]
+
+In case of TCA_HHF_NON_HH_WEIGHT or TCA_HHF_QUANTUM is zero,
+it would make no progress inside the loop in hhf_dequeue() thus
+kernel would get stuck.
+
+Fix this by checking this corner case in hhf_change().
+
+Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc")
+Reported-by: syzbot+bc6297c11f19ee807dc2@syzkaller.appspotmail.com
+Reported-by: syzbot+041483004a7f45f1f20a@syzkaller.appspotmail.com
+Reported-by: syzbot+55be5f513bed37fc4367@syzkaller.appspotmail.com
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Jiri Pirko <jiri@resnulli.us>
+Cc: Terry Lam <vtlam@google.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>
+---
+ net/sched/sch_hhf.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sched/sch_hhf.c
++++ b/net/sched/sch_hhf.c
+@@ -531,7 +531,7 @@ static int hhf_change(struct Qdisc *sch,
+               new_hhf_non_hh_weight = nla_get_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
+       non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight;
+-      if (non_hh_quantum > INT_MAX)
++      if (non_hh_quantum == 0 || non_hh_quantum > INT_MAX)
+               return -EINVAL;
+       sch_tree_lock(sch);
diff --git a/queue-5.2/sctp-fix-the-link-time-qualifier-of-sctp_ctrlsock_exit.patch b/queue-5.2/sctp-fix-the-link-time-qualifier-of-sctp_ctrlsock_exit.patch
new file mode 100644 (file)
index 0000000..b6911ef
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Wed, 11 Sep 2019 18:02:39 +0200
+Subject: sctp: Fix the link time qualifier of 'sctp_ctrlsock_exit()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b456d72412ca8797234449c25815e82f4e1426c0 ]
+
+The '.exit' functions from 'pernet_operations' structure should be marked
+as __net_exit, not __net_init.
+
+Fixes: 8e2d61e0aed2 ("sctp: fix race on protocol/netns initialization")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+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/protocol.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -1336,7 +1336,7 @@ static int __net_init sctp_ctrlsock_init
+       return status;
+ }
+-static void __net_init sctp_ctrlsock_exit(struct net *net)
++static void __net_exit sctp_ctrlsock_exit(struct net *net)
+ {
+       /* Free the control endpoint.  */
+       inet_ctl_sock_destroy(net->sctp.ctl_sock);
diff --git a/queue-5.2/sctp-fix-the-missing-put_user-when-dumping-transport-thresholds.patch b/queue-5.2/sctp-fix-the-missing-put_user-when-dumping-transport-thresholds.patch
new file mode 100644 (file)
index 0000000..2704924
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Xin Long <lucien.xin@gmail.com>
+Date: Mon, 9 Sep 2019 15:33:29 +0800
+Subject: sctp: fix the missing put_user when dumping transport thresholds
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit f794dc2304d83ab998c2eee5bab0549aff5c53a2 ]
+
+This issue causes SCTP_PEER_ADDR_THLDS sockopt not to be able to dump
+a transport thresholds info.
+
+Fix it by adding 'goto' put_user in sctp_getsockopt_paddr_thresholds.
+
+Fixes: 8add543e369d ("sctp: add SCTP_FUTURE_ASSOC for SCTP_PEER_ADDR_THLDS sockopt")
+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/socket.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -7176,7 +7176,7 @@ static int sctp_getsockopt_paddr_thresho
+               val.spt_pathmaxrxt = trans->pathmaxrxt;
+               val.spt_pathpfthld = trans->pf_retrans;
+-              return 0;
++              goto out;
+       }
+       asoc = sctp_id2assoc(sk, val.spt_assoc_id);
+@@ -7194,6 +7194,7 @@ static int sctp_getsockopt_paddr_thresho
+               val.spt_pathmaxrxt = sp->pathmaxrxt;
+       }
++out:
+       if (put_user(len, optlen) || copy_to_user(optval, &val, len))
+               return -EFAULT;
diff --git a/queue-5.2/sctp-use-transport-pf_retrans-in-sctp_do_8_2_transport_strike.patch b/queue-5.2/sctp-use-transport-pf_retrans-in-sctp_do_8_2_transport_strike.patch
new file mode 100644 (file)
index 0000000..224eb9a
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Xin Long <lucien.xin@gmail.com>
+Date: Mon, 2 Sep 2019 23:24:21 +0800
+Subject: sctp: use transport pf_retrans in sctp_do_8_2_transport_strike
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 10eb56c582c557c629271f1ee31e15e7a9b2558b ]
+
+Transport should use its own pf_retrans to do the error_count
+check, instead of asoc's. Otherwise, it's meaningless to make
+pf_retrans per transport.
+
+Fixes: 5aa93bcf66f4 ("sctp: Implement quick failover draft from tsvwg")
+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/sm_sideeffect.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -547,7 +547,7 @@ static void sctp_do_8_2_transport_strike
+       if (net->sctp.pf_enable &&
+          (transport->state == SCTP_ACTIVE) &&
+          (transport->error_count < transport->pathmaxrxt) &&
+-         (transport->error_count > asoc->pf_retrans)) {
++         (transport->error_count > transport->pf_retrans)) {
+               sctp_assoc_control_transport(asoc, transport,
+                                            SCTP_TRANSPORT_PF,
diff --git a/queue-5.2/tcp-fix-tcp_ecn_withdraw_cwr-to-clear-tcp_ecn_queue_cwr.patch b/queue-5.2/tcp-fix-tcp_ecn_withdraw_cwr-to-clear-tcp_ecn_queue_cwr.patch
new file mode 100644 (file)
index 0000000..5775f16
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Neal Cardwell <ncardwell@google.com>
+Date: Mon, 9 Sep 2019 16:56:02 -0400
+Subject: tcp: fix tcp_ecn_withdraw_cwr() to clear TCP_ECN_QUEUE_CWR
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit af38d07ed391b21f7405fa1f936ca9686787d6d2 ]
+
+Fix tcp_ecn_withdraw_cwr() to clear the correct bit:
+TCP_ECN_QUEUE_CWR.
+
+Rationale: basically, TCP_ECN_DEMAND_CWR is a bit that is purely about
+the behavior of data receivers, and deciding whether to reflect
+incoming IP ECN CE marks as outgoing TCP th->ece marks. The
+TCP_ECN_QUEUE_CWR bit is purely about the behavior of data senders,
+and deciding whether to send CWR. The tcp_ecn_withdraw_cwr() function
+is only called from tcp_undo_cwnd_reduction() by data senders during
+an undo, so it should zero the sender-side state,
+TCP_ECN_QUEUE_CWR. It does not make sense to stop the reflection of
+incoming CE bits on incoming data packets just because outgoing
+packets were spuriously retransmitted.
+
+The bug has been reproduced with packetdrill to manifest in a scenario
+with RFC3168 ECN, with an incoming data packet with CE bit set and
+carrying a TCP timestamp value that causes cwnd undo. Before this fix,
+the IP CE bit was ignored and not reflected in the TCP ECE header bit,
+and sender sent a TCP CWR ('W') bit on the next outgoing data packet,
+even though the cwnd reduction had been undone.  After this fix, the
+sender properly reflects the CE bit and does not set the W bit.
+
+Note: the bug actually predates 2005 git history; this Fixes footer is
+chosen to be the oldest SHA1 I have tested (from Sep 2007) for which
+the patch applies cleanly (since before this commit the code was in a
+.h file).
+
+Fixes: bdf1ee5d3bd3 ("[TCP]: Move code from tcp_ecn.h to tcp*.c and tcp.h & remove it")
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Acked-by: Yuchung Cheng <ycheng@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_input.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -266,7 +266,7 @@ static void tcp_ecn_accept_cwr(struct so
+ static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
+ {
+-      tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
++      tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
+ }
+ static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
diff --git a/queue-5.2/tipc-add-null-pointer-check-before-calling-kfree_rcu.patch b/queue-5.2/tipc-add-null-pointer-check-before-calling-kfree_rcu.patch
new file mode 100644 (file)
index 0000000..3250899
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Xin Long <lucien.xin@gmail.com>
+Date: Tue, 3 Sep 2019 17:53:12 +0800
+Subject: tipc: add NULL pointer check before calling kfree_rcu
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 42dec1dbe38239cf91cc1f4df7830c66276ced37 ]
+
+Unlike kfree(p), kfree_rcu(p, rcu) won't do NULL pointer check. When
+tipc_nametbl_remove_publ returns NULL, the panic below happens:
+
+   BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
+   RIP: 0010:__call_rcu+0x1d/0x290
+   Call Trace:
+    <IRQ>
+    tipc_publ_notify+0xa9/0x170 [tipc]
+    tipc_node_write_unlock+0x8d/0x100 [tipc]
+    tipc_node_link_down+0xae/0x1d0 [tipc]
+    tipc_node_check_dest+0x3ea/0x8f0 [tipc]
+    ? tipc_disc_rcv+0x2c7/0x430 [tipc]
+    tipc_disc_rcv+0x2c7/0x430 [tipc]
+    ? tipc_rcv+0x6bb/0xf20 [tipc]
+    tipc_rcv+0x6bb/0xf20 [tipc]
+    ? ip_route_input_slow+0x9cf/0xb10
+    tipc_udp_recv+0x195/0x1e0 [tipc]
+    ? tipc_udp_is_known_peer+0x80/0x80 [tipc]
+    udp_queue_rcv_skb+0x180/0x460
+    udp_unicast_rcv_skb.isra.56+0x75/0x90
+    __udp4_lib_rcv+0x4ce/0xb90
+    ip_local_deliver_finish+0x11c/0x210
+    ip_local_deliver+0x6b/0xe0
+    ? ip_rcv_finish+0xa9/0x410
+    ip_rcv+0x273/0x362
+
+Fixes: 97ede29e80ee ("tipc: convert name table read-write lock to RCU")
+Reported-by: Li Shuang <shuali@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/tipc/name_distr.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/tipc/name_distr.c
++++ b/net/tipc/name_distr.c
+@@ -223,7 +223,8 @@ static void tipc_publ_purge(struct net *
+                      publ->key);
+       }
+-      kfree_rcu(p, rcu);
++      if (p)
++              kfree_rcu(p, rcu);
+ }
+ /**
diff --git a/queue-5.2/tun-fix-use-after-free-when-register-netdev-failed.patch b/queue-5.2/tun-fix-use-after-free-when-register-netdev-failed.patch
new file mode 100644 (file)
index 0000000..904f82e
--- /dev/null
@@ -0,0 +1,193 @@
+From foo@baz Mon 16 Sep 2019 12:44:35 PM CEST
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Tue, 10 Sep 2019 18:56:57 +0800
+Subject: tun: fix use-after-free when register netdev failed
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 77f22f92dff8e7b45c7786a430626d38071d4670 ]
+
+I got a UAF repport in tun driver when doing fuzzy test:
+
+[  466.269490] ==================================================================
+[  466.271792] BUG: KASAN: use-after-free in tun_chr_read_iter+0x2ca/0x2d0
+[  466.271806] Read of size 8 at addr ffff888372139250 by task tun-test/2699
+[  466.271810]
+[  466.271824] CPU: 1 PID: 2699 Comm: tun-test Not tainted 5.3.0-rc1-00001-g5a9433db2614-dirty #427
+[  466.271833] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+[  466.271838] Call Trace:
+[  466.271858]  dump_stack+0xca/0x13e
+[  466.271871]  ? tun_chr_read_iter+0x2ca/0x2d0
+[  466.271890]  print_address_description+0x79/0x440
+[  466.271906]  ? vprintk_func+0x5e/0xf0
+[  466.271920]  ? tun_chr_read_iter+0x2ca/0x2d0
+[  466.271935]  __kasan_report+0x15c/0x1df
+[  466.271958]  ? tun_chr_read_iter+0x2ca/0x2d0
+[  466.271976]  kasan_report+0xe/0x20
+[  466.271987]  tun_chr_read_iter+0x2ca/0x2d0
+[  466.272013]  do_iter_readv_writev+0x4b7/0x740
+[  466.272032]  ? default_llseek+0x2d0/0x2d0
+[  466.272072]  do_iter_read+0x1c5/0x5e0
+[  466.272110]  vfs_readv+0x108/0x180
+[  466.299007]  ? compat_rw_copy_check_uvector+0x440/0x440
+[  466.299020]  ? fsnotify+0x888/0xd50
+[  466.299040]  ? __fsnotify_parent+0xd0/0x350
+[  466.299064]  ? fsnotify_first_mark+0x1e0/0x1e0
+[  466.304548]  ? vfs_write+0x264/0x510
+[  466.304569]  ? ksys_write+0x101/0x210
+[  466.304591]  ? do_preadv+0x116/0x1a0
+[  466.304609]  do_preadv+0x116/0x1a0
+[  466.309829]  do_syscall_64+0xc8/0x600
+[  466.309849]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[  466.309861] RIP: 0033:0x4560f9
+[  466.309875] Code: 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+[  466.309889] RSP: 002b:00007ffffa5166e8 EFLAGS: 00000206 ORIG_RAX: 0000000000000127
+[  466.322992] RAX: ffffffffffffffda RBX: 0000000000400460 RCX: 00000000004560f9
+[  466.322999] RDX: 0000000000000003 RSI: 00000000200008c0 RDI: 0000000000000003
+[  466.323007] RBP: 00007ffffa516700 R08: 0000000000000004 R09: 0000000000000000
+[  466.323014] R10: 0000000000000000 R11: 0000000000000206 R12: 000000000040cb10
+[  466.323021] R13: 0000000000000000 R14: 00000000006d7018 R15: 0000000000000000
+[  466.323057]
+[  466.323064] Allocated by task 2605:
+[  466.335165]  save_stack+0x19/0x80
+[  466.336240]  __kasan_kmalloc.constprop.8+0xa0/0xd0
+[  466.337755]  kmem_cache_alloc+0xe8/0x320
+[  466.339050]  getname_flags+0xca/0x560
+[  466.340229]  user_path_at_empty+0x2c/0x50
+[  466.341508]  vfs_statx+0xe6/0x190
+[  466.342619]  __do_sys_newstat+0x81/0x100
+[  466.343908]  do_syscall_64+0xc8/0x600
+[  466.345303]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[  466.347034]
+[  466.347517] Freed by task 2605:
+[  466.348471]  save_stack+0x19/0x80
+[  466.349476]  __kasan_slab_free+0x12e/0x180
+[  466.350726]  kmem_cache_free+0xc8/0x430
+[  466.351874]  putname+0xe2/0x120
+[  466.352921]  filename_lookup+0x257/0x3e0
+[  466.354319]  vfs_statx+0xe6/0x190
+[  466.355498]  __do_sys_newstat+0x81/0x100
+[  466.356889]  do_syscall_64+0xc8/0x600
+[  466.358037]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[  466.359567]
+[  466.360050] The buggy address belongs to the object at ffff888372139100
+[  466.360050]  which belongs to the cache names_cache of size 4096
+[  466.363735] The buggy address is located 336 bytes inside of
+[  466.363735]  4096-byte region [ffff888372139100, ffff88837213a100)
+[  466.367179] The buggy address belongs to the page:
+[  466.368604] page:ffffea000dc84e00 refcount:1 mapcount:0 mapping:ffff8883df1b4f00 index:0x0 compound_mapcount: 0
+[  466.371582] flags: 0x2fffff80010200(slab|head)
+[  466.372910] raw: 002fffff80010200 dead000000000100 dead000000000122 ffff8883df1b4f00
+[  466.375209] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
+[  466.377778] page dumped because: kasan: bad access detected
+[  466.379730]
+[  466.380288] Memory state around the buggy address:
+[  466.381844]  ffff888372139100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[  466.384009]  ffff888372139180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[  466.386131] >ffff888372139200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[  466.388257]                                                  ^
+[  466.390234]  ffff888372139280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[  466.392512]  ffff888372139300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[  466.394667] ==================================================================
+
+tun_chr_read_iter() accessed the memory which freed by free_netdev()
+called by tun_set_iff():
+
+        CPUA                                           CPUB
+  tun_set_iff()
+    alloc_netdev_mqs()
+    tun_attach()
+                                                  tun_chr_read_iter()
+                                                    tun_get()
+                                                    tun_do_read()
+                                                      tun_ring_recv()
+    register_netdevice() <-- inject error
+    goto err_detach
+    tun_detach_all() <-- set RCV_SHUTDOWN
+    free_netdev() <-- called from
+                     err_free_dev path
+      netdev_freemem() <-- free the memory
+                        without check refcount
+      (In this path, the refcount cannot prevent
+       freeing the memory of dev, and the memory
+       will be used by dev_put() called by
+       tun_chr_read_iter() on CPUB.)
+                                                     (Break from tun_ring_recv(),
+                                                     because RCV_SHUTDOWN is set)
+                                                   tun_put()
+                                                     dev_put() <-- use the memory
+                                                                   freed by netdev_freemem()
+
+Put the publishing of tfile->tun after register_netdevice(),
+so tun_get() won't get the tun pointer that freed by
+err_detach path if register_netdevice() failed.
+
+Fixes: eb0fb363f920 ("tuntap: attach queue 0 before registering netdevice")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Suggested-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tun.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -788,7 +788,8 @@ static void tun_detach_all(struct net_de
+ }
+ static int tun_attach(struct tun_struct *tun, struct file *file,
+-                    bool skip_filter, bool napi, bool napi_frags)
++                    bool skip_filter, bool napi, bool napi_frags,
++                    bool publish_tun)
+ {
+       struct tun_file *tfile = file->private_data;
+       struct net_device *dev = tun->dev;
+@@ -871,7 +872,8 @@ static int tun_attach(struct tun_struct
+        * initialized tfile; otherwise we risk using half-initialized
+        * object.
+        */
+-      rcu_assign_pointer(tfile->tun, tun);
++      if (publish_tun)
++              rcu_assign_pointer(tfile->tun, tun);
+       rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
+       tun->numqueues++;
+       tun_set_real_num_queues(tun);
+@@ -2731,7 +2733,7 @@ static int tun_set_iff(struct net *net,
+               err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER,
+                                ifr->ifr_flags & IFF_NAPI,
+-                               ifr->ifr_flags & IFF_NAPI_FRAGS);
++                               ifr->ifr_flags & IFF_NAPI_FRAGS, true);
+               if (err < 0)
+                       return err;
+@@ -2830,13 +2832,17 @@ static int tun_set_iff(struct net *net,
+               INIT_LIST_HEAD(&tun->disabled);
+               err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI,
+-                               ifr->ifr_flags & IFF_NAPI_FRAGS);
++                               ifr->ifr_flags & IFF_NAPI_FRAGS, false);
+               if (err < 0)
+                       goto err_free_flow;
+               err = register_netdevice(tun->dev);
+               if (err < 0)
+                       goto err_detach;
++              /* free_netdev() won't check refcnt, to aovid race
++               * with dev_put() we need publish tun after registration.
++               */
++              rcu_assign_pointer(tfile->tun, tun);
+       }
+       netif_carrier_on(tun->dev);
+@@ -2979,7 +2985,7 @@ static int tun_set_queue(struct file *fi
+               if (ret < 0)
+                       goto unlock;
+               ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI,
+-                               tun->flags & IFF_NAPI_FRAGS);
++                               tun->flags & IFF_NAPI_FRAGS, true);
+       } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
+               tun = rtnl_dereference(tfile->tun);
+               if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached)