]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jun 2020 12:09:48 +0000 (14:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jun 2020 12:09:48 +0000 (14:09 +0200)
added patches:
bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch
bnxt_en-fix-firmware-message-length-endianness.patch
bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch
crypto-chelsio-chtls-properly-set-tp-lsndtime.patch
esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch
ieee80211-fix-incorrect-mask-for-default-pe-duration.patch
ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch
ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch
net-dsa-declare-lockless-tx-feature-for-slave-ports.patch
netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch
netfilter-ipset-fix-subcounter-update-skip.patch
netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch
netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch
netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch
nexthop-expand-nexthop_is_multipath-in-a-few-places.patch
nexthops-don-t-modify-published-nexthop-groups.patch
nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch
powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch
qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch
x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch
xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch
xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch
xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch
xfrm-espintcp-save-and-call-old-sk_destruct.patch
xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch
xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch
xfrm-fix-error-in-comment.patch
xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch
xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch
xsk-add-overflow-check-for-u64-division-stored-into-u32.patch

31 files changed:
queue-5.6/bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch [new file with mode: 0644]
queue-5.6/bnxt_en-fix-firmware-message-length-endianness.patch [new file with mode: 0644]
queue-5.6/bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch [new file with mode: 0644]
queue-5.6/crypto-chelsio-chtls-properly-set-tp-lsndtime.patch [new file with mode: 0644]
queue-5.6/esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch [new file with mode: 0644]
queue-5.6/ieee80211-fix-incorrect-mask-for-default-pe-duration.patch [new file with mode: 0644]
queue-5.6/ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch [new file with mode: 0644]
queue-5.6/ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch [new file with mode: 0644]
queue-5.6/net-dsa-declare-lockless-tx-feature-for-slave-ports.patch [new file with mode: 0644]
queue-5.6/netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch [new file with mode: 0644]
queue-5.6/netfilter-ipset-fix-subcounter-update-skip.patch [new file with mode: 0644]
queue-5.6/netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch [new file with mode: 0644]
queue-5.6/netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch [new file with mode: 0644]
queue-5.6/netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch [new file with mode: 0644]
queue-5.6/nexthop-expand-nexthop_is_multipath-in-a-few-places.patch [new file with mode: 0644]
queue-5.6/nexthops-don-t-modify-published-nexthop-groups.patch [new file with mode: 0644]
queue-5.6/nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch [new file with mode: 0644]
queue-5.6/powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch [new file with mode: 0644]
queue-5.6/qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch [new file with mode: 0644]
queue-5.6/series
queue-5.6/x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch [new file with mode: 0644]
queue-5.6/xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch [new file with mode: 0644]
queue-5.6/xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch [new file with mode: 0644]
queue-5.6/xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch [new file with mode: 0644]
queue-5.6/xfrm-espintcp-save-and-call-old-sk_destruct.patch [new file with mode: 0644]
queue-5.6/xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch [new file with mode: 0644]
queue-5.6/xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch [new file with mode: 0644]
queue-5.6/xfrm-fix-error-in-comment.patch [new file with mode: 0644]
queue-5.6/xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch [new file with mode: 0644]
queue-5.6/xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch [new file with mode: 0644]
queue-5.6/xsk-add-overflow-check-for-u64-division-stored-into-u32.patch [new file with mode: 0644]

diff --git a/queue-5.6/bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch b/queue-5.6/bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch
new file mode 100644 (file)
index 0000000..dcfb57f
--- /dev/null
@@ -0,0 +1,41 @@
+From b8056e8434b037fdab08158fea99ed7bc8ef3a74 Mon Sep 17 00:00:00 2001
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Mon, 25 May 2020 17:41:17 -0400
+Subject: bnxt_en: Fix accumulation of bp->net_stats_prev.
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+commit b8056e8434b037fdab08158fea99ed7bc8ef3a74 upstream.
+
+We have logic to maintain network counters across resets by storing
+the counters in bp->net_stats_prev before reset.  But not all resets
+will clear the counters.  Certain resets that don't need to change
+the number of rings do not clear the counters.  The current logic
+accumulates the counters before all resets, causing big jumps in
+the counters after some resets, such as ethtool -G.
+
+Fix it by only accumulating the counters during reset if the irq_re_init
+parameter is set.  The parameter signifies that all rings and interrupts
+will be reset and that means that the counters will also be reset.
+
+Reported-by: Vijayendra Suman <vijayendra.suman@oracle.com>
+Fixes: b8875ca356f1 ("bnxt_en: Save ring statistics before reset.")
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -9324,7 +9324,7 @@ static void __bnxt_close_nic(struct bnxt
+       bnxt_free_skbs(bp);
+       /* Save ring stats before shutdown */
+-      if (bp->bnapi)
++      if (bp->bnapi && irq_re_init)
+               bnxt_get_ring_stats(bp, &bp->net_stats_prev);
+       if (irq_re_init) {
+               bnxt_free_irq(bp);
diff --git a/queue-5.6/bnxt_en-fix-firmware-message-length-endianness.patch b/queue-5.6/bnxt_en-fix-firmware-message-length-endianness.patch
new file mode 100644 (file)
index 0000000..c5149eb
--- /dev/null
@@ -0,0 +1,105 @@
+From 2a5a8800fa915bd9bc272c91ca64728e6aa84c0a Mon Sep 17 00:00:00 2001
+From: Edwin Peer <edwin.peer@broadcom.com>
+Date: Mon, 25 May 2020 17:41:19 -0400
+Subject: bnxt_en: fix firmware message length endianness
+
+From: Edwin Peer <edwin.peer@broadcom.com>
+
+commit 2a5a8800fa915bd9bc272c91ca64728e6aa84c0a upstream.
+
+The explicit mask and shift is not the appropriate way to parse fields
+out of a little endian struct. The length field is internally __le16
+and the strategy employed only happens to work on little endian machines
+because the offset used is actually incorrect (length is at offset 6).
+
+Also remove the related and no longer used definitions from bnxt.h.
+
+Fixes: 845adfe40c2a ("bnxt_en: Improve valid bit checking in firmware response message.")
+Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |   14 ++++----------
+ drivers/net/ethernet/broadcom/bnxt/bnxt.h |    5 -----
+ 2 files changed, 4 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -4184,14 +4184,12 @@ static int bnxt_hwrm_do_send_msg(struct
+       int i, intr_process, rc, tmo_count;
+       struct input *req = msg;
+       u32 *data = msg;
+-      __le32 *resp_len;
+       u8 *valid;
+       u16 cp_ring_id, len = 0;
+       struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
+       u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
+       struct hwrm_short_input short_input = {0};
+       u32 doorbell_offset = BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER;
+-      u8 *resp_addr = (u8 *)bp->hwrm_cmd_resp_addr;
+       u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
+       u16 dst = BNXT_HWRM_CHNL_CHIMP;
+@@ -4209,7 +4207,6 @@ static int bnxt_hwrm_do_send_msg(struct
+               bar_offset = BNXT_GRCPF_REG_KONG_COMM;
+               doorbell_offset = BNXT_GRCPF_REG_KONG_COMM_TRIGGER;
+               resp = bp->hwrm_cmd_kong_resp_addr;
+-              resp_addr = (u8 *)bp->hwrm_cmd_kong_resp_addr;
+       }
+       memset(resp, 0, PAGE_SIZE);
+@@ -4278,7 +4275,6 @@ static int bnxt_hwrm_do_send_msg(struct
+       tmo_count = HWRM_SHORT_TIMEOUT_COUNTER;
+       timeout = timeout - HWRM_SHORT_MIN_TIMEOUT * HWRM_SHORT_TIMEOUT_COUNTER;
+       tmo_count += DIV_ROUND_UP(timeout, HWRM_MIN_TIMEOUT);
+-      resp_len = (__le32 *)(resp_addr + HWRM_RESP_LEN_OFFSET);
+       if (intr_process) {
+               u16 seq_id = bp->hwrm_intr_seq_id;
+@@ -4306,9 +4302,8 @@ static int bnxt_hwrm_do_send_msg(struct
+                                          le16_to_cpu(req->req_type));
+                       return -EBUSY;
+               }
+-              len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
+-                    HWRM_RESP_LEN_SFT;
+-              valid = resp_addr + len - 1;
++              len = le16_to_cpu(resp->resp_len);
++              valid = ((u8 *)resp) + len - 1;
+       } else {
+               int j;
+@@ -4319,8 +4314,7 @@ static int bnxt_hwrm_do_send_msg(struct
+                        */
+                       if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
+                               return -EBUSY;
+-                      len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
+-                            HWRM_RESP_LEN_SFT;
++                      len = le16_to_cpu(resp->resp_len);
+                       if (len)
+                               break;
+                       /* on first few passes, just barely sleep */
+@@ -4342,7 +4336,7 @@ static int bnxt_hwrm_do_send_msg(struct
+               }
+               /* Last byte of resp contains valid bit */
+-              valid = resp_addr + len - 1;
++              valid = ((u8 *)resp) + len - 1;
+               for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
+                       /* make sure we read from updated DMA memory */
+                       dma_rmb();
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -654,11 +654,6 @@ struct nqe_cn {
+ #define HWRM_CMD_TIMEOUT              (bp->hwrm_cmd_timeout)
+ #define HWRM_RESET_TIMEOUT            ((HWRM_CMD_TIMEOUT) * 4)
+ #define HWRM_COREDUMP_TIMEOUT         ((HWRM_CMD_TIMEOUT) * 12)
+-#define HWRM_RESP_ERR_CODE_MASK               0xffff
+-#define HWRM_RESP_LEN_OFFSET          4
+-#define HWRM_RESP_LEN_MASK            0xffff0000
+-#define HWRM_RESP_LEN_SFT             16
+-#define HWRM_RESP_VALID_MASK          0xff000000
+ #define BNXT_HWRM_REQ_MAX_SIZE                128
+ #define BNXT_HWRM_REQS_PER_PAGE               (BNXT_PAGE_SIZE /       \
+                                        BNXT_HWRM_REQ_MAX_SIZE)
diff --git a/queue-5.6/bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch b/queue-5.6/bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch
new file mode 100644 (file)
index 0000000..442d95f
--- /dev/null
@@ -0,0 +1,38 @@
+From a068aab42258e25094bc2c159948d263ed7d7a77 Mon Sep 17 00:00:00 2001
+From: Qiushi Wu <wu000273@umn.edu>
+Date: Wed, 27 May 2020 22:10:29 -0500
+Subject: bonding: Fix reference count leak in bond_sysfs_slave_add.
+
+From: Qiushi Wu <wu000273@umn.edu>
+
+commit a068aab42258e25094bc2c159948d263ed7d7a77 upstream.
+
+kobject_init_and_add() takes reference even when it fails.
+If this function returns an error, kobject_put() must be called to
+properly clean up the memory associated with the object. Previous
+commit "b8eb718348b8" fixed a similar problem.
+
+Fixes: 07699f9a7c8d ("bonding: add sysfs /slave dir for bond slave devices.")
+Signed-off-by: Qiushi Wu <wu000273@umn.edu>
+Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/bonding/bond_sysfs_slave.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/bonding/bond_sysfs_slave.c
++++ b/drivers/net/bonding/bond_sysfs_slave.c
+@@ -149,8 +149,10 @@ int bond_sysfs_slave_add(struct slave *s
+       err = kobject_init_and_add(&slave->kobj, &slave_ktype,
+                                  &(slave->dev->dev.kobj), "bonding_slave");
+-      if (err)
++      if (err) {
++              kobject_put(&slave->kobj);
+               return err;
++      }
+       for (a = slave_attrs; *a; ++a) {
+               err = sysfs_create_file(&slave->kobj, &((*a)->attr));
diff --git a/queue-5.6/crypto-chelsio-chtls-properly-set-tp-lsndtime.patch b/queue-5.6/crypto-chelsio-chtls-properly-set-tp-lsndtime.patch
new file mode 100644 (file)
index 0000000..3685c4c
--- /dev/null
@@ -0,0 +1,33 @@
+From a4976a3ef844c510ae9120290b23e9f3f47d6bce Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 26 May 2020 17:28:56 -0700
+Subject: crypto: chelsio/chtls: properly set tp->lsndtime
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit a4976a3ef844c510ae9120290b23e9f3f47d6bce upstream.
+
+TCP tp->lsndtime unit/base is tcp_jiffies32, not tcp_time_stamp()
+
+Fixes: 36bedb3f2e5b ("crypto: chtls - Inline TLS record Tx")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Ayush Sawal <ayush.sawal@chelsio.com>
+Cc: Vinay Kumar Yadav <vinay.yadav@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/chelsio/chtls/chtls_io.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/chelsio/chtls/chtls_io.c
++++ b/drivers/crypto/chelsio/chtls/chtls_io.c
+@@ -682,7 +682,7 @@ int chtls_push_frames(struct chtls_sock
+                               make_tx_data_wr(sk, skb, immdlen, len,
+                                               credits_needed, completion);
+                       tp->snd_nxt += len;
+-                      tp->lsndtime = tcp_time_stamp(tp);
++                      tp->lsndtime = tcp_jiffies32;
+                       if (completion)
+                               ULP_SKB_CB(skb)->flags &= ~ULPCB_FLAG_NEED_HDR;
+               } else {
diff --git a/queue-5.6/esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch b/queue-5.6/esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch
new file mode 100644 (file)
index 0000000..83607c1
--- /dev/null
@@ -0,0 +1,54 @@
+From 3c96ec56828922e3fe5477f75eb3fc02f98f98b5 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Fri, 10 Apr 2020 17:06:56 +0800
+Subject: esp6: get the right proto for transport mode in esp6_gso_encap
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 3c96ec56828922e3fe5477f75eb3fc02f98f98b5 upstream.
+
+For transport mode, when ipv6 nexthdr is set, the packet format might
+be like:
+
+    ----------------------------------------------------
+    |        | dest |     |     |      |  ESP    | ESP |
+    | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
+    ----------------------------------------------------
+
+What it wants to get for x-proto in esp6_gso_encap() is the proto that
+will be set in ESP nexthdr. So it should skip all ipv6 nexthdrs and
+get the real transport protocol. Othersize, the wrong proto number
+will be set into ESP nexthdr.
+
+This patch is to skip all ipv6 nexthdrs by calling ipv6_skip_exthdr()
+in esp6_gso_encap().
+
+Fixes: 7862b4058b9f ("esp: Add gso handlers for esp4 and esp6")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/esp6_offload.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -121,9 +121,16 @@ static void esp6_gso_encap(struct xfrm_s
+       struct ip_esp_hdr *esph;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
+       struct xfrm_offload *xo = xfrm_offload(skb);
+-      int proto = iph->nexthdr;
++      u8 proto = iph->nexthdr;
+       skb_push(skb, -skb_network_offset(skb));
++
++      if (x->outer_mode.encap == XFRM_MODE_TRANSPORT) {
++              __be16 frag;
++
++              ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &proto, &frag);
++      }
++
+       esph = ip_esp_hdr(skb);
+       *skb_mac_header(skb) = IPPROTO_ESP;
diff --git a/queue-5.6/ieee80211-fix-incorrect-mask-for-default-pe-duration.patch b/queue-5.6/ieee80211-fix-incorrect-mask-for-default-pe-duration.patch
new file mode 100644 (file)
index 0000000..0be37ec
--- /dev/null
@@ -0,0 +1,32 @@
+From d031781bdabe1027858a3220f868866586bf6e7c Mon Sep 17 00:00:00 2001
+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+Date: Wed, 6 May 2020 03:24:30 -0700
+Subject: ieee80211: Fix incorrect mask for default PE duration
+
+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+
+commit d031781bdabe1027858a3220f868866586bf6e7c upstream.
+
+Fixes bitmask for HE opration's default PE duration.
+
+Fixes: daa5b83513a7 ("mac80211: update HE operation fields to D3.0")
+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
+Link: https://lore.kernel.org/r/20200506102430.5153-1-pradeepc@codeaurora.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/ieee80211.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -2047,7 +2047,7 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr,
+ }
+ /* HE Operation defines */
+-#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK          0x00000003
++#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK          0x00000007
+ #define IEEE80211_HE_OPERATION_TWT_REQUIRED                   0x00000008
+ #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK             0x00003ff0
+ #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET           4
diff --git a/queue-5.6/ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch b/queue-5.6/ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch
new file mode 100644 (file)
index 0000000..a15270e
--- /dev/null
@@ -0,0 +1,65 @@
+From 976eba8ab596bab94b9714cd46d38d5c6a2c660d Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Tue, 21 Apr 2020 20:46:11 +0800
+Subject: ip_vti: receive ipip packet by calling ip_tunnel_rcv
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 976eba8ab596bab94b9714cd46d38d5c6a2c660d upstream.
+
+In Commit dd9ee3444014 ("vti4: Fix a ipip packet processing bug in
+'IPCOMP' virtual tunnel"), it tries to receive IPIP packets in vti
+by calling xfrm_input(). This case happens when a small packet or
+frag sent by peer is too small to get compressed.
+
+However, xfrm_input() will still get to the IPCOMP path where skb
+sec_path is set, but never dropped while it should have been done
+in vti_ipcomp4_protocol.cb_handler(vti_rcv_cb), as it's not an
+ipcomp4 packet. This will cause that the packet can never pass
+xfrm4_policy_check() in the upper protocol rcv functions.
+
+So this patch is to call ip_tunnel_rcv() to process IPIP packets
+instead.
+
+Fixes: dd9ee3444014 ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/ip_vti.c |   23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_vti.c
++++ b/net/ipv4/ip_vti.c
+@@ -93,7 +93,28 @@ static int vti_rcv_proto(struct sk_buff
+ static int vti_rcv_tunnel(struct sk_buff *skb)
+ {
+-      return vti_rcv(skb, ip_hdr(skb)->saddr, true);
++      struct ip_tunnel_net *itn = net_generic(dev_net(skb->dev), vti_net_id);
++      const struct iphdr *iph = ip_hdr(skb);
++      struct ip_tunnel *tunnel;
++
++      tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
++                                iph->saddr, iph->daddr, 0);
++      if (tunnel) {
++              struct tnl_ptk_info tpi = {
++                      .proto = htons(ETH_P_IP),
++              };
++
++              if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
++                      goto drop;
++              if (iptunnel_pull_header(skb, 0, tpi.proto, false))
++                      goto drop;
++              return ip_tunnel_rcv(tunnel, skb, &tpi, NULL, false);
++      }
++
++      return -EINVAL;
++drop:
++      kfree_skb(skb);
++      return 0;
+ }
+ static int vti_rcv_cb(struct sk_buff *skb, int err)
diff --git a/queue-5.6/ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch b/queue-5.6/ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch
new file mode 100644 (file)
index 0000000..1baec11
--- /dev/null
@@ -0,0 +1,110 @@
+From 1fd1c768f3624a5e66766e7b4ddb9b607cd834a5 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Tue, 26 May 2020 12:56:18 -0600
+Subject: ipv4: nexthop version of fib_info_nh_uses_dev
+
+From: David Ahern <dsahern@gmail.com>
+
+commit 1fd1c768f3624a5e66766e7b4ddb9b607cd834a5 upstream.
+
+Similar to the last path, need to fix fib_info_nh_uses_dev for
+external nexthops to avoid referencing multiple nh_grp structs.
+Move the device check in fib_info_nh_uses_dev to a helper and
+create a nexthop version that is called if the fib_info uses an
+external nexthop.
+
+Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
+Signed-off-by: David Ahern <dsahern@gmail.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>
+
+---
+ include/net/ip_fib.h    |   10 ++++++++++
+ include/net/nexthop.h   |   25 +++++++++++++++++++++++++
+ net/ipv4/fib_frontend.c |   19 ++++++++++---------
+ 3 files changed, 45 insertions(+), 9 deletions(-)
+
+--- a/include/net/ip_fib.h
++++ b/include/net/ip_fib.h
+@@ -447,6 +447,16 @@ static inline int fib_num_tclassid_users
+ #endif
+ int fib_unmerge(struct net *net);
++static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
++const struct net_device *dev)
++{
++      if (nhc->nhc_dev == dev ||
++          l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
++              return true;
++
++      return false;
++}
++
+ /* Exported by fib_semantics.c */
+ int ip_fib_check_default(__be32 gw, struct net_device *dev);
+ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -233,6 +233,31 @@ struct fib_nh_common *nexthop_fib_nhc(st
+       return &nhi->fib_nhc;
+ }
++static inline bool nexthop_uses_dev(const struct nexthop *nh,
++                                  const struct net_device *dev)
++{
++      struct nh_info *nhi;
++
++      if (nh->is_group) {
++              struct nh_group *nhg = rcu_dereference(nh->nh_grp);
++              int i;
++
++              for (i = 0; i < nhg->num_nh; i++) {
++                      struct nexthop *nhe = nhg->nh_entries[i].nh;
++
++                      nhi = rcu_dereference(nhe->nh_info);
++                      if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
++                              return true;
++              }
++      } else {
++              nhi = rcu_dereference(nh->nh_info);
++              if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
++                      return true;
++      }
++
++      return false;
++}
++
+ static inline unsigned int fib_info_num_path(const struct fib_info *fi)
+ {
+       if (unlikely(fi->nh))
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -309,17 +309,18 @@ bool fib_info_nh_uses_dev(struct fib_inf
+ {
+       bool dev_match = false;
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH
+-      int ret;
++      if (unlikely(fi->nh)) {
++              dev_match = nexthop_uses_dev(fi->nh, dev);
++      } else {
++              int ret;
+-      for (ret = 0; ret < fib_info_num_path(fi); ret++) {
+-              const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
++              for (ret = 0; ret < fib_info_num_path(fi); ret++) {
++                      const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
+-              if (nhc->nhc_dev == dev) {
+-                      dev_match = true;
+-                      break;
+-              } else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
+-                      dev_match = true;
+-                      break;
++                      if (nhc_l3mdev_matches_dev(nhc, dev)) {
++                              dev_match = true;
++                              break;
++                      }
+               }
+       }
+ #else
diff --git a/queue-5.6/net-dsa-declare-lockless-tx-feature-for-slave-ports.patch b/queue-5.6/net-dsa-declare-lockless-tx-feature-for-slave-ports.patch
new file mode 100644 (file)
index 0000000..0ff3c95
--- /dev/null
@@ -0,0 +1,174 @@
+From 2b86cb8299765688c5119fd18d5f436716c81010 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 27 May 2020 21:08:05 +0300
+Subject: net: dsa: declare lockless TX feature for slave ports
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+commit 2b86cb8299765688c5119fd18d5f436716c81010 upstream.
+
+Be there a platform with the following layout:
+
+      Regular NIC
+       |
+       +----> DSA master for switch port
+               |
+               +----> DSA master for another switch port
+
+After changing DSA back to static lockdep class keys in commit
+1a33e10e4a95 ("net: partially revert dynamic lockdep key changes"), this
+kernel splat can be seen:
+
+[   13.361198] ============================================
+[   13.366524] WARNING: possible recursive locking detected
+[   13.371851] 5.7.0-rc4-02121-gc32a05ecd7af-dirty #988 Not tainted
+[   13.377874] --------------------------------------------
+[   13.383201] swapper/0/0 is trying to acquire lock:
+[   13.388004] ffff0000668ff298 (&dsa_slave_netdev_xmit_lock_key){+.-.}-{2:2}, at: __dev_queue_xmit+0x84c/0xbe0
+[   13.397879]
+[   13.397879] but task is already holding lock:
+[   13.403727] ffff0000661a1698 (&dsa_slave_netdev_xmit_lock_key){+.-.}-{2:2}, at: __dev_queue_xmit+0x84c/0xbe0
+[   13.413593]
+[   13.413593] other info that might help us debug this:
+[   13.420140]  Possible unsafe locking scenario:
+[   13.420140]
+[   13.426075]        CPU0
+[   13.428523]        ----
+[   13.430969]   lock(&dsa_slave_netdev_xmit_lock_key);
+[   13.435946]   lock(&dsa_slave_netdev_xmit_lock_key);
+[   13.440924]
+[   13.440924]  *** DEADLOCK ***
+[   13.440924]
+[   13.446860]  May be due to missing lock nesting notation
+[   13.446860]
+[   13.453668] 6 locks held by swapper/0/0:
+[   13.457598]  #0: ffff800010003de0 ((&idev->mc_ifc_timer)){+.-.}-{0:0}, at: call_timer_fn+0x0/0x400
+[   13.466593]  #1: ffffd4d3fb478700 (rcu_read_lock){....}-{1:2}, at: mld_sendpack+0x0/0x560
+[   13.474803]  #2: ffffd4d3fb478728 (rcu_read_lock_bh){....}-{1:2}, at: ip6_finish_output2+0x64/0xb10
+[   13.483886]  #3: ffffd4d3fb478728 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x6c/0xbe0
+[   13.492793]  #4: ffff0000661a1698 (&dsa_slave_netdev_xmit_lock_key){+.-.}-{2:2}, at: __dev_queue_xmit+0x84c/0xbe0
+[   13.503094]  #5: ffffd4d3fb478728 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x6c/0xbe0
+[   13.512000]
+[   13.512000] stack backtrace:
+[   13.516369] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.7.0-rc4-02121-gc32a05ecd7af-dirty #988
+[   13.530421] Call trace:
+[   13.532871]  dump_backtrace+0x0/0x1d8
+[   13.536539]  show_stack+0x24/0x30
+[   13.539862]  dump_stack+0xe8/0x150
+[   13.543271]  __lock_acquire+0x1030/0x1678
+[   13.547290]  lock_acquire+0xf8/0x458
+[   13.550873]  _raw_spin_lock+0x44/0x58
+[   13.554543]  __dev_queue_xmit+0x84c/0xbe0
+[   13.558562]  dev_queue_xmit+0x24/0x30
+[   13.562232]  dsa_slave_xmit+0xe0/0x128
+[   13.565988]  dev_hard_start_xmit+0xf4/0x448
+[   13.570182]  __dev_queue_xmit+0x808/0xbe0
+[   13.574200]  dev_queue_xmit+0x24/0x30
+[   13.577869]  neigh_resolve_output+0x15c/0x220
+[   13.582237]  ip6_finish_output2+0x244/0xb10
+[   13.586430]  __ip6_finish_output+0x1dc/0x298
+[   13.590709]  ip6_output+0x84/0x358
+[   13.594116]  mld_sendpack+0x2bc/0x560
+[   13.597786]  mld_ifc_timer_expire+0x210/0x390
+[   13.602153]  call_timer_fn+0xcc/0x400
+[   13.605822]  run_timer_softirq+0x588/0x6e0
+[   13.609927]  __do_softirq+0x118/0x590
+[   13.613597]  irq_exit+0x13c/0x148
+[   13.616918]  __handle_domain_irq+0x6c/0xc0
+[   13.621023]  gic_handle_irq+0x6c/0x160
+[   13.624779]  el1_irq+0xbc/0x180
+[   13.627927]  cpuidle_enter_state+0xb4/0x4d0
+[   13.632120]  cpuidle_enter+0x3c/0x50
+[   13.635703]  call_cpuidle+0x44/0x78
+[   13.639199]  do_idle+0x228/0x2c8
+[   13.642433]  cpu_startup_entry+0x2c/0x48
+[   13.646363]  rest_init+0x1ac/0x280
+[   13.649773]  arch_call_rest_init+0x14/0x1c
+[   13.653878]  start_kernel+0x490/0x4bc
+
+Lockdep keys themselves were added in commit ab92d68fc22f ("net: core:
+add generic lockdep keys"), and it's very likely that this splat existed
+since then, but I have no real way to check, since this stacked platform
+wasn't supported by mainline back then.
+
+>From Taehee's own words:
+
+  This patch was considered that all stackable devices have LLTX flag.
+  But the dsa doesn't have LLTX, so this splat happened.
+  After this patch, dsa shares the same lockdep class key.
+  On the nested dsa interface architecture, which you illustrated,
+  the same lockdep class key will be used in __dev_queue_xmit() because
+  dsa doesn't have LLTX.
+  So that lockdep detects deadlock because the same lockdep class key is
+  used recursively although actually the different locks are used.
+  There are some ways to fix this problem.
+
+  1. using NETIF_F_LLTX flag.
+  If possible, using the LLTX flag is a very clear way for it.
+  But I'm so sorry I don't know whether the dsa could have LLTX or not.
+
+  2. using dynamic lockdep again.
+  It means that each interface uses a separate lockdep class key.
+  So, lockdep will not detect recursive locking.
+  But this way has a problem that it could consume lockdep class key
+  too many.
+  Currently, lockdep can have 8192 lockdep class keys.
+   - you can see this number with the following command.
+     cat /proc/lockdep_stats
+     lock-classes:                         1251 [max: 8192]
+     ...
+     The [max: 8192] means that the maximum number of lockdep class keys.
+  If too many lockdep class keys are registered, lockdep stops to work.
+  So, using a dynamic(separated) lockdep class key should be considered
+  carefully.
+  In addition, updating lockdep class key routine might have to be existing.
+  (lockdep_register_key(), lockdep_set_class(), lockdep_unregister_key())
+
+  3. Using lockdep subclass.
+  A lockdep class key could have 8 subclasses.
+  The different subclass is considered different locks by lockdep
+  infrastructure.
+  But "lock-classes" is not counted by subclasses.
+  So, it could avoid stopping lockdep infrastructure by an overflow of
+  lockdep class keys.
+  This approach should also have an updating lockdep class key routine.
+  (lockdep_set_subclass())
+
+  4. Using nonvalidate lockdep class key.
+  The lockdep infrastructure supports nonvalidate lockdep class key type.
+  It means this lockdep is not validated by lockdep infrastructure.
+  So, the splat will not happen but lockdep couldn't detect real deadlock
+  case because lockdep really doesn't validate it.
+  I think this should be used for really special cases.
+  (lockdep_set_novalidate_class())
+
+Further discussion here:
+https://patchwork.ozlabs.org/project/netdev/patch/20200503052220.4536-2-xiyou.wangcong@gmail.com/
+
+There appears to be no negative side-effect to declaring lockless TX for
+the DSA virtual interfaces, which means they handle their own locking.
+So that's what we do to make the splat go away.
+
+Patch tested in a wide variety of cases: unicast, multicast, PTP, etc.
+
+Fixes: ab92d68fc22f ("net: core: add generic lockdep keys")
+Suggested-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+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>
+
+---
+ net/dsa/slave.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1393,6 +1393,7 @@ int dsa_slave_create(struct dsa_port *po
+       if (ds->ops->port_vlan_add && ds->ops->port_vlan_del)
+               slave_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+       slave_dev->hw_features |= NETIF_F_HW_TC;
++      slave_dev->features |= NETIF_F_LLTX;
+       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
+       if (!IS_ERR_OR_NULL(port->mac))
+               ether_addr_copy(slave_dev->dev_addr, port->mac);
diff --git a/queue-5.6/netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch b/queue-5.6/netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch
new file mode 100644 (file)
index 0000000..995a9eb
--- /dev/null
@@ -0,0 +1,145 @@
+From ee04805ff54a63ffd90bc6749ebfe73473734ddb Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sun, 24 May 2020 19:52:10 +0200
+Subject: netfilter: conntrack: make conntrack userspace helpers work again
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+commit ee04805ff54a63ffd90bc6749ebfe73473734ddb upstream.
+
+Florian Westphal says:
+
+"Problem is that after the helper hook was merged back into the confirm
+one, the queueing itself occurs from the confirm hook, i.e. we queue
+from the last netfilter callback in the hook-list.
+
+Therefore, on return, the packet bypasses the confirm action and the
+connection is never committed to the main conntrack table.
+
+To fix this there are several ways:
+1. revert the 'Fixes' commit and have a extra helper hook again.
+   Works, but has the drawback of adding another indirect call for
+   everyone.
+
+2. Special case this: split the hooks only when userspace helper
+   gets added, so queueing occurs at a lower priority again,
+   and normal enqueue reinject would eventually call the last hook.
+
+3. Extend the existing nf_queue ct update hook to allow a forced
+   confirmation (plus run the seqadj code).
+
+This goes for 3)."
+
+Fixes: 827318feb69cb ("netfilter: conntrack: remove helper hook again")
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nf_conntrack_core.c |   78 +++++++++++++++++++++++++++++++++++---
+ 1 file changed, 72 insertions(+), 6 deletions(-)
+
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -2014,22 +2014,18 @@ static void nf_conntrack_attach(struct s
+       nf_conntrack_get(skb_nfct(nskb));
+ }
+-static int nf_conntrack_update(struct net *net, struct sk_buff *skb)
++static int __nf_conntrack_update(struct net *net, struct sk_buff *skb,
++                               struct nf_conn *ct)
+ {
+       struct nf_conntrack_tuple_hash *h;
+       struct nf_conntrack_tuple tuple;
+       enum ip_conntrack_info ctinfo;
+       struct nf_nat_hook *nat_hook;
+       unsigned int status;
+-      struct nf_conn *ct;
+       int dataoff;
+       u16 l3num;
+       u8 l4num;
+-      ct = nf_ct_get(skb, &ctinfo);
+-      if (!ct || nf_ct_is_confirmed(ct))
+-              return 0;
+-
+       l3num = nf_ct_l3num(ct);
+       dataoff = get_l4proto(skb, skb_network_offset(skb), l3num, &l4num);
+@@ -2086,6 +2082,76 @@ static int nf_conntrack_update(struct ne
+       return 0;
+ }
++/* This packet is coming from userspace via nf_queue, complete the packet
++ * processing after the helper invocation in nf_confirm().
++ */
++static int nf_confirm_cthelper(struct sk_buff *skb, struct nf_conn *ct,
++                             enum ip_conntrack_info ctinfo)
++{
++      const struct nf_conntrack_helper *helper;
++      const struct nf_conn_help *help;
++      unsigned int protoff;
++
++      help = nfct_help(ct);
++      if (!help)
++              return 0;
++
++      helper = rcu_dereference(help->helper);
++      if (!(helper->flags & NF_CT_HELPER_F_USERSPACE))
++              return 0;
++
++      switch (nf_ct_l3num(ct)) {
++      case NFPROTO_IPV4:
++              protoff = skb_network_offset(skb) + ip_hdrlen(skb);
++              break;
++#if IS_ENABLED(CONFIG_IPV6)
++      case NFPROTO_IPV6: {
++              __be16 frag_off;
++              u8 pnum;
++
++              pnum = ipv6_hdr(skb)->nexthdr;
++              protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
++                                         &frag_off);
++              if (protoff < 0 || (frag_off & htons(~0x7)) != 0)
++                      return 0;
++              break;
++      }
++#endif
++      default:
++              return 0;
++      }
++
++      if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
++          !nf_is_loopback_packet(skb)) {
++              if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) {
++                      NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
++                      return -1;
++              }
++      }
++
++      /* We've seen it coming out the other side: confirm it */
++      return nf_conntrack_confirm(skb) == NF_DROP ? - 1 : 0;
++}
++
++static int nf_conntrack_update(struct net *net, struct sk_buff *skb)
++{
++      enum ip_conntrack_info ctinfo;
++      struct nf_conn *ct;
++      int err;
++
++      ct = nf_ct_get(skb, &ctinfo);
++      if (!ct)
++              return 0;
++
++      if (!nf_ct_is_confirmed(ct)) {
++              err = __nf_conntrack_update(net, skb, ct);
++              if (err < 0)
++                      return err;
++      }
++
++      return nf_confirm_cthelper(skb, ct, ctinfo);
++}
++
+ static bool nf_conntrack_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
+                                      const struct sk_buff *skb)
+ {
diff --git a/queue-5.6/netfilter-ipset-fix-subcounter-update-skip.patch b/queue-5.6/netfilter-ipset-fix-subcounter-update-skip.patch
new file mode 100644 (file)
index 0000000..a4eef26
--- /dev/null
@@ -0,0 +1,33 @@
+From a164b95ad6055c50612795882f35e0efda1f1390 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <phil@nwl.cc>
+Date: Thu, 14 May 2020 13:31:21 +0200
+Subject: netfilter: ipset: Fix subcounter update skip
+
+From: Phil Sutter <phil@nwl.cc>
+
+commit a164b95ad6055c50612795882f35e0efda1f1390 upstream.
+
+If IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE is set, user requested to not
+update counters in sub sets. Therefore IPSET_FLAG_SKIP_COUNTER_UPDATE
+must be set, not unset.
+
+Fixes: 6e01781d1c80e ("netfilter: ipset: set match: add support to match the counters")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipset/ip_set_list_set.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/netfilter/ipset/ip_set_list_set.c
++++ b/net/netfilter/ipset/ip_set_list_set.c
+@@ -59,7 +59,7 @@ list_set_ktest(struct ip_set *set, const
+       /* Don't lookup sub-counters at all */
+       opt->cmdflags &= ~IPSET_FLAG_MATCH_COUNTERS;
+       if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
+-              opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
++              opt->cmdflags |= IPSET_FLAG_SKIP_COUNTER_UPDATE;
+       list_for_each_entry_rcu(e, &map->members, list) {
+               ret = ip_set_test(e->id, skb, par, opt);
+               if (ret <= 0)
diff --git a/queue-5.6/netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch b/queue-5.6/netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch
new file mode 100644 (file)
index 0000000..a95a51b
--- /dev/null
@@ -0,0 +1,201 @@
+From 4c559f15efcc43b996f4da528cd7f9483aaca36d Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Thu, 14 May 2020 14:14:23 +0200
+Subject: netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+commit 4c559f15efcc43b996f4da528cd7f9483aaca36d upstream.
+
+Dan Carpenter says: "Smatch complains that the value for "cmd" comes
+from the network and can't be trusted."
+
+Add pptp_msg_name() helper function that checks for the array boundary.
+
+Fixes: f09943fefe6b ("[NETFILTER]: nf_conntrack/nf_nat: add PPTP helper port")
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/netfilter/nf_conntrack_pptp.h |    2 
+ net/ipv4/netfilter/nf_nat_pptp.c            |    7 ---
+ net/netfilter/nf_conntrack_pptp.c           |   62 +++++++++++++++-------------
+ 3 files changed, 38 insertions(+), 33 deletions(-)
+
+--- a/include/linux/netfilter/nf_conntrack_pptp.h
++++ b/include/linux/netfilter/nf_conntrack_pptp.h
+@@ -10,7 +10,7 @@
+ #include <net/netfilter/nf_conntrack_expect.h>
+ #include <uapi/linux/netfilter/nf_conntrack_tuple_common.h>
+-extern const char *const pptp_msg_name[];
++extern const char *const pptp_msg_name(u_int16_t msg);
+ /* state of the control session */
+ enum pptp_ctrlsess_state {
+--- a/net/ipv4/netfilter/nf_nat_pptp.c
++++ b/net/ipv4/netfilter/nf_nat_pptp.c
+@@ -166,8 +166,7 @@ pptp_outbound_pkt(struct sk_buff *skb,
+               break;
+       default:
+               pr_debug("unknown outbound packet 0x%04x:%s\n", msg,
+-                       msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+-                                             pptp_msg_name[0]);
++                       pptp_msg_name(msg));
+               /* fall through */
+       case PPTP_SET_LINK_INFO:
+               /* only need to NAT in case PAC is behind NAT box */
+@@ -268,9 +267,7 @@ pptp_inbound_pkt(struct sk_buff *skb,
+               pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
+               break;
+       default:
+-              pr_debug("unknown inbound packet %s\n",
+-                       msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+-                                             pptp_msg_name[0]);
++              pr_debug("unknown inbound packet %s\n", pptp_msg_name(msg));
+               /* fall through */
+       case PPTP_START_SESSION_REQUEST:
+       case PPTP_START_SESSION_REPLY:
+--- a/net/netfilter/nf_conntrack_pptp.c
++++ b/net/netfilter/nf_conntrack_pptp.c
+@@ -72,24 +72,32 @@ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expec
+ #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+ /* PptpControlMessageType names */
+-const char *const pptp_msg_name[] = {
+-      "UNKNOWN_MESSAGE",
+-      "START_SESSION_REQUEST",
+-      "START_SESSION_REPLY",
+-      "STOP_SESSION_REQUEST",
+-      "STOP_SESSION_REPLY",
+-      "ECHO_REQUEST",
+-      "ECHO_REPLY",
+-      "OUT_CALL_REQUEST",
+-      "OUT_CALL_REPLY",
+-      "IN_CALL_REQUEST",
+-      "IN_CALL_REPLY",
+-      "IN_CALL_CONNECT",
+-      "CALL_CLEAR_REQUEST",
+-      "CALL_DISCONNECT_NOTIFY",
+-      "WAN_ERROR_NOTIFY",
+-      "SET_LINK_INFO"
++static const char *const pptp_msg_name_array[PPTP_MSG_MAX + 1] = {
++      [0]                             = "UNKNOWN_MESSAGE",
++      [PPTP_START_SESSION_REQUEST]    = "START_SESSION_REQUEST",
++      [PPTP_START_SESSION_REPLY]      = "START_SESSION_REPLY",
++      [PPTP_STOP_SESSION_REQUEST]     = "STOP_SESSION_REQUEST",
++      [PPTP_STOP_SESSION_REPLY]       = "STOP_SESSION_REPLY",
++      [PPTP_ECHO_REQUEST]             = "ECHO_REQUEST",
++      [PPTP_ECHO_REPLY]               = "ECHO_REPLY",
++      [PPTP_OUT_CALL_REQUEST]         = "OUT_CALL_REQUEST",
++      [PPTP_OUT_CALL_REPLY]           = "OUT_CALL_REPLY",
++      [PPTP_IN_CALL_REQUEST]          = "IN_CALL_REQUEST",
++      [PPTP_IN_CALL_REPLY]            = "IN_CALL_REPLY",
++      [PPTP_IN_CALL_CONNECT]          = "IN_CALL_CONNECT",
++      [PPTP_CALL_CLEAR_REQUEST]       = "CALL_CLEAR_REQUEST",
++      [PPTP_CALL_DISCONNECT_NOTIFY]   = "CALL_DISCONNECT_NOTIFY",
++      [PPTP_WAN_ERROR_NOTIFY]         = "WAN_ERROR_NOTIFY",
++      [PPTP_SET_LINK_INFO]            = "SET_LINK_INFO"
+ };
++
++const char *const pptp_msg_name(u_int16_t msg)
++{
++      if (msg > PPTP_MSG_MAX)
++              return pptp_msg_name_array[0];
++
++      return pptp_msg_name_array[msg];
++}
+ EXPORT_SYMBOL(pptp_msg_name);
+ #endif
+@@ -276,7 +284,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+       typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound;
+       msg = ntohs(ctlh->messageType);
+-      pr_debug("inbound control message %s\n", pptp_msg_name[msg]);
++      pr_debug("inbound control message %s\n", pptp_msg_name(msg));
+       switch (msg) {
+       case PPTP_START_SESSION_REPLY:
+@@ -311,7 +319,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+               pcid = pptpReq->ocack.peersCallID;
+               if (info->pns_call_id != pcid)
+                       goto invalid;
+-              pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
++              pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name(msg),
+                        ntohs(cid), ntohs(pcid));
+               if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) {
+@@ -328,7 +336,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+                       goto invalid;
+               cid = pptpReq->icreq.callID;
+-              pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
++              pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid));
+               info->cstate = PPTP_CALL_IN_REQ;
+               info->pac_call_id = cid;
+               break;
+@@ -347,7 +355,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+               if (info->pns_call_id != pcid)
+                       goto invalid;
+-              pr_debug("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
++              pr_debug("%s, PCID=%X\n", pptp_msg_name(msg), ntohs(pcid));
+               info->cstate = PPTP_CALL_IN_CONF;
+               /* we expect a GRE connection from PAC to PNS */
+@@ -357,7 +365,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+       case PPTP_CALL_DISCONNECT_NOTIFY:
+               /* server confirms disconnect */
+               cid = pptpReq->disc.callID;
+-              pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
++              pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid));
+               info->cstate = PPTP_CALL_NONE;
+               /* untrack this call id, unexpect GRE packets */
+@@ -384,7 +392,7 @@ pptp_inbound_pkt(struct sk_buff *skb, un
+ invalid:
+       pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+                "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+-               msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
++               pptp_msg_name(msg),
+                msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+                ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+       return NF_ACCEPT;
+@@ -404,7 +412,7 @@ pptp_outbound_pkt(struct sk_buff *skb, u
+       typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound;
+       msg = ntohs(ctlh->messageType);
+-      pr_debug("outbound control message %s\n", pptp_msg_name[msg]);
++      pr_debug("outbound control message %s\n", pptp_msg_name(msg));
+       switch (msg) {
+       case PPTP_START_SESSION_REQUEST:
+@@ -426,7 +434,7 @@ pptp_outbound_pkt(struct sk_buff *skb, u
+               info->cstate = PPTP_CALL_OUT_REQ;
+               /* track PNS call id */
+               cid = pptpReq->ocreq.callID;
+-              pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
++              pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid));
+               info->pns_call_id = cid;
+               break;
+@@ -440,7 +448,7 @@ pptp_outbound_pkt(struct sk_buff *skb, u
+               pcid = pptpReq->icack.peersCallID;
+               if (info->pac_call_id != pcid)
+                       goto invalid;
+-              pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
++              pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name(msg),
+                        ntohs(cid), ntohs(pcid));
+               if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) {
+@@ -480,7 +488,7 @@ pptp_outbound_pkt(struct sk_buff *skb, u
+ invalid:
+       pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+                "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+-               msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
++               pptp_msg_name(msg),
+                msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+                ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+       return NF_ACCEPT;
diff --git a/queue-5.6/netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch b/queue-5.6/netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch
new file mode 100644 (file)
index 0000000..c668a13
--- /dev/null
@@ -0,0 +1,40 @@
+From 703acd70f2496537457186211c2f03e792409e68 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sun, 24 May 2020 21:04:42 +0200
+Subject: netfilter: nfnetlink_cthelper: unbreak userspace helper support
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+commit 703acd70f2496537457186211c2f03e792409e68 upstream.
+
+Restore helper data size initialization and fix memcopy of the helper
+data size.
+
+Fixes: 157ffffeb5dc ("netfilter: nfnetlink_cthelper: reject too large userspace allocation requests")
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nfnetlink_cthelper.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/nfnetlink_cthelper.c
++++ b/net/netfilter/nfnetlink_cthelper.c
+@@ -103,7 +103,7 @@ nfnl_cthelper_from_nlattr(struct nlattr
+       if (help->helper->data_len == 0)
+               return -EINVAL;
+-      nla_memcpy(help->data, nla_data(attr), sizeof(help->data));
++      nla_memcpy(help->data, attr, sizeof(help->data));
+       return 0;
+ }
+@@ -240,6 +240,7 @@ nfnl_cthelper_create(const struct nlattr
+               ret = -ENOMEM;
+               goto err2;
+       }
++      helper->data_len = size;
+       helper->flags |= NF_CT_HELPER_F_USERSPACE;
+       memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple));
diff --git a/queue-5.6/netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch b/queue-5.6/netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch
new file mode 100644 (file)
index 0000000..0df6252
--- /dev/null
@@ -0,0 +1,38 @@
+From e9c284ec4b41c827f4369973d2792992849e4fa5 Mon Sep 17 00:00:00 2001
+From: Michael Braun <michael-dev@fami-braun.de>
+Date: Wed, 6 May 2020 11:46:25 +0200
+Subject: netfilter: nft_reject_bridge: enable reject with bridge vlan
+
+From: Michael Braun <michael-dev@fami-braun.de>
+
+commit e9c284ec4b41c827f4369973d2792992849e4fa5 upstream.
+
+Currently, using the bridge reject target with tagged packets
+results in untagged packets being sent back.
+
+Fix this by mirroring the vlan id as well.
+
+Fixes: 85f5b3086a04 ("netfilter: bridge: add reject support")
+Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bridge/netfilter/nft_reject_bridge.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/bridge/netfilter/nft_reject_bridge.c
++++ b/net/bridge/netfilter/nft_reject_bridge.c
+@@ -31,6 +31,12 @@ static void nft_reject_br_push_etherhdr(
+       ether_addr_copy(eth->h_dest, eth_hdr(oldskb)->h_source);
+       eth->h_proto = eth_hdr(oldskb)->h_proto;
+       skb_pull(nskb, ETH_HLEN);
++
++      if (skb_vlan_tag_present(oldskb)) {
++              u16 vid = skb_vlan_tag_get(oldskb);
++
++              __vlan_hwaccel_put_tag(nskb, oldskb->vlan_proto, vid);
++      }
+ }
+ static int nft_bridge_iphdr_validate(struct sk_buff *skb)
diff --git a/queue-5.6/nexthop-expand-nexthop_is_multipath-in-a-few-places.patch b/queue-5.6/nexthop-expand-nexthop_is_multipath-in-a-few-places.patch
new file mode 100644 (file)
index 0000000..c136abc
--- /dev/null
@@ -0,0 +1,111 @@
+From 0b5e2e39739e861fa5fc84ab27a35dbe62a15330 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Tue, 26 May 2020 12:56:16 -0600
+Subject: nexthop: Expand nexthop_is_multipath in a few places
+
+From: David Ahern <dsahern@gmail.com>
+
+commit 0b5e2e39739e861fa5fc84ab27a35dbe62a15330 upstream.
+
+I got too fancy consolidating checks on multipath type. The result
+is that path lookups can access 2 different nh_grp structs as exposed
+by Nik's torture tests. Expand nexthop_is_multipath within nexthop.h to
+avoid multiple, nh_grp dereferences and make decisions based on the
+consistent struct.
+
+Only 2 places left using nexthop_is_multipath are within IPv6, both
+only check that the nexthop is a multipath for a branching decision
+which are acceptable.
+
+Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
+Signed-off-by: David Ahern <dsahern@gmail.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>
+
+---
+ include/net/nexthop.h |   41 +++++++++++++++++++++++++----------------
+ 1 file changed, 25 insertions(+), 16 deletions(-)
+
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -137,21 +137,20 @@ static inline unsigned int nexthop_num_p
+ {
+       unsigned int rc = 1;
+-      if (nexthop_is_multipath(nh)) {
++      if (nh->is_group) {
+               struct nh_group *nh_grp;
+               nh_grp = rcu_dereference_rtnl(nh->nh_grp);
+-              rc = nh_grp->num_nh;
++              if (nh_grp->mpath)
++                      rc = nh_grp->num_nh;
+       }
+       return rc;
+ }
+ static inline
+-struct nexthop *nexthop_mpath_select(const struct nexthop *nh, int nhsel)
++struct nexthop *nexthop_mpath_select(const struct nh_group *nhg, int nhsel)
+ {
+-      const struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp);
+-
+       /* for_nexthops macros in fib_semantics.c grabs a pointer to
+        * the nexthop before checking nhsel
+        */
+@@ -186,12 +185,14 @@ static inline bool nexthop_is_blackhole(
+ {
+       const struct nh_info *nhi;
+-      if (nexthop_is_multipath(nh)) {
+-              if (nexthop_num_path(nh) > 1)
+-                      return false;
+-              nh = nexthop_mpath_select(nh, 0);
+-              if (!nh)
++      if (nh->is_group) {
++              struct nh_group *nh_grp;
++
++              nh_grp = rcu_dereference_rtnl(nh->nh_grp);
++              if (nh_grp->num_nh > 1)
+                       return false;
++
++              nh = nh_grp->nh_entries[0].nh;
+       }
+       nhi = rcu_dereference_rtnl(nh->nh_info);
+@@ -217,10 +218,15 @@ struct fib_nh_common *nexthop_fib_nhc(st
+       BUILD_BUG_ON(offsetof(struct fib_nh, nh_common) != 0);
+       BUILD_BUG_ON(offsetof(struct fib6_nh, nh_common) != 0);
+-      if (nexthop_is_multipath(nh)) {
+-              nh = nexthop_mpath_select(nh, nhsel);
+-              if (!nh)
+-                      return NULL;
++      if (nh->is_group) {
++              struct nh_group *nh_grp;
++
++              nh_grp = rcu_dereference_rtnl(nh->nh_grp);
++              if (nh_grp->mpath) {
++                      nh = nexthop_mpath_select(nh_grp, nhsel);
++                      if (!nh)
++                              return NULL;
++              }
+       }
+       nhi = rcu_dereference_rtnl(nh->nh_info);
+@@ -264,8 +270,11 @@ static inline struct fib6_nh *nexthop_fi
+ {
+       struct nh_info *nhi;
+-      if (nexthop_is_multipath(nh)) {
+-              nh = nexthop_mpath_select(nh, 0);
++      if (nh->is_group) {
++              struct nh_group *nh_grp;
++
++              nh_grp = rcu_dereference_rtnl(nh->nh_grp);
++              nh = nexthop_mpath_select(nh_grp, 0);
+               if (!nh)
+                       return NULL;
+       }
diff --git a/queue-5.6/nexthops-don-t-modify-published-nexthop-groups.patch b/queue-5.6/nexthops-don-t-modify-published-nexthop-groups.patch
new file mode 100644 (file)
index 0000000..3ab13af
--- /dev/null
@@ -0,0 +1,200 @@
+From 90f33bffa382598a32cc82abfeb20adc92d041b6 Mon Sep 17 00:00:00 2001
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Tue, 26 May 2020 12:56:15 -0600
+Subject: nexthops: don't modify published nexthop groups
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+commit 90f33bffa382598a32cc82abfeb20adc92d041b6 upstream.
+
+We must avoid modifying published nexthop groups while they might be
+in use, otherwise we might see NULL ptr dereferences. In order to do
+that we allocate 2 nexthoup group structures upon nexthop creation
+and swap between them when we have to delete an entry. The reason is
+that we can't fail nexthop group removal, so we can't handle allocation
+failure thus we move the extra allocation on creation where we can
+safely fail and return ENOMEM.
+
+Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/nexthop.h |    1 
+ net/ipv4/nexthop.c    |   91 +++++++++++++++++++++++++++++++-------------------
+ 2 files changed, 59 insertions(+), 33 deletions(-)
+
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -70,6 +70,7 @@ struct nh_grp_entry {
+ };
+ struct nh_group {
++      struct nh_group         *spare; /* spare group for removals */
+       u16                     num_nh;
+       bool                    mpath;
+       bool                    has_v4;
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -63,9 +63,16 @@ static void nexthop_free_mpath(struct ne
+       int i;
+       nhg = rcu_dereference_raw(nh->nh_grp);
+-      for (i = 0; i < nhg->num_nh; ++i)
+-              WARN_ON(nhg->nh_entries[i].nh);
++      for (i = 0; i < nhg->num_nh; ++i) {
++              struct nh_grp_entry *nhge = &nhg->nh_entries[i];
++              WARN_ON(!list_empty(&nhge->nh_list));
++              nexthop_put(nhge->nh);
++      }
++
++      WARN_ON(nhg->spare == nhg);
++
++      kfree(nhg->spare);
+       kfree(nhg);
+ }
+@@ -697,46 +704,53 @@ static void nh_group_rebalance(struct nh
+ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
+                               struct nl_info *nlinfo)
+ {
++      struct nh_grp_entry *nhges, *new_nhges;
+       struct nexthop *nhp = nhge->nh_parent;
+       struct nexthop *nh = nhge->nh;
+-      struct nh_grp_entry *nhges;
+-      struct nh_group *nhg;
+-      bool found = false;
+-      int i;
++      struct nh_group *nhg, *newg;
++      int i, j;
+       WARN_ON(!nh);
+-      list_del(&nhge->nh_list);
+-
+       nhg = rtnl_dereference(nhp->nh_grp);
+-      nhges = nhg->nh_entries;
+-      for (i = 0; i < nhg->num_nh; ++i) {
+-              if (found) {
+-                      nhges[i-1].nh = nhges[i].nh;
+-                      nhges[i-1].weight = nhges[i].weight;
+-                      list_del(&nhges[i].nh_list);
+-                      list_add(&nhges[i-1].nh_list, &nhges[i-1].nh->grp_list);
+-              } else if (nhg->nh_entries[i].nh == nh) {
+-                      found = true;
+-              }
+-      }
++      newg = nhg->spare;
+-      if (WARN_ON(!found))
++      /* last entry, keep it visible and remove the parent */
++      if (nhg->num_nh == 1) {
++              remove_nexthop(net, nhp, nlinfo);
+               return;
++      }
+-      nhg->num_nh--;
+-      nhg->nh_entries[nhg->num_nh].nh = NULL;
++      newg->has_v4 = nhg->has_v4;
++      newg->mpath = nhg->mpath;
++      newg->num_nh = nhg->num_nh;
+-      nh_group_rebalance(nhg);
++      /* copy old entries to new except the one getting removed */
++      nhges = nhg->nh_entries;
++      new_nhges = newg->nh_entries;
++      for (i = 0, j = 0; i < nhg->num_nh; ++i) {
++              /* current nexthop getting removed */
++              if (nhg->nh_entries[i].nh == nh) {
++                      newg->num_nh--;
++                      continue;
++              }
+-      nexthop_put(nh);
++              list_del(&nhges[i].nh_list);
++              new_nhges[j].nh_parent = nhges[i].nh_parent;
++              new_nhges[j].nh = nhges[i].nh;
++              new_nhges[j].weight = nhges[i].weight;
++              list_add(&new_nhges[j].nh_list, &new_nhges[j].nh->grp_list);
++              j++;
++      }
++
++      nh_group_rebalance(newg);
++      rcu_assign_pointer(nhp->nh_grp, newg);
++
++      list_del(&nhge->nh_list);
++      nexthop_put(nhge->nh);
+       if (nlinfo)
+               nexthop_notify(RTM_NEWNEXTHOP, nhp, nlinfo);
+-
+-      /* if this group has no more entries then remove it */
+-      if (!nhg->num_nh)
+-              remove_nexthop(net, nhp, nlinfo);
+ }
+ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
+@@ -746,6 +760,9 @@ static void remove_nexthop_from_groups(s
+       list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list)
+               remove_nh_grp_entry(net, nhge, nlinfo);
++
++      /* make sure all see the newly published array before releasing rtnl */
++      synchronize_rcu();
+ }
+ static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo)
+@@ -759,10 +776,7 @@ static void remove_nexthop_group(struct
+               if (WARN_ON(!nhge->nh))
+                       continue;
+-              list_del(&nhge->nh_list);
+-              nexthop_put(nhge->nh);
+-              nhge->nh = NULL;
+-              nhg->num_nh--;
++              list_del_init(&nhge->nh_list);
+       }
+ }
+@@ -1085,6 +1099,7 @@ static struct nexthop *nexthop_create_gr
+ {
+       struct nlattr *grps_attr = cfg->nh_grp;
+       struct nexthop_grp *entry = nla_data(grps_attr);
++      u16 num_nh = nla_len(grps_attr) / sizeof(*entry);
+       struct nh_group *nhg;
+       struct nexthop *nh;
+       int i;
+@@ -1095,12 +1110,21 @@ static struct nexthop *nexthop_create_gr
+       nh->is_group = 1;
+-      nhg = nexthop_grp_alloc(nla_len(grps_attr) / sizeof(*entry));
++      nhg = nexthop_grp_alloc(num_nh);
+       if (!nhg) {
+               kfree(nh);
+               return ERR_PTR(-ENOMEM);
+       }
++      /* spare group used for removals */
++      nhg->spare = nexthop_grp_alloc(num_nh);
++      if (!nhg) {
++              kfree(nhg);
++              kfree(nh);
++              return NULL;
++      }
++      nhg->spare->spare = nhg;
++
+       for (i = 0; i < nhg->num_nh; ++i) {
+               struct nexthop *nhe;
+               struct nh_info *nhi;
+@@ -1132,6 +1156,7 @@ out_no_nh:
+       for (; i >= 0; --i)
+               nexthop_put(nhg->nh_entries[i].nh);
++      kfree(nhg->spare);
+       kfree(nhg);
+       kfree(nh);
diff --git a/queue-5.6/nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch b/queue-5.6/nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch
new file mode 100644 (file)
index 0000000..1f5d99f
--- /dev/null
@@ -0,0 +1,81 @@
+From ac21753a5c2c9a6a2019997481a2ac12bbde48c8 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Tue, 26 May 2020 12:56:14 -0600
+Subject: nexthops: Move code from remove_nexthop_from_groups to remove_nh_grp_entry
+
+From: David Ahern <dsahern@gmail.com>
+
+commit ac21753a5c2c9a6a2019997481a2ac12bbde48c8 upstream.
+
+Move nh_grp dereference and check for removing nexthop group due to
+all members gone into remove_nh_grp_entry.
+
+Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
+Signed-off-by: David Ahern <dsahern@gmail.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/ipv4/nexthop.c |   27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -694,17 +694,21 @@ static void nh_group_rebalance(struct nh
+       }
+ }
+-static void remove_nh_grp_entry(struct nh_grp_entry *nhge,
+-                              struct nh_group *nhg,
++static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
+                               struct nl_info *nlinfo)
+ {
++      struct nexthop *nhp = nhge->nh_parent;
+       struct nexthop *nh = nhge->nh;
+       struct nh_grp_entry *nhges;
++      struct nh_group *nhg;
+       bool found = false;
+       int i;
+       WARN_ON(!nh);
++      list_del(&nhge->nh_list);
++
++      nhg = rtnl_dereference(nhp->nh_grp);
+       nhges = nhg->nh_entries;
+       for (i = 0; i < nhg->num_nh; ++i) {
+               if (found) {
+@@ -728,7 +732,11 @@ static void remove_nh_grp_entry(struct n
+       nexthop_put(nh);
+       if (nlinfo)
+-              nexthop_notify(RTM_NEWNEXTHOP, nhge->nh_parent, nlinfo);
++              nexthop_notify(RTM_NEWNEXTHOP, nhp, nlinfo);
++
++      /* if this group has no more entries then remove it */
++      if (!nhg->num_nh)
++              remove_nexthop(net, nhp, nlinfo);
+ }
+ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
+@@ -736,17 +744,8 @@ static void remove_nexthop_from_groups(s
+ {
+       struct nh_grp_entry *nhge, *tmp;
+-      list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list) {
+-              struct nh_group *nhg;
+-
+-              list_del(&nhge->nh_list);
+-              nhg = rtnl_dereference(nhge->nh_parent->nh_grp);
+-              remove_nh_grp_entry(nhge, nhg, nlinfo);
+-
+-              /* if this group has no more entries then remove it */
+-              if (!nhg->num_nh)
+-                      remove_nexthop(net, nhge->nh_parent, nlinfo);
+-      }
++      list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list)
++              remove_nh_grp_entry(net, nhge, nlinfo);
+ }
+ static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo)
diff --git a/queue-5.6/powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch b/queue-5.6/powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch
new file mode 100644 (file)
index 0000000..12f73d9
--- /dev/null
@@ -0,0 +1,44 @@
+From d195b1d1d1196681ac4775e0361e9cca70f740c2 Mon Sep 17 00:00:00 2001
+From: Petr Mladek <pmladek@suse.com>
+Date: Wed, 27 May 2020 14:28:44 +0200
+Subject: powerpc/bpf: Enable bpf_probe_read{, str}() on powerpc again
+
+From: Petr Mladek <pmladek@suse.com>
+
+commit d195b1d1d1196681ac4775e0361e9cca70f740c2 upstream.
+
+The commit 0ebeea8ca8a4d1d453a ("bpf: Restrict bpf_probe_read{, str}() only
+to archs where they work") caused that bpf_probe_read{, str}() functions
+were not longer available on architectures where the same logical address
+might have different content in kernel and user memory mapping. These
+architectures should use probe_read_{user,kernel}_str helpers.
+
+For backward compatibility, the problematic functions are still available
+on architectures where the user and kernel address spaces are not
+overlapping. This is defined CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE.
+
+At the moment, these backward compatible functions are enabled only on x86_64,
+arm, and arm64. Let's do it also on powerpc that has the non overlapping
+address space as well.
+
+Fixes: 0ebeea8ca8a4 ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work")
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/lkml/20200527122844.19524-1-pmladek@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -125,6 +125,7 @@ config PPC
+       select ARCH_HAS_MMIOWB                  if PPC64
+       select ARCH_HAS_PHYS_TO_DMA
+       select ARCH_HAS_PMEM_API
++      select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+       select ARCH_HAS_PTE_DEVMAP              if PPC_BOOK3S_64
+       select ARCH_HAS_PTE_SPECIAL
+       select ARCH_HAS_MEMBARRIER_CALLBACKS
diff --git a/queue-5.6/qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch b/queue-5.6/qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch
new file mode 100644 (file)
index 0000000..5c3a05a
--- /dev/null
@@ -0,0 +1,45 @@
+From 15c973858903009e995b2037683de29dfe968621 Mon Sep 17 00:00:00 2001
+From: Qiushi Wu <wu000273@umn.edu>
+Date: Mon, 25 May 2020 03:24:39 -0500
+Subject: qlcnic: fix missing release in qlcnic_83xx_interrupt_test.
+
+From: Qiushi Wu <wu000273@umn.edu>
+
+commit 15c973858903009e995b2037683de29dfe968621 upstream.
+
+In function qlcnic_83xx_interrupt_test(), function
+qlcnic_83xx_diag_alloc_res() is not handled by function
+qlcnic_83xx_diag_free_res() after a call of the function
+qlcnic_alloc_mbx_args() failed. Fix this issue by adding
+a jump target "fail_mbx_args", and jump to this new target
+when qlcnic_alloc_mbx_args() failed.
+
+Fixes: b6b4316c8b2f ("qlcnic: Handle qlcnic_alloc_mbx_args() failure")
+Signed-off-by: Qiushi Wu <wu000273@umn.edu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+@@ -3651,7 +3651,7 @@ int qlcnic_83xx_interrupt_test(struct ne
+       ahw->diag_cnt = 0;
+       ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
+       if (ret)
+-              goto fail_diag_irq;
++              goto fail_mbx_args;
+       if (adapter->flags & QLCNIC_MSIX_ENABLED)
+               intrpt_id = ahw->intr_tbl[0].id;
+@@ -3681,6 +3681,8 @@ int qlcnic_83xx_interrupt_test(struct ne
+ done:
+       qlcnic_free_mbx_args(&cmd);
++
++fail_mbx_args:
+       qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
+ fail_diag_irq:
index 497b922f478e47a98c38b437e1c60427c08eb9f8..adeb5b1c9162e1e0d8aa282d7b2e74fb873ed777 100644 (file)
@@ -141,3 +141,33 @@ cfg80211-fix-debugfs-rename-crash.patch
 mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch
 x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch
 copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch
+xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch
+xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch
+xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch
+xfrm-espintcp-save-and-call-old-sk_destruct.patch
+xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch
+xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch
+xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch
+xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch
+xfrm-fix-error-in-comment.patch
+ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch
+netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch
+netfilter-ipset-fix-subcounter-update-skip.patch
+netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch
+netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch
+netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch
+esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch
+bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch
+bnxt_en-fix-firmware-message-length-endianness.patch
+ieee80211-fix-incorrect-mask-for-default-pe-duration.patch
+x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch
+xsk-add-overflow-check-for-u64-division-stored-into-u32.patch
+qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch
+crypto-chelsio-chtls-properly-set-tp-lsndtime.patch
+nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch
+nexthops-don-t-modify-published-nexthop-groups.patch
+nexthop-expand-nexthop_is_multipath-in-a-few-places.patch
+ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch
+net-dsa-declare-lockless-tx-feature-for-slave-ports.patch
+bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch
+powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch
diff --git a/queue-5.6/x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch b/queue-5.6/x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch
new file mode 100644 (file)
index 0000000..022b7db
--- /dev/null
@@ -0,0 +1,153 @@
+From 4bfe6cce133cad82cea04490c308795275857782 Mon Sep 17 00:00:00 2001
+From: Jay Lang <jaytlang@mit.edu>
+Date: Sun, 24 May 2020 12:27:39 -0400
+Subject: x86/ioperm: Prevent a memory leak when fork fails
+
+From: Jay Lang <jaytlang@mit.edu>
+
+commit 4bfe6cce133cad82cea04490c308795275857782 upstream.
+
+In the copy_process() routine called by _do_fork(), failure to allocate
+a PID (or further along in the function) will trigger an invocation to
+exit_thread(). This is done to clean up from an earlier call to
+copy_thread_tls(). Naturally, the child task is passed into exit_thread(),
+however during the process, io_bitmap_exit() nullifies the parent's
+io_bitmap rather than the child's.
+
+As copy_thread_tls() has been called ahead of the failure, the reference
+count on the calling thread's io_bitmap is incremented as we would expect.
+However, io_bitmap_exit() doesn't accept any arguments, and thus assumes
+it should trash the current thread's io_bitmap reference rather than the
+child's. This is pretty sneaky in practice, because in all instances but
+this one, exit_thread() is called with respect to the current task and
+everything works out.
+
+A determined attacker can issue an appropriate ioctl (i.e. KDENABIO) to
+get a bitmap allocated, and force a clone3() syscall to fail by passing
+in a zeroed clone_args structure. The kernel handles the erroneous struct
+and the buggy code path is followed, and even though the parent's reference
+to the io_bitmap is trashed, the child still holds a reference and thus
+the structure will never be freed.
+
+Fix this by tweaking io_bitmap_exit() and its subroutines to accept a
+task_struct argument which to operate on.
+
+Fixes: ea5f1cd7ab49 ("x86/ioperm: Remove bitmap if all permissions dropped")
+Signed-off-by: Jay Lang <jaytlang@mit.edu>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable#@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200524162742.253727-1-jaytlang@mit.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/io_bitmap.h |    4 ++--
+ arch/x86/kernel/ioport.c         |   22 +++++++++++-----------
+ arch/x86/kernel/process.c        |    4 ++--
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+--- a/arch/x86/include/asm/io_bitmap.h
++++ b/arch/x86/include/asm/io_bitmap.h
+@@ -17,7 +17,7 @@ struct task_struct;
+ #ifdef CONFIG_X86_IOPL_IOPERM
+ void io_bitmap_share(struct task_struct *tsk);
+-void io_bitmap_exit(void);
++void io_bitmap_exit(struct task_struct *tsk);
+ void native_tss_update_io_bitmap(void);
+@@ -29,7 +29,7 @@ void native_tss_update_io_bitmap(void);
+ #else
+ static inline void io_bitmap_share(struct task_struct *tsk) { }
+-static inline void io_bitmap_exit(void) { }
++static inline void io_bitmap_exit(struct task_struct *tsk) { }
+ static inline void tss_update_io_bitmap(void) { }
+ #endif
+--- a/arch/x86/kernel/ioport.c
++++ b/arch/x86/kernel/ioport.c
+@@ -32,15 +32,15 @@ void io_bitmap_share(struct task_struct
+       set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
+ }
+-static void task_update_io_bitmap(void)
++static void task_update_io_bitmap(struct task_struct *tsk)
+ {
+-      struct thread_struct *t = &current->thread;
++      struct thread_struct *t = &tsk->thread;
+       if (t->iopl_emul == 3 || t->io_bitmap) {
+               /* TSS update is handled on exit to user space */
+-              set_thread_flag(TIF_IO_BITMAP);
++              set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
+       } else {
+-              clear_thread_flag(TIF_IO_BITMAP);
++              clear_tsk_thread_flag(tsk, TIF_IO_BITMAP);
+               /* Invalidate TSS */
+               preempt_disable();
+               tss_update_io_bitmap();
+@@ -48,12 +48,12 @@ static void task_update_io_bitmap(void)
+       }
+ }
+-void io_bitmap_exit(void)
++void io_bitmap_exit(struct task_struct *tsk)
+ {
+-      struct io_bitmap *iobm = current->thread.io_bitmap;
++      struct io_bitmap *iobm = tsk->thread.io_bitmap;
+-      current->thread.io_bitmap = NULL;
+-      task_update_io_bitmap();
++      tsk->thread.io_bitmap = NULL;
++      task_update_io_bitmap(tsk);
+       if (iobm && refcount_dec_and_test(&iobm->refcnt))
+               kfree(iobm);
+ }
+@@ -101,7 +101,7 @@ long ksys_ioperm(unsigned long from, uns
+               if (!iobm)
+                       return -ENOMEM;
+               refcount_set(&iobm->refcnt, 1);
+-              io_bitmap_exit();
++              io_bitmap_exit(current);
+       }
+       /*
+@@ -133,7 +133,7 @@ long ksys_ioperm(unsigned long from, uns
+       }
+       /* All permissions dropped? */
+       if (max_long == UINT_MAX) {
+-              io_bitmap_exit();
++              io_bitmap_exit(current);
+               return 0;
+       }
+@@ -191,7 +191,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
+       }
+       t->iopl_emul = level;
+-      task_update_io_bitmap();
++      task_update_io_bitmap(current);
+       return 0;
+ }
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -97,7 +97,7 @@ int arch_dup_task_struct(struct task_str
+ }
+ /*
+- * Free current thread data structures etc..
++ * Free thread data structures etc..
+  */
+ void exit_thread(struct task_struct *tsk)
+ {
+@@ -105,7 +105,7 @@ void exit_thread(struct task_struct *tsk
+       struct fpu *fpu = &t->fpu;
+       if (test_thread_flag(TIF_IO_BITMAP))
+-              io_bitmap_exit();
++              io_bitmap_exit(tsk);
+       free_vm86(t);
diff --git a/queue-5.6/xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch b/queue-5.6/xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch
new file mode 100644 (file)
index 0000000..09eb510
--- /dev/null
@@ -0,0 +1,45 @@
+From afcaf61be9d1dbdee5ec186d1dcc67b6b692180f Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Fri, 10 Apr 2020 17:06:01 +0800
+Subject: xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit afcaf61be9d1dbdee5ec186d1dcc67b6b692180f upstream.
+
+For beet mode, when it's ipv6 inner address with nexthdrs set,
+the packet format might be:
+
+    ----------------------------------------------------
+    | outer  |     | dest |     |      |  ESP    | ESP |
+    | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
+    ----------------------------------------------------
+
+The nexthdr from ESP could be NEXTHDR_HOP(0), so it should
+continue processing the packet when nexthdr returns 0 in
+xfrm_input(). Otherwise, when ipv6 nexthdr is set, the
+packet will be dropped.
+
+I don't see any error cases that nexthdr may return 0. So
+fix it by removing the check for nexthdr == 0.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_input.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -644,7 +644,7 @@ resume:
+               dev_put(skb->dev);
+               spin_lock(&x->lock);
+-              if (nexthdr <= 0) {
++              if (nexthdr < 0) {
+                       if (nexthdr == -EBADMSG) {
+                               xfrm_audit_state_icvfail(x, skb,
+                                                        x->type->proto);
diff --git a/queue-5.6/xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch b/queue-5.6/xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch
new file mode 100644 (file)
index 0000000..4b76ddc
--- /dev/null
@@ -0,0 +1,97 @@
+From a204aef9fd77dce1efd9066ca4e44eede99cd858 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Mon, 20 Apr 2020 21:51:09 +0800
+Subject: xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit a204aef9fd77dce1efd9066ca4e44eede99cd858 upstream.
+
+An use-after-free crash can be triggered when sending big packets over
+vxlan over esp with esp offload enabled:
+
+  [] BUG: KASAN: use-after-free in ipv6_gso_pull_exthdrs.part.8+0x32c/0x4e0
+  [] Call Trace:
+  []  dump_stack+0x75/0xa0
+  []  kasan_report+0x37/0x50
+  []  ipv6_gso_pull_exthdrs.part.8+0x32c/0x4e0
+  []  ipv6_gso_segment+0x2c8/0x13c0
+  []  skb_mac_gso_segment+0x1cb/0x420
+  []  skb_udp_tunnel_segment+0x6b5/0x1c90
+  []  inet_gso_segment+0x440/0x1380
+  []  skb_mac_gso_segment+0x1cb/0x420
+  []  esp4_gso_segment+0xae8/0x1709 [esp4_offload]
+  []  inet_gso_segment+0x440/0x1380
+  []  skb_mac_gso_segment+0x1cb/0x420
+  []  __skb_gso_segment+0x2d7/0x5f0
+  []  validate_xmit_skb+0x527/0xb10
+  []  __dev_queue_xmit+0x10f8/0x2320 <---
+  []  ip_finish_output2+0xa2e/0x1b50
+  []  ip_output+0x1a8/0x2f0
+  []  xfrm_output_resume+0x110e/0x15f0
+  []  __xfrm4_output+0xe1/0x1b0
+  []  xfrm4_output+0xa0/0x200
+  []  iptunnel_xmit+0x5a7/0x920
+  []  vxlan_xmit_one+0x1658/0x37a0 [vxlan]
+  []  vxlan_xmit+0x5e4/0x3ec8 [vxlan]
+  []  dev_hard_start_xmit+0x125/0x540
+  []  __dev_queue_xmit+0x17bd/0x2320  <---
+  []  ip6_finish_output2+0xb20/0x1b80
+  []  ip6_output+0x1b3/0x390
+  []  ip6_xmit+0xb82/0x17e0
+  []  inet6_csk_xmit+0x225/0x3d0
+  []  __tcp_transmit_skb+0x1763/0x3520
+  []  tcp_write_xmit+0xd64/0x5fe0
+  []  __tcp_push_pending_frames+0x8c/0x320
+  []  tcp_sendmsg_locked+0x2245/0x3500
+  []  tcp_sendmsg+0x27/0x40
+
+As on the tx path of vxlan over esp, skb->inner_network_header would be
+set on vxlan_xmit() and xfrm4_tunnel_encap_add(), and the later one can
+overwrite the former one. It causes skb_udp_tunnel_segment() to use a
+wrong skb->inner_network_header, then the issue occurs.
+
+This patch is to fix it by calling xfrm_output_gso() instead when the
+inner_protocol is set, in which gso_segment of inner_protocol will be
+done first.
+
+While at it, also improve some code around.
+
+Fixes: 7862b4058b9f ("esp: Add gso handlers for esp4 and esp6")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_output.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -583,18 +583,20 @@ int xfrm_output(struct sock *sk, struct
+               xfrm_state_hold(x);
+               if (skb_is_gso(skb)) {
+-                      skb_shinfo(skb)->gso_type |= SKB_GSO_ESP;
++                      if (skb->inner_protocol)
++                              return xfrm_output_gso(net, sk, skb);
+-                      return xfrm_output2(net, sk, skb);
++                      skb_shinfo(skb)->gso_type |= SKB_GSO_ESP;
++                      goto out;
+               }
+               if (x->xso.dev && x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)
+                       goto out;
++      } else {
++              if (skb_is_gso(skb))
++                      return xfrm_output_gso(net, sk, skb);
+       }
+-      if (skb_is_gso(skb))
+-              return xfrm_output_gso(net, sk, skb);
+-
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               err = skb_checksum_help(skb);
+               if (err) {
diff --git a/queue-5.6/xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch b/queue-5.6/xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch
new file mode 100644 (file)
index 0000000..2ce31e4
--- /dev/null
@@ -0,0 +1,77 @@
+From 06a0afcfe2f551ff755849ea2549b0d8409fd9a0 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Fri, 10 Apr 2020 17:06:31 +0800
+Subject: xfrm: do pskb_pull properly in __xfrm_transport_prep
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 06a0afcfe2f551ff755849ea2549b0d8409fd9a0 upstream.
+
+For transport mode, when ipv6 nexthdr is set, the packet format might
+be like:
+
+    ----------------------------------------------------
+    |        | dest |     |     |      |  ESP    | ESP |
+    | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
+    ----------------------------------------------------
+
+and in __xfrm_transport_prep():
+
+  pskb_pull(skb, skb->mac_len + sizeof(ip6hdr) + x->props.header_len);
+
+it will pull the data pointer to the wrong position, as it missed the
+nexthdrs/dest opts.
+
+This patch is to fix it by using:
+
+  pskb_pull(skb, skb_transport_offset(skb) + x->props.header_len);
+
+as we can be sure transport_header points to ESP header at that moment.
+
+It also fixes a panic when packets with ipv6 nexthdr are sent over
+esp6 transport mode:
+
+  [  100.473845] kernel BUG at net/core/skbuff.c:4325!
+  [  100.478517] RIP: 0010:__skb_to_sgvec+0x252/0x260
+  [  100.494355] Call Trace:
+  [  100.494829]  skb_to_sgvec+0x11/0x40
+  [  100.495492]  esp6_output_tail+0x12e/0x550 [esp6]
+  [  100.496358]  esp6_xmit+0x1d5/0x260 [esp6_offload]
+  [  100.498029]  validate_xmit_xfrm+0x22f/0x2e0
+  [  100.499604]  __dev_queue_xmit+0x589/0x910
+  [  100.502928]  ip6_finish_output2+0x2a5/0x5a0
+  [  100.503718]  ip6_output+0x6c/0x120
+  [  100.505198]  xfrm_output_resume+0x4bf/0x530
+  [  100.508683]  xfrm6_output+0x3a/0xc0
+  [  100.513446]  inet6_csk_xmit+0xa1/0xf0
+  [  100.517335]  tcp_sendmsg+0x27/0x40
+  [  100.517977]  sock_sendmsg+0x3e/0x60
+  [  100.518648]  __sys_sendto+0xee/0x160
+
+Fixes: c35fe4106b92 ("xfrm: Add mode handlers for IPsec on layer 2")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_device.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -25,12 +25,10 @@ static void __xfrm_transport_prep(struct
+       struct xfrm_offload *xo = xfrm_offload(skb);
+       skb_reset_mac_len(skb);
+-      pskb_pull(skb, skb->mac_len + hsize + x->props.header_len);
+-
+-      if (xo->flags & XFRM_GSO_SEGMENT) {
+-              skb_reset_transport_header(skb);
++      if (xo->flags & XFRM_GSO_SEGMENT)
+               skb->transport_header -= x->props.header_len;
+-      }
++
++      pskb_pull(skb, skb_transport_offset(skb) + x->props.header_len);
+ }
+ static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb,
diff --git a/queue-5.6/xfrm-espintcp-save-and-call-old-sk_destruct.patch b/queue-5.6/xfrm-espintcp-save-and-call-old-sk_destruct.patch
new file mode 100644 (file)
index 0000000..7576fdf
--- /dev/null
@@ -0,0 +1,52 @@
+From 9f0cadc32d738f0f0c8e30be83be7087c7b85ee5 Mon Sep 17 00:00:00 2001
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Thu, 16 Apr 2020 17:45:44 +0200
+Subject: xfrm: espintcp: save and call old ->sk_destruct
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+commit 9f0cadc32d738f0f0c8e30be83be7087c7b85ee5 upstream.
+
+When ESP encapsulation is enabled on a TCP socket, I'm replacing the
+existing ->sk_destruct callback with espintcp_destruct. We still need to
+call the old callback to perform the other cleanups when the socket is
+destroyed. Save the old callback, and call it from espintcp_destruct.
+
+Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/espintcp.h |    1 +
+ net/xfrm/espintcp.c    |    2 ++
+ 2 files changed, 3 insertions(+)
+
+--- a/include/net/espintcp.h
++++ b/include/net/espintcp.h
+@@ -25,6 +25,7 @@ struct espintcp_ctx {
+       struct espintcp_msg partial;
+       void (*saved_data_ready)(struct sock *sk);
+       void (*saved_write_space)(struct sock *sk);
++      void (*saved_destruct)(struct sock *sk);
+       struct work_struct work;
+       bool tx_running;
+ };
+--- a/net/xfrm/espintcp.c
++++ b/net/xfrm/espintcp.c
+@@ -379,6 +379,7 @@ static void espintcp_destruct(struct soc
+ {
+       struct espintcp_ctx *ctx = espintcp_getctx(sk);
++      ctx->saved_destruct(sk);
+       kfree(ctx);
+ }
+@@ -419,6 +420,7 @@ static int espintcp_init_sk(struct sock
+       sk->sk_socket->ops = &espintcp_ops;
+       ctx->saved_data_ready = sk->sk_data_ready;
+       ctx->saved_write_space = sk->sk_write_space;
++      ctx->saved_destruct = sk->sk_destruct;
+       sk->sk_data_ready = espintcp_data_ready;
+       sk->sk_write_space = espintcp_write_space;
+       sk->sk_destruct = espintcp_destruct;
diff --git a/queue-5.6/xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch b/queue-5.6/xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch
new file mode 100644 (file)
index 0000000..6f61586
--- /dev/null
@@ -0,0 +1,65 @@
+From f6a23d85d078c2ffde79c66ca81d0a1dde451649 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Tue, 26 May 2020 17:41:46 +0800
+Subject: xfrm: fix a NULL-ptr deref in xfrm_local_error
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit f6a23d85d078c2ffde79c66ca81d0a1dde451649 upstream.
+
+This patch is to fix a crash:
+
+  [ ] kasan: GPF could be caused by NULL-ptr deref or user memory access
+  [ ] general protection fault: 0000 [#1] SMP KASAN PTI
+  [ ] RIP: 0010:ipv6_local_error+0xac/0x7a0
+  [ ] Call Trace:
+  [ ]  xfrm6_local_error+0x1eb/0x300
+  [ ]  xfrm_local_error+0x95/0x130
+  [ ]  __xfrm6_output+0x65f/0xb50
+  [ ]  xfrm6_output+0x106/0x46f
+  [ ]  udp_tunnel6_xmit_skb+0x618/0xbf0 [ip6_udp_tunnel]
+  [ ]  vxlan_xmit_one+0xbc6/0x2c60 [vxlan]
+  [ ]  vxlan_xmit+0x6a0/0x4276 [vxlan]
+  [ ]  dev_hard_start_xmit+0x165/0x820
+  [ ]  __dev_queue_xmit+0x1ff0/0x2b90
+  [ ]  ip_finish_output2+0xd3e/0x1480
+  [ ]  ip_do_fragment+0x182d/0x2210
+  [ ]  ip_output+0x1d0/0x510
+  [ ]  ip_send_skb+0x37/0xa0
+  [ ]  raw_sendmsg+0x1b4c/0x2b80
+  [ ]  sock_sendmsg+0xc0/0x110
+
+This occurred when sending a v4 skb over vxlan6 over ipsec, in which case
+skb->protocol == htons(ETH_P_IPV6) while skb->sk->sk_family == AF_INET in
+xfrm_local_error(). Then it will go to xfrm6_local_error() where it tries
+to get ipv6 info from a ipv4 sk.
+
+This issue was actually fixed by Commit 628e341f319f ("xfrm: make local
+error reporting more robust"), but brought back by Commit 844d48746e4b
+("xfrm: choose protocol family by skb protocol").
+
+So to fix it, we should call xfrm6_local_error() only when skb->protocol
+is htons(ETH_P_IPV6) and skb->sk->sk_family is AF_INET6.
+
+Fixes: 844d48746e4b ("xfrm: choose protocol family by skb protocol")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_output.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -642,7 +642,8 @@ void xfrm_local_error(struct sk_buff *sk
+       if (skb->protocol == htons(ETH_P_IP))
+               proto = AF_INET;
+-      else if (skb->protocol == htons(ETH_P_IPV6))
++      else if (skb->protocol == htons(ETH_P_IPV6) &&
++               skb->sk->sk_family == AF_INET6)
+               proto = AF_INET6;
+       else
+               return;
diff --git a/queue-5.6/xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch b/queue-5.6/xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch
new file mode 100644 (file)
index 0000000..e29fd4a
--- /dev/null
@@ -0,0 +1,76 @@
+From ed17b8d377eaf6b4a01d46942b4c647378a79bdd Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Mon, 25 May 2020 13:53:37 +0800
+Subject: xfrm: fix a warning in xfrm_policy_insert_list
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit ed17b8d377eaf6b4a01d46942b4c647378a79bdd upstream.
+
+This waring can be triggered simply by:
+
+  # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
+    priority 1 mark 0 mask 0x10  #[1]
+  # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
+    priority 2 mark 0 mask 0x1   #[2]
+  # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
+    priority 2 mark 0 mask 0x10  #[3]
+
+Then dmesg shows:
+
+  [ ] WARNING: CPU: 1 PID: 7265 at net/xfrm/xfrm_policy.c:1548
+  [ ] RIP: 0010:xfrm_policy_insert_list+0x2f2/0x1030
+  [ ] Call Trace:
+  [ ]  xfrm_policy_inexact_insert+0x85/0xe50
+  [ ]  xfrm_policy_insert+0x4ba/0x680
+  [ ]  xfrm_add_policy+0x246/0x4d0
+  [ ]  xfrm_user_rcv_msg+0x331/0x5c0
+  [ ]  netlink_rcv_skb+0x121/0x350
+  [ ]  xfrm_netlink_rcv+0x66/0x80
+  [ ]  netlink_unicast+0x439/0x630
+  [ ]  netlink_sendmsg+0x714/0xbf0
+  [ ]  sock_sendmsg+0xe2/0x110
+
+The issue was introduced by Commit 7cb8a93968e3 ("xfrm: Allow inserting
+policies with matching mark and different priorities"). After that, the
+policies [1] and [2] would be able to be added with different priorities.
+
+However, policy [3] will actually match both [1] and [2]. Policy [1]
+was matched due to the 1st 'return true' in xfrm_policy_mark_match(),
+and policy [2] was matched due to the 2nd 'return true' in there. It
+caused WARN_ON() in xfrm_policy_insert_list().
+
+This patch is to fix it by only (the same value and priority) as the
+same policy in xfrm_policy_mark_match().
+
+Thanks to Yuehaibing, we could make this fix better.
+
+v1->v2:
+  - check policy->mark.v == pol->mark.v only without mask.
+
+Fixes: 7cb8a93968e3 ("xfrm: Allow inserting policies with matching mark and different priorities")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_policy.c |    7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1436,12 +1436,7 @@ static void xfrm_policy_requeue(struct x
+ static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
+                                  struct xfrm_policy *pol)
+ {
+-      u32 mark = policy->mark.v & policy->mark.m;
+-
+-      if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
+-              return true;
+-
+-      if ((mark & pol->mark.m) == pol->mark.v &&
++      if (policy->mark.v == pol->mark.v &&
+           policy->priority == pol->priority)
+               return true;
diff --git a/queue-5.6/xfrm-fix-error-in-comment.patch b/queue-5.6/xfrm-fix-error-in-comment.patch
new file mode 100644 (file)
index 0000000..2c408ba
--- /dev/null
@@ -0,0 +1,31 @@
+From 29e4276667e24ee6b91d9f91064d8fda9a210ea1 Mon Sep 17 00:00:00 2001
+From: Antony Antony <antony@phenome.org>
+Date: Wed, 15 Apr 2020 21:47:10 +0200
+Subject: xfrm: fix error in comment
+
+From: Antony Antony <antony@phenome.org>
+
+commit 29e4276667e24ee6b91d9f91064d8fda9a210ea1 upstream.
+
+s/xfrm_state_offload/xfrm_user_offload/
+
+Fixes: d77e38e612a ("xfrm: Add an IPsec hardware offloading API")
+Signed-off-by: Antony Antony <antony@phenome.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/uapi/linux/xfrm.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/xfrm.h
++++ b/include/uapi/linux/xfrm.h
+@@ -304,7 +304,7 @@ enum xfrm_attr_type_t {
+       XFRMA_PROTO,            /* __u8 */
+       XFRMA_ADDRESS_FILTER,   /* struct xfrm_address_filter */
+       XFRMA_PAD,
+-      XFRMA_OFFLOAD_DEV,      /* struct xfrm_state_offload */
++      XFRMA_OFFLOAD_DEV,      /* struct xfrm_user_offload */
+       XFRMA_SET_MARK,         /* __u32 */
+       XFRMA_SET_MARK_MASK,    /* __u32 */
+       XFRMA_IF_ID,            /* __u32 */
diff --git a/queue-5.6/xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch b/queue-5.6/xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch
new file mode 100644 (file)
index 0000000..d1d78b6
--- /dev/null
@@ -0,0 +1,98 @@
+From c95c5f58b35ef995f66cb55547eee6093ab5fcb8 Mon Sep 17 00:00:00 2001
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Thu, 23 Apr 2020 00:06:45 +0200
+Subject: xfrm interface: fix oops when deleting a x-netns interface
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+commit c95c5f58b35ef995f66cb55547eee6093ab5fcb8 upstream.
+
+Here is the steps to reproduce the problem:
+ip netns add foo
+ip netns add bar
+ip -n foo link add xfrmi0 type xfrm dev lo if_id 42
+ip -n foo link set xfrmi0 netns bar
+ip netns del foo
+ip netns del bar
+
+Which results to:
+[  186.686395] general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6bd3: 0000 [#1] SMP PTI
+[  186.687665] CPU: 7 PID: 232 Comm: kworker/u16:2 Not tainted 5.6.0+ #1
+[  186.688430] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+[  186.689420] Workqueue: netns cleanup_net
+[  186.689903] RIP: 0010:xfrmi_dev_uninit+0x1b/0x4b [xfrm_interface]
+[  186.690657] Code: 44 f6 ff ff 31 c0 5b 5d 41 5c 41 5d 41 5e c3 48 8d 8f c0 08 00 00 8b 05 ce 14 00 00 48 8b 97 d0 08 00 00 48 8b 92 c0 0e 00 00 <48> 8b 14 c2 48 8b 02 48 85 c0 74 19 48 39 c1 75 0c 48 8b 87 c0 08
+[  186.692838] RSP: 0018:ffffc900003b7d68 EFLAGS: 00010286
+[  186.693435] RAX: 000000000000000d RBX: ffff8881b0f31000 RCX: ffff8881b0f318c0
+[  186.694334] RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000246 RDI: ffff8881b0f31000
+[  186.695190] RBP: ffffc900003b7df0 R08: ffff888236c07740 R09: 0000000000000040
+[  186.696024] R10: ffffffff81fce1b8 R11: 0000000000000002 R12: ffffc900003b7d80
+[  186.696859] R13: ffff8881edcc6a40 R14: ffff8881a1b6e780 R15: ffffffff81ed47c8
+[  186.697738] FS:  0000000000000000(0000) GS:ffff888237dc0000(0000) knlGS:0000000000000000
+[  186.698705] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  186.699408] CR2: 00007f2129e93148 CR3: 0000000001e0a000 CR4: 00000000000006e0
+[  186.700221] Call Trace:
+[  186.700508]  rollback_registered_many+0x32b/0x3fd
+[  186.701058]  ? __rtnl_unlock+0x20/0x3d
+[  186.701494]  ? arch_local_irq_save+0x11/0x17
+[  186.702012]  unregister_netdevice_many+0x12/0x55
+[  186.702594]  default_device_exit_batch+0x12b/0x150
+[  186.703160]  ? prepare_to_wait_exclusive+0x60/0x60
+[  186.703719]  cleanup_net+0x17d/0x234
+[  186.704138]  process_one_work+0x196/0x2e8
+[  186.704652]  worker_thread+0x1a4/0x249
+[  186.705087]  ? cancel_delayed_work+0x92/0x92
+[  186.705620]  kthread+0x105/0x10f
+[  186.706000]  ? __kthread_bind_mask+0x57/0x57
+[  186.706501]  ret_from_fork+0x35/0x40
+[  186.706978] Modules linked in: xfrm_interface nfsv3 nfs_acl auth_rpcgss nfsv4 nfs lockd grace fscache sunrpc button parport_pc parport serio_raw evdev pcspkr loop ext4 crc16 mbcache jbd2 crc32c_generic 8139too ide_cd_mod cdrom ide_gd_mod ata_generic ata_piix libata scsi_mod piix psmouse i2c_piix4 ide_core 8139cp i2c_core mii floppy
+[  186.710423] ---[ end trace 463bba18105537e5 ]---
+
+The problem is that x-netns xfrm interface are not removed when the link
+netns is removed. This causes later this oops when thoses interfaces are
+removed.
+
+Let's add a handler to remove all interfaces related to a netns when this
+netns is removed.
+
+Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces")
+Reported-by: Christophe Gouault <christophe.gouault@6wind.com>
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_interface.c |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/net/xfrm/xfrm_interface.c
++++ b/net/xfrm/xfrm_interface.c
+@@ -750,7 +750,28 @@ static struct rtnl_link_ops xfrmi_link_o
+       .get_link_net   = xfrmi_get_link_net,
+ };
++static void __net_exit xfrmi_exit_batch_net(struct list_head *net_exit_list)
++{
++      struct net *net;
++      LIST_HEAD(list);
++
++      rtnl_lock();
++      list_for_each_entry(net, net_exit_list, exit_list) {
++              struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
++              struct xfrm_if __rcu **xip;
++              struct xfrm_if *xi;
++
++              for (xip = &xfrmn->xfrmi[0];
++                   (xi = rtnl_dereference(*xip)) != NULL;
++                   xip = &xi->next)
++                      unregister_netdevice_queue(xi->dev, &list);
++      }
++      unregister_netdevice_many(&list);
++      rtnl_unlock();
++}
++
+ static struct pernet_operations xfrmi_net_ops = {
++      .exit_batch = xfrmi_exit_batch_net,
+       .id   = &xfrmi_net_id,
+       .size = sizeof(struct xfrmi_net),
+ };
diff --git a/queue-5.6/xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch b/queue-5.6/xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch
new file mode 100644 (file)
index 0000000..4183925
--- /dev/null
@@ -0,0 +1,53 @@
+From db87668ad1e4917cfe04e217307ba6ed9390716e Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Fri, 10 Apr 2020 17:08:24 +0800
+Subject: xfrm: remove the xfrm_state_put call becofe going to out_reset
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit db87668ad1e4917cfe04e217307ba6ed9390716e upstream.
+
+This xfrm_state_put call in esp4/6_gro_receive() will cause
+double put for state, as in out_reset path secpath_reset()
+will put all states set in skb sec_path.
+
+So fix it by simply remove the xfrm_state_put call.
+
+Fixes: 6ed69184ed9c ("xfrm: Reset secpath in xfrm failure")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/esp4_offload.c |    4 +---
+ net/ipv6/esp6_offload.c |    4 +---
+ 2 files changed, 2 insertions(+), 6 deletions(-)
+
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -63,10 +63,8 @@ static struct sk_buff *esp4_gro_receive(
+               sp->olen++;
+               xo = xfrm_offload(skb);
+-              if (!xo) {
+-                      xfrm_state_put(x);
++              if (!xo)
+                       goto out_reset;
+-              }
+       }
+       xo->flags |= XFRM_GRO;
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -85,10 +85,8 @@ static struct sk_buff *esp6_gro_receive(
+               sp->olen++;
+               xo = xfrm_offload(skb);
+-              if (!xo) {
+-                      xfrm_state_put(x);
++              if (!xo)
+                       goto out_reset;
+-              }
+       }
+       xo->flags |= XFRM_GRO;
diff --git a/queue-5.6/xsk-add-overflow-check-for-u64-division-stored-into-u32.patch b/queue-5.6/xsk-add-overflow-check-for-u64-division-stored-into-u32.patch
new file mode 100644 (file)
index 0000000..83ce1ba
--- /dev/null
@@ -0,0 +1,70 @@
+From b16a87d0aef7a6be766f6618976dc5ff2c689291 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= <bjorn.topel@intel.com>
+Date: Mon, 25 May 2020 10:03:59 +0200
+Subject: xsk: Add overflow check for u64 division, stored into u32
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn.topel@intel.com>
+
+commit b16a87d0aef7a6be766f6618976dc5ff2c689291 upstream.
+
+The npgs member of struct xdp_umem is an u32 entity, and stores the
+number of pages the UMEM consumes. The calculation of npgs
+
+  npgs = size / PAGE_SIZE
+
+can overflow.
+
+To avoid overflow scenarios, the division is now first stored in a
+u64, and the result is verified to fit into 32b.
+
+An alternative would be storing the npgs as a u64, however, this
+wastes memory and is an unrealisticly large packet area.
+
+Fixes: c0c77d8fb787 ("xsk: add user memory registration support sockopt")
+Reported-by: "Minh Bùi Quang" <minhquangbui99@gmail.com>
+Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jonathan Lemon <jonathan.lemon@gmail.com>
+Link: https://lore.kernel.org/bpf/CACtPs=GGvV-_Yj6rbpzTVnopgi5nhMoCcTkSkYrJHGQHJWFZMQ@mail.gmail.com/
+Link: https://lore.kernel.org/bpf/20200525080400.13195-1-bjorn.topel@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xdp/xdp_umem.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/xdp/xdp_umem.c
++++ b/net/xdp/xdp_umem.c
+@@ -341,8 +341,8 @@ static int xdp_umem_reg(struct xdp_umem
+ {
+       bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
+       u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
++      u64 npgs, addr = mr->addr, size = mr->len;
+       unsigned int chunks, chunks_per_page;
+-      u64 addr = mr->addr, size = mr->len;
+       int err;
+       if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
+@@ -372,6 +372,10 @@ static int xdp_umem_reg(struct xdp_umem
+       if ((addr + size) < addr)
+               return -EINVAL;
++      npgs = div_u64(size, PAGE_SIZE);
++      if (npgs > U32_MAX)
++              return -EINVAL;
++
+       chunks = (unsigned int)div_u64(size, chunk_size);
+       if (chunks == 0)
+               return -EINVAL;
+@@ -391,7 +395,7 @@ static int xdp_umem_reg(struct xdp_umem
+       umem->size = size;
+       umem->headroom = headroom;
+       umem->chunk_size_nohr = chunk_size - headroom;
+-      umem->npgs = size / PAGE_SIZE;
++      umem->npgs = (u32)npgs;
+       umem->pgs = NULL;
+       umem->user = NULL;
+       umem->flags = mr->flags;