From: Greg Kroah-Hartman Date: Mon, 1 Mar 2021 15:12:55 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.259~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5b03863bd010558f9ebd4e52be67f79a92d190e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: gtp-use-icmp_ndo_send-helper.patch icmp-introduce-helper-for-nat-d-source-address-in-network-device-context.patch sunvnet-use-icmp_ndo_send-helper.patch xfrm-interface-use-icmp_ndo_send-helper.patch --- diff --git a/queue-5.4/gtp-use-icmp_ndo_send-helper.patch b/queue-5.4/gtp-use-icmp_ndo_send-helper.patch new file mode 100644 index 00000000000..cebc93eed3f --- /dev/null +++ b/queue-5.4/gtp-use-icmp_ndo_send-helper.patch @@ -0,0 +1,33 @@ +From e0fce6f945a26d4e953a147fe7ca11410322c9fe Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Tue, 11 Feb 2020 20:47:06 +0100 +Subject: gtp: use icmp_ndo_send helper + +From: Jason A. Donenfeld + +commit e0fce6f945a26d4e953a147fe7ca11410322c9fe upstream. + +Because gtp is calling icmp from network device context, it should use +the ndo helper so that the rate limiting applies correctly. + +Signed-off-by: Jason A. Donenfeld +Cc: Harald Welte +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/gtp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -546,8 +546,8 @@ static int gtp_build_skb_ip4(struct sk_b + mtu < ntohs(iph->tot_len)) { + netdev_dbg(dev, "packet too big, fragmentation needed\n"); + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, +- htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(mtu)); + goto err_rt; + } + diff --git a/queue-5.4/icmp-introduce-helper-for-nat-d-source-address-in-network-device-context.patch b/queue-5.4/icmp-introduce-helper-for-nat-d-source-address-in-network-device-context.patch new file mode 100644 index 00000000000..7049d8a3154 --- /dev/null +++ b/queue-5.4/icmp-introduce-helper-for-nat-d-source-address-in-network-device-context.patch @@ -0,0 +1,139 @@ +From 0b41713b606694257b90d61ba7e2712d8457648b Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Tue, 11 Feb 2020 20:47:05 +0100 +Subject: icmp: introduce helper for nat'd source address in network device context + +From: Jason A. Donenfeld + +commit 0b41713b606694257b90d61ba7e2712d8457648b upstream. + +This introduces a helper function to be called only by network drivers +that wraps calls to icmp[v6]_send in a conntrack transformation, in case +NAT has been used. We don't want to pollute the non-driver path, though, +so we introduce this as a helper to be called by places that actually +make use of this, as suggested by Florian. + +Signed-off-by: Jason A. Donenfeld +Cc: Florian Westphal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/icmpv6.h | 6 ++++++ + include/net/icmp.h | 6 ++++++ + net/ipv4/icmp.c | 33 +++++++++++++++++++++++++++++++++ + net/ipv6/ip6_icmp.c | 34 ++++++++++++++++++++++++++++++++++ + 4 files changed, 79 insertions(+) + +--- a/include/linux/icmpv6.h ++++ b/include/linux/icmpv6.h +@@ -31,6 +31,12 @@ static inline void icmpv6_send(struct sk + } + #endif + ++#if IS_ENABLED(CONFIG_NF_NAT) ++void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info); ++#else ++#define icmpv6_ndo_send icmpv6_send ++#endif ++ + extern int icmpv6_init(void); + extern int icmpv6_err_convert(u8 type, u8 code, + int *err); +--- a/include/net/icmp.h ++++ b/include/net/icmp.h +@@ -43,6 +43,12 @@ static inline void icmp_send(struct sk_b + __icmp_send(skb_in, type, code, info, &IPCB(skb_in)->opt); + } + ++#if IS_ENABLED(CONFIG_NF_NAT) ++void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info); ++#else ++#define icmp_ndo_send icmp_send ++#endif ++ + int icmp_rcv(struct sk_buff *skb); + int icmp_err(struct sk_buff *skb, u32 info); + int icmp_init(void); +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -750,6 +750,39 @@ out:; + } + EXPORT_SYMBOL(__icmp_send); + ++#if IS_ENABLED(CONFIG_NF_NAT) ++#include ++void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info) ++{ ++ struct sk_buff *cloned_skb = NULL; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *ct; ++ __be32 orig_ip; ++ ++ ct = nf_ct_get(skb_in, &ctinfo); ++ if (!ct || !(ct->status & IPS_SRC_NAT)) { ++ icmp_send(skb_in, type, code, info); ++ return; ++ } ++ ++ if (skb_shared(skb_in)) ++ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC); ++ ++ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head || ++ (skb_network_header(skb_in) + sizeof(struct iphdr)) > ++ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in, ++ skb_network_offset(skb_in) + sizeof(struct iphdr)))) ++ goto out; ++ ++ orig_ip = ip_hdr(skb_in)->saddr; ++ ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip; ++ icmp_send(skb_in, type, code, info); ++ ip_hdr(skb_in)->saddr = orig_ip; ++out: ++ consume_skb(cloned_skb); ++} ++EXPORT_SYMBOL(icmp_ndo_send); ++#endif + + static void icmp_socket_deliver(struct sk_buff *skb, u32 info) + { +--- a/net/ipv6/ip6_icmp.c ++++ b/net/ipv6/ip6_icmp.c +@@ -45,4 +45,38 @@ out: + rcu_read_unlock(); + } + EXPORT_SYMBOL(icmpv6_send); ++ ++#if IS_ENABLED(CONFIG_NF_NAT) ++#include ++void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info) ++{ ++ struct sk_buff *cloned_skb = NULL; ++ enum ip_conntrack_info ctinfo; ++ struct in6_addr orig_ip; ++ struct nf_conn *ct; ++ ++ ct = nf_ct_get(skb_in, &ctinfo); ++ if (!ct || !(ct->status & IPS_SRC_NAT)) { ++ icmpv6_send(skb_in, type, code, info); ++ return; ++ } ++ ++ if (skb_shared(skb_in)) ++ skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC); ++ ++ if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head || ++ (skb_network_header(skb_in) + sizeof(struct ipv6hdr)) > ++ skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in, ++ skb_network_offset(skb_in) + sizeof(struct ipv6hdr)))) ++ goto out; ++ ++ orig_ip = ipv6_hdr(skb_in)->saddr; ++ ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6; ++ icmpv6_send(skb_in, type, code, info); ++ ipv6_hdr(skb_in)->saddr = orig_ip; ++out: ++ consume_skb(cloned_skb); ++} ++EXPORT_SYMBOL(icmpv6_ndo_send); ++#endif + #endif diff --git a/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch b/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch index 56c61b6193a..1aa7e53792a 100644 --- a/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch +++ b/queue-5.4/ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch @@ -18,8 +18,8 @@ Signed-off-by: Greg Kroah-Hartman --- include/linux/icmpv6.h | 22 +++++++++++++++++++++- net/ipv6/icmp.c | 5 +++-- - net/ipv6/ip6_icmp.c | 9 +++++---- - 3 files changed, 29 insertions(+), 7 deletions(-) + net/ipv6/ip6_icmp.c | 10 +++++----- + 3 files changed, 29 insertions(+), 8 deletions(-) --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -89,10 +89,11 @@ Signed-off-by: Greg Kroah-Hartman static ip6_icmp_send_t __rcu *ip6_icmp_send; int inet6_register_icmp_sender(ip6_icmp_send_t *fn) -@@ -38,11 +40,10 @@ void icmpv6_send(struct sk_buff *skb, u8 +@@ -37,14 +39,12 @@ void icmpv6_send(struct sk_buff *skb, u8 + rcu_read_lock(); send = rcu_dereference(ip6_icmp_send); - +- - if (!send) - goto out; - send(skb, type, code, info, NULL); @@ -102,5 +103,7 @@ Signed-off-by: Greg Kroah-Hartman rcu_read_unlock(); } EXPORT_SYMBOL(icmpv6_send); - #endif +#endif + + #if IS_ENABLED(CONFIG_NF_NAT) + #include diff --git a/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch b/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch index 969f87ec7f6..f26c4a35ed0 100644 --- a/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch +++ b/queue-5.4/net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch @@ -82,11 +82,13 @@ Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/gtp.c | 1 - - include/linux/icmpv6.h | 20 +++++++++++++++----- + include/linux/icmpv6.h | 26 ++++++++++++++++++++------ include/linux/ipv6.h | 1 - + include/net/icmp.h | 6 +++++- + net/ipv4/icmp.c | 5 +++-- net/ipv6/icmp.c | 16 ++++++++-------- - net/ipv6/ip6_icmp.c | 7 ++++--- - 5 files changed, 27 insertions(+), 18 deletions(-) + net/ipv6/ip6_icmp.c | 12 +++++++----- + 7 files changed, 43 insertions(+), 24 deletions(-) --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -95,8 +97,8 @@ Signed-off-by: Greg Kroah-Hartman mtu < ntohs(iph->tot_len)) { netdev_dbg(dev, "packet too big, fragmentation needed\n"); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); goto err_rt; --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -148,6 +150,19 @@ Signed-off-by: Greg Kroah-Hartman int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type, unsigned int data_len); +@@ -54,7 +64,11 @@ static inline void icmpv6_send(struct sk + #if IS_ENABLED(CONFIG_NF_NAT) + void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info); + #else +-#define icmpv6_ndo_send icmpv6_send ++static inline void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info) ++{ ++ struct inet6_skb_parm parm = { 0 }; ++ __icmpv6_send(skb_in, type, code, info, &parm); ++} + #endif + + extern int icmpv6_init(void); --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -83,7 +83,6 @@ struct ipv6_params { @@ -158,6 +173,48 @@ Signed-off-by: Greg Kroah-Hartman #include #include +--- a/include/net/icmp.h ++++ b/include/net/icmp.h +@@ -46,7 +46,11 @@ static inline void icmp_send(struct sk_b + #if IS_ENABLED(CONFIG_NF_NAT) + void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info); + #else +-#define icmp_ndo_send icmp_send ++static inline void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info) ++{ ++ struct ip_options opts = { 0 }; ++ __icmp_send(skb_in, type, code, info, &opts); ++} + #endif + + int icmp_rcv(struct sk_buff *skb); +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -755,13 +755,14 @@ EXPORT_SYMBOL(__icmp_send); + void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info) + { + struct sk_buff *cloned_skb = NULL; ++ struct ip_options opts = { 0 }; + enum ip_conntrack_info ctinfo; + struct nf_conn *ct; + __be32 orig_ip; + + ct = nf_ct_get(skb_in, &ctinfo); + if (!ct || !(ct->status & IPS_SRC_NAT)) { +- icmp_send(skb_in, type, code, info); ++ __icmp_send(skb_in, type, code, info, &opts); + return; + } + +@@ -776,7 +777,7 @@ void icmp_ndo_send(struct sk_buff *skb_i + + orig_ip = ip_hdr(skb_in)->saddr; + ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip; +- icmp_send(skb_in, type, code, info); ++ __icmp_send(skb_in, type, code, info, &opts); + ip_hdr(skb_in)->saddr = orig_ip; + out: + consume_skb(cloned_skb); --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -312,10 +312,9 @@ static int icmpv6_getfrag(void *from, ch @@ -224,7 +281,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/net/ipv6/ip6_icmp.c +++ b/net/ipv6/ip6_icmp.c -@@ -33,7 +33,8 @@ int inet6_unregister_icmp_sender(ip6_icm +@@ -33,23 +33,25 @@ int inet6_unregister_icmp_sender(ip6_icm } EXPORT_SYMBOL(inet6_unregister_icmp_sender); @@ -234,9 +291,8 @@ Signed-off-by: Greg Kroah-Hartman { ip6_icmp_send_t *send; -@@ -41,9 +42,9 @@ void icmpv6_send(struct sk_buff *skb, u8 + rcu_read_lock(); send = rcu_dereference(ip6_icmp_send); - if (send) - send(skb, type, code, info, NULL); + send(skb, type, code, info, NULL, parm); @@ -245,4 +301,30 @@ Signed-off-by: Greg Kroah-Hartman -EXPORT_SYMBOL(icmpv6_send); +EXPORT_SYMBOL(__icmpv6_send); #endif - #endif + + #if IS_ENABLED(CONFIG_NF_NAT) + #include + void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info) + { ++ struct inet6_skb_parm parm = { 0 }; + struct sk_buff *cloned_skb = NULL; + enum ip_conntrack_info ctinfo; + struct in6_addr orig_ip; +@@ -57,7 +59,7 @@ void icmpv6_ndo_send(struct sk_buff *skb + + ct = nf_ct_get(skb_in, &ctinfo); + if (!ct || !(ct->status & IPS_SRC_NAT)) { +- icmpv6_send(skb_in, type, code, info); ++ __icmpv6_send(skb_in, type, code, info, &parm); + return; + } + +@@ -72,7 +74,7 @@ void icmpv6_ndo_send(struct sk_buff *skb + + orig_ip = ipv6_hdr(skb_in)->saddr; + ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6; +- icmpv6_send(skb_in, type, code, info); ++ __icmpv6_send(skb_in, type, code, info, &parm); + ipv6_hdr(skb_in)->saddr = orig_ip; + out: + consume_skb(cloned_skb); diff --git a/queue-5.4/series b/queue-5.4/series index 4df8f4301ac..4491618a1b6 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -328,6 +328,10 @@ dm-era-use-correct-value-size-in-equality-function-of-writeset-tree.patch dm-era-reinitialize-bitset-cache-before-digesting-a-new-writeset.patch dm-era-only-resize-metadata-in-preresume.patch drm-i915-reject-446-480mhz-hdmi-clock-on-glk.patch +icmp-introduce-helper-for-nat-d-source-address-in-network-device-context.patch +gtp-use-icmp_ndo_send-helper.patch +sunvnet-use-icmp_ndo_send-helper.patch +xfrm-interface-use-icmp_ndo_send-helper.patch ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch ipv6-silence-compilation-warning-for-non-ipv6-builds.patch net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch diff --git a/queue-5.4/sunvnet-use-icmp_ndo_send-helper.patch b/queue-5.4/sunvnet-use-icmp_ndo_send-helper.patch new file mode 100644 index 00000000000..c5b9d7c7550 --- /dev/null +++ b/queue-5.4/sunvnet-use-icmp_ndo_send-helper.patch @@ -0,0 +1,56 @@ +From 67c9a7e1e3ac491b5df018803639addc36f154ba Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Tue, 11 Feb 2020 20:47:07 +0100 +Subject: sunvnet: use icmp_ndo_send helper + +From: Jason A. Donenfeld + +commit 67c9a7e1e3ac491b5df018803639addc36f154ba upstream. + +Because sunvnet is calling icmp from network device context, it should use +the ndo helper so that the rate limiting applies correctly. While we're +at it, doing the additional route lookup before calling icmp_ndo_send is +superfluous, since this is the job of the icmp code in the first place. + +Signed-off-by: Jason A. Donenfeld +Cc: Shannon Nelson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sun/sunvnet_common.c | 23 ++++------------------- + 1 file changed, 4 insertions(+), 19 deletions(-) + +--- a/drivers/net/ethernet/sun/sunvnet_common.c ++++ b/drivers/net/ethernet/sun/sunvnet_common.c +@@ -1353,27 +1353,12 @@ sunvnet_start_xmit_common(struct sk_buff + if (vio_version_after_eq(&port->vio, 1, 3)) + localmtu -= VLAN_HLEN; + +- if (skb->protocol == htons(ETH_P_IP)) { +- struct flowi4 fl4; +- struct rtable *rt = NULL; +- +- memset(&fl4, 0, sizeof(fl4)); +- fl4.flowi4_oif = dev->ifindex; +- fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); +- fl4.daddr = ip_hdr(skb)->daddr; +- fl4.saddr = ip_hdr(skb)->saddr; +- +- rt = ip_route_output_key(dev_net(dev), &fl4); +- if (!IS_ERR(rt)) { +- skb_dst_set(skb, &rt->dst); +- icmp_send(skb, ICMP_DEST_UNREACH, +- ICMP_FRAG_NEEDED, +- htonl(localmtu)); +- } +- } ++ if (skb->protocol == htons(ETH_P_IP)) ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(localmtu)); + #if IS_ENABLED(CONFIG_IPV6) + else if (skb->protocol == htons(ETH_P_IPV6)) +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu); + #endif + goto out_dropped; + } diff --git a/queue-5.4/xfrm-interface-use-icmp_ndo_send-helper.patch b/queue-5.4/xfrm-interface-use-icmp_ndo_send-helper.patch new file mode 100644 index 00000000000..57d84b0424c --- /dev/null +++ b/queue-5.4/xfrm-interface-use-icmp_ndo_send-helper.patch @@ -0,0 +1,37 @@ +From 45942ba890e6f35232727a5fa33d732681f4eb9f Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Tue, 11 Feb 2020 20:47:09 +0100 +Subject: xfrm: interface: use icmp_ndo_send helper + +From: Jason A. Donenfeld + +commit 45942ba890e6f35232727a5fa33d732681f4eb9f upstream. + +Because xfrmi is calling icmp from network device context, it should use +the ndo helper so that the rate limiting applies correctly. + +Signed-off-by: Jason A. Donenfeld +Cc: Nicolas Dichtel +Cc: Steffen Klassert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_interface.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/xfrm/xfrm_interface.c ++++ b/net/xfrm/xfrm_interface.c +@@ -300,10 +300,10 @@ xfrmi_xmit2(struct sk_buff *skb, struct + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + +- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ++ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + } else { +- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, +- htonl(mtu)); ++ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, ++ htonl(mtu)); + } + + dst_release(dst);