From: Greg Kroah-Hartman Date: Mon, 1 Jun 2020 12:09:48 +0000 (+0200) Subject: 5.6-stable patches X-Git-Tag: v4.4.226~34 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9ef9a9eec0e63de3b2dcefb9faf7b0af84b0f5d;p=thirdparty%2Fkernel%2Fstable-queue.git 5.6-stable patches 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 --- 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 index 00000000000..dcfb57f6b57 --- /dev/null +++ b/queue-5.6/bnxt_en-fix-accumulation-of-bp-net_stats_prev.patch @@ -0,0 +1,41 @@ +From b8056e8434b037fdab08158fea99ed7bc8ef3a74 Mon Sep 17 00:00:00 2001 +From: Michael Chan +Date: Mon, 25 May 2020 17:41:17 -0400 +Subject: bnxt_en: Fix accumulation of bp->net_stats_prev. + +From: Michael Chan + +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 +Fixes: b8875ca356f1 ("bnxt_en: Save ring statistics before reset.") +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c5149eb0089 --- /dev/null +++ b/queue-5.6/bnxt_en-fix-firmware-message-length-endianness.patch @@ -0,0 +1,105 @@ +From 2a5a8800fa915bd9bc272c91ca64728e6aa84c0a Mon Sep 17 00:00:00 2001 +From: Edwin Peer +Date: Mon, 25 May 2020 17:41:19 -0400 +Subject: bnxt_en: fix firmware message length endianness + +From: Edwin Peer + +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 +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..442d95f48de --- /dev/null +++ b/queue-5.6/bonding-fix-reference-count-leak-in-bond_sysfs_slave_add.patch @@ -0,0 +1,38 @@ +From a068aab42258e25094bc2c159948d263ed7d7a77 Mon Sep 17 00:00:00 2001 +From: Qiushi Wu +Date: Wed, 27 May 2020 22:10:29 -0500 +Subject: bonding: Fix reference count leak in bond_sysfs_slave_add. + +From: Qiushi Wu + +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 +Acked-by: Jay Vosburgh +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3685c4c1ad4 --- /dev/null +++ b/queue-5.6/crypto-chelsio-chtls-properly-set-tp-lsndtime.patch @@ -0,0 +1,33 @@ +From a4976a3ef844c510ae9120290b23e9f3f47d6bce Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 26 May 2020 17:28:56 -0700 +Subject: crypto: chelsio/chtls: properly set tp->lsndtime + +From: Eric Dumazet + +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 +Cc: Ayush Sawal +Cc: Vinay Kumar Yadav +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..83607c17461 --- /dev/null +++ b/queue-5.6/esp6-get-the-right-proto-for-transport-mode-in-esp6_gso_encap.patch @@ -0,0 +1,54 @@ +From 3c96ec56828922e3fe5477f75eb3fc02f98f98b5 Mon Sep 17 00:00:00 2001 +From: Xin Long +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 + +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0be37ec5286 --- /dev/null +++ b/queue-5.6/ieee80211-fix-incorrect-mask-for-default-pe-duration.patch @@ -0,0 +1,32 @@ +From d031781bdabe1027858a3220f868866586bf6e7c Mon Sep 17 00:00:00 2001 +From: Pradeep Kumar Chitrapu +Date: Wed, 6 May 2020 03:24:30 -0700 +Subject: ieee80211: Fix incorrect mask for default PE duration + +From: Pradeep Kumar Chitrapu + +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 +Link: https://lore.kernel.org/r/20200506102430.5153-1-pradeepc@codeaurora.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a15270e5b20 --- /dev/null +++ b/queue-5.6/ip_vti-receive-ipip-packet-by-calling-ip_tunnel_rcv.patch @@ -0,0 +1,65 @@ +From 976eba8ab596bab94b9714cd46d38d5c6a2c660d Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Tue, 21 Apr 2020 20:46:11 +0800 +Subject: ip_vti: receive ipip packet by calling ip_tunnel_rcv + +From: Xin Long + +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 +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1baec112f94 --- /dev/null +++ b/queue-5.6/ipv4-nexthop-version-of-fib_info_nh_uses_dev.patch @@ -0,0 +1,110 @@ +From 1fd1c768f3624a5e66766e7b4ddb9b607cd834a5 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Tue, 26 May 2020 12:56:18 -0600 +Subject: ipv4: nexthop version of fib_info_nh_uses_dev + +From: David Ahern + +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 +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0ff3c958d2f --- /dev/null +++ b/queue-5.6/net-dsa-declare-lockless-tx-feature-for-slave-ports.patch @@ -0,0 +1,174 @@ +From 2b86cb8299765688c5119fd18d5f436716c81010 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Wed, 27 May 2020 21:08:05 +0300 +Subject: net: dsa: declare lockless TX feature for slave ports + +From: Vladimir Oltean + +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 +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..995a9eb7486 --- /dev/null +++ b/queue-5.6/netfilter-conntrack-make-conntrack-userspace-helpers-work-again.patch @@ -0,0 +1,145 @@ +From ee04805ff54a63ffd90bc6749ebfe73473734ddb Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Sun, 24 May 2020 19:52:10 +0200 +Subject: netfilter: conntrack: make conntrack userspace helpers work again + +From: Pablo Neira Ayuso + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a4eef26ce5d --- /dev/null +++ b/queue-5.6/netfilter-ipset-fix-subcounter-update-skip.patch @@ -0,0 +1,33 @@ +From a164b95ad6055c50612795882f35e0efda1f1390 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 14 May 2020 13:31:21 +0200 +Subject: netfilter: ipset: Fix subcounter update skip + +From: Phil Sutter + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a95a51b3251 --- /dev/null +++ b/queue-5.6/netfilter-nf_conntrack_pptp-prevent-buffer-overflows-in-debug-code.patch @@ -0,0 +1,201 @@ +From 4c559f15efcc43b996f4da528cd7f9483aaca36d Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Thu, 14 May 2020 14:14:23 +0200 +Subject: netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code + +From: Pablo Neira Ayuso + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + +-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 index 00000000000..c668a13340f --- /dev/null +++ b/queue-5.6/netfilter-nfnetlink_cthelper-unbreak-userspace-helper-support.patch @@ -0,0 +1,40 @@ +From 703acd70f2496537457186211c2f03e792409e68 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Sun, 24 May 2020 21:04:42 +0200 +Subject: netfilter: nfnetlink_cthelper: unbreak userspace helper support + +From: Pablo Neira Ayuso + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0df6252ce64 --- /dev/null +++ b/queue-5.6/netfilter-nft_reject_bridge-enable-reject-with-bridge-vlan.patch @@ -0,0 +1,38 @@ +From e9c284ec4b41c827f4369973d2792992849e4fa5 Mon Sep 17 00:00:00 2001 +From: Michael Braun +Date: Wed, 6 May 2020 11:46:25 +0200 +Subject: netfilter: nft_reject_bridge: enable reject with bridge vlan + +From: Michael Braun + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c136abceefd --- /dev/null +++ b/queue-5.6/nexthop-expand-nexthop_is_multipath-in-a-few-places.patch @@ -0,0 +1,111 @@ +From 0b5e2e39739e861fa5fc84ab27a35dbe62a15330 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Tue, 26 May 2020 12:56:16 -0600 +Subject: nexthop: Expand nexthop_is_multipath in a few places + +From: David Ahern + +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 +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3ab13afed2b --- /dev/null +++ b/queue-5.6/nexthops-don-t-modify-published-nexthop-groups.patch @@ -0,0 +1,200 @@ +From 90f33bffa382598a32cc82abfeb20adc92d041b6 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Tue, 26 May 2020 12:56:15 -0600 +Subject: nexthops: don't modify published nexthop groups + +From: Nikolay Aleksandrov + +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 +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1f5d99f5a4b --- /dev/null +++ b/queue-5.6/nexthops-move-code-from-remove_nexthop_from_groups-to-remove_nh_grp_entry.patch @@ -0,0 +1,81 @@ +From ac21753a5c2c9a6a2019997481a2ac12bbde48c8 Mon Sep 17 00:00:00 2001 +From: David Ahern +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 + +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 +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..12f73d92a07 --- /dev/null +++ b/queue-5.6/powerpc-bpf-enable-bpf_probe_read-str-on-powerpc-again.patch @@ -0,0 +1,44 @@ +From d195b1d1d1196681ac4775e0361e9cca70f740c2 Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Wed, 27 May 2020 14:28:44 +0200 +Subject: powerpc/bpf: Enable bpf_probe_read{, str}() on powerpc again + +From: Petr Mladek + +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 +Signed-off-by: Daniel Borkmann +Acked-by: Michael Ellerman +Link: https://lore.kernel.org/lkml/20200527122844.19524-1-pmladek@suse.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5c3a05ada9f --- /dev/null +++ b/queue-5.6/qlcnic-fix-missing-release-in-qlcnic_83xx_interrupt_test.patch @@ -0,0 +1,45 @@ +From 15c973858903009e995b2037683de29dfe968621 Mon Sep 17 00:00:00 2001 +From: Qiushi Wu +Date: Mon, 25 May 2020 03:24:39 -0500 +Subject: qlcnic: fix missing release in qlcnic_83xx_interrupt_test. + +From: Qiushi Wu + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-5.6/series b/queue-5.6/series index 497b922f478..adeb5b1c916 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -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 index 00000000000..022b7db278d --- /dev/null +++ b/queue-5.6/x86-ioperm-prevent-a-memory-leak-when-fork-fails.patch @@ -0,0 +1,153 @@ +From 4bfe6cce133cad82cea04490c308795275857782 Mon Sep 17 00:00:00 2001 +From: Jay Lang +Date: Sun, 24 May 2020 12:27:39 -0400 +Subject: x86/ioperm: Prevent a memory leak when fork fails + +From: Jay Lang + +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 +Signed-off-by: Thomas Gleixner +Cc: stable#@vger.kernel.org +Link: https://lkml.kernel.org/r/20200524162742.253727-1-jaytlang@mit.edu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = ¤t->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 index 00000000000..09eb510e412 --- /dev/null +++ b/queue-5.6/xfrm-allow-to-accept-packets-with-ipv6-nexthdr_hop-in-xfrm_input.patch @@ -0,0 +1,45 @@ +From afcaf61be9d1dbdee5ec186d1dcc67b6b692180f Mon Sep 17 00:00:00 2001 +From: Xin Long +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 + +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4b76ddcfb9d --- /dev/null +++ b/queue-5.6/xfrm-call-xfrm_output_gso-when-inner_protocol-is-set-in-xfrm_output.patch @@ -0,0 +1,97 @@ +From a204aef9fd77dce1efd9066ca4e44eede99cd858 Mon Sep 17 00:00:00 2001 +From: Xin Long +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 + +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 +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2ce31e44bbb --- /dev/null +++ b/queue-5.6/xfrm-do-pskb_pull-properly-in-__xfrm_transport_prep.patch @@ -0,0 +1,77 @@ +From 06a0afcfe2f551ff755849ea2549b0d8409fd9a0 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Fri, 10 Apr 2020 17:06:31 +0800 +Subject: xfrm: do pskb_pull properly in __xfrm_transport_prep + +From: Xin Long + +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7576fdfdbb7 --- /dev/null +++ b/queue-5.6/xfrm-espintcp-save-and-call-old-sk_destruct.patch @@ -0,0 +1,52 @@ +From 9f0cadc32d738f0f0c8e30be83be7087c7b85ee5 Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Thu, 16 Apr 2020 17:45:44 +0200 +Subject: xfrm: espintcp: save and call old ->sk_destruct + +From: Sabrina Dubroca + +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..6f615865e88 --- /dev/null +++ b/queue-5.6/xfrm-fix-a-null-ptr-deref-in-xfrm_local_error.patch @@ -0,0 +1,65 @@ +From f6a23d85d078c2ffde79c66ca81d0a1dde451649 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Tue, 26 May 2020 17:41:46 +0800 +Subject: xfrm: fix a NULL-ptr deref in xfrm_local_error + +From: Xin Long + +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 +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e29fd4afaed --- /dev/null +++ b/queue-5.6/xfrm-fix-a-warning-in-xfrm_policy_insert_list.patch @@ -0,0 +1,76 @@ +From ed17b8d377eaf6b4a01d46942b4c647378a79bdd Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Mon, 25 May 2020 13:53:37 +0800 +Subject: xfrm: fix a warning in xfrm_policy_insert_list + +From: Xin Long + +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 +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2c408ba91e3 --- /dev/null +++ b/queue-5.6/xfrm-fix-error-in-comment.patch @@ -0,0 +1,31 @@ +From 29e4276667e24ee6b91d9f91064d8fda9a210ea1 Mon Sep 17 00:00:00 2001 +From: Antony Antony +Date: Wed, 15 Apr 2020 21:47:10 +0200 +Subject: xfrm: fix error in comment + +From: Antony Antony + +commit 29e4276667e24ee6b91d9f91064d8fda9a210ea1 upstream. + +s/xfrm_state_offload/xfrm_user_offload/ + +Fixes: d77e38e612a ("xfrm: Add an IPsec hardware offloading API") +Signed-off-by: Antony Antony +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d1d78b66fee --- /dev/null +++ b/queue-5.6/xfrm-interface-fix-oops-when-deleting-a-x-netns-interface.patch @@ -0,0 +1,98 @@ +From c95c5f58b35ef995f66cb55547eee6093ab5fcb8 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Thu, 23 Apr 2020 00:06:45 +0200 +Subject: xfrm interface: fix oops when deleting a x-netns interface + +From: Nicolas Dichtel + +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 +Signed-off-by: Nicolas Dichtel +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4183925f4ae --- /dev/null +++ b/queue-5.6/xfrm-remove-the-xfrm_state_put-call-becofe-going-to-out_reset.patch @@ -0,0 +1,53 @@ +From db87668ad1e4917cfe04e217307ba6ed9390716e Mon Sep 17 00:00:00 2001 +From: Xin Long +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 + +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..83ce1ba3873 --- /dev/null +++ b/queue-5.6/xsk-add-overflow-check-for-u64-division-stored-into-u32.patch @@ -0,0 +1,70 @@ +From b16a87d0aef7a6be766f6618976dc5ff2c689291 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= +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 + +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" +Signed-off-by: Björn Töpel +Signed-off-by: Daniel Borkmann +Acked-by: Jonathan Lemon +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 + +--- + 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;