From: Greg Kroah-Hartman Date: Fri, 15 Jan 2021 09:15:12 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.252~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9822184e14a5bfd6d9eaaba880eb5728ba6a5fe7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch net-fix-pmtu-check-in-nopmtudisc-mode.patch net-ip-always-refragment-ip-defragmented-packets.patch net-vlan-avoid-leaks-on-register_vlan_dev-failures.patch --- diff --git a/queue-4.14/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch b/queue-4.14/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch new file mode 100644 index 00000000000..2b32d124471 --- /dev/null +++ b/queue-4.14/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch @@ -0,0 +1,85 @@ +From foo@baz Fri Jan 15 09:53:35 AM CET 2021 +From: "Jouni K. Seppänen" +Date: Tue, 5 Jan 2021 06:52:49 +0200 +Subject: net: cdc_ncm: correct overhead in delayed_ndp_size + +From: "Jouni K. Seppänen" + +[ Upstream commit 7a68d725e4ea384977445e0bcaed3d7de83ab5b3 ] + +Aligning to tx_ndp_modulus is not sufficient because the next align +call can be cdc_ncm_align_tail, which can add up to ctx->tx_modulus + +ctx->tx_remainder - 1 bytes. This used to lead to occasional crashes +on a Huawei 909s-120 LTE module as follows: + +- the condition marked /* if there is a remaining skb [...] */ is true + so the swaps happen +- skb_out is set from ctx->tx_curr_skb +- skb_out->len is exactly 0x3f52 +- ctx->tx_curr_size is 0x4000 and delayed_ndp_size is 0xac + (note that the sum of skb_out->len and delayed_ndp_size is 0x3ffe) +- the for loop over n is executed once +- the cdc_ncm_align_tail call marked /* align beginning of next frame */ + increases skb_out->len to 0x3f56 (the sum is now 0x4002) +- the condition marked /* check if we had enough room left [...] */ is + false so we break out of the loop +- the condition marked /* If requested, put NDP at end of frame. */ is + true so the NDP is written into skb_out +- now skb_out->len is 0x4002, so padding_count is minus two interpreted + as an unsigned number, which is used as the length argument to memset, + leading to a crash with various symptoms but usually including + +> Call Trace: +> +> cdc_ncm_fill_tx_frame+0x83a/0x970 [cdc_ncm] +> cdc_mbim_tx_fixup+0x1d9/0x240 [cdc_mbim] +> usbnet_start_xmit+0x5d/0x720 [usbnet] + +The cdc_ncm_align_tail call first aligns on a ctx->tx_modulus +boundary (adding at most ctx->tx_modulus-1 bytes), then adds +ctx->tx_remainder bytes. Alternatively, the next alignment call can +occur in cdc_ncm_ndp16 or cdc_ncm_ndp32, in which case at most +ctx->tx_ndp_modulus-1 bytes are added. + +A similar problem has occurred before, and the code is nontrivial to +reason about, so add a guard before the crashing call. By that time it +is too late to prevent any memory corruption (we'll have written past +the end of the buffer already) but we can at least try to get a warning +written into an on-disk log by avoiding the hard crash caused by padding +past the buffer with a huge number of zeros. + +Signed-off-by: Jouni K. Seppänen +Fixes: 4a0e3e989d66 ("cdc_ncm: Add support for moving NDP to end of NCM frame") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=209407 +Reported-by: kernel test robot +Reviewed-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_ncm.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1128,7 +1128,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev + * accordingly. Otherwise, we should check here. + */ + if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) +- delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus); ++ delayed_ndp_size = ctx->max_ndp_size + ++ max_t(u32, ++ ctx->tx_ndp_modulus, ++ ctx->tx_modulus + ctx->tx_remainder) - 1; + else + delayed_ndp_size = 0; + +@@ -1309,7 +1312,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev + if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && + skb_out->len > ctx->min_tx_pkt) { + padding_count = ctx->tx_curr_size - skb_out->len; +- skb_put_zero(skb_out, padding_count); ++ if (!WARN_ON(padding_count > ctx->tx_curr_size)) ++ skb_put_zero(skb_out, padding_count); + } else if (skb_out->len < ctx->tx_curr_size && + (skb_out->len % dev->maxpacket) == 0) { + skb_put_u8(skb_out, 0); /* force short packet */ diff --git a/queue-4.14/net-fix-pmtu-check-in-nopmtudisc-mode.patch b/queue-4.14/net-fix-pmtu-check-in-nopmtudisc-mode.patch new file mode 100644 index 00000000000..5d417c28243 --- /dev/null +++ b/queue-4.14/net-fix-pmtu-check-in-nopmtudisc-mode.patch @@ -0,0 +1,61 @@ +From foo@baz Fri Jan 15 09:43:29 AM CET 2021 +From: Florian Westphal +Date: Wed, 6 Jan 2021 00:15:22 +0100 +Subject: net: fix pmtu check in nopmtudisc mode + +From: Florian Westphal + +[ Upstream commit 50c661670f6a3908c273503dfa206dfc7aa54c07 ] + +For some reason ip_tunnel insist on setting the DF bit anyway when the +inner header has the DF bit set, EVEN if the tunnel was configured with +'nopmtudisc'. + +This means that the script added in the previous commit +cannot be made to work by adding the 'nopmtudisc' flag to the +ip tunnel configuration. Doing so breaks connectivity even for the +without-conntrack/netfilter scenario. + +When nopmtudisc is set, the tunnel will skip the mtu check, so no +icmp error is sent to client. Then, because inner header has DF set, +the outer header gets added with DF bit set as well. + +IP stack then sends an error to itself because the packet exceeds +the device MTU. + +Fixes: 23a3647bc4f93 ("ip_tunnels: Use skb-len to PMTU check.") +Cc: Stefano Brivio +Signed-off-by: Florian Westphal +Acked-by: Pablo Neira Ayuso +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_tunnel.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -752,7 +752,11 @@ void ip_tunnel_xmit(struct sk_buff *skb, + goto tx_error; + } + +- if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) { ++ df = tnl_params->frag_off; ++ if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) ++ df |= (inner_iph->frag_off & htons(IP_DF)); ++ ++ if (tnl_update_pmtu(dev, skb, rt, df, inner_iph)) { + ip_rt_put(rt); + goto tx_error; + } +@@ -780,10 +784,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, + ttl = ip4_dst_hoplimit(&rt->dst); + } + +- df = tnl_params->frag_off; +- if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) +- df |= (inner_iph->frag_off&htons(IP_DF)); +- + max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); + if (max_headroom > dev->needed_headroom) diff --git a/queue-4.14/net-ip-always-refragment-ip-defragmented-packets.patch b/queue-4.14/net-ip-always-refragment-ip-defragmented-packets.patch new file mode 100644 index 00000000000..a53dbc88f50 --- /dev/null +++ b/queue-4.14/net-ip-always-refragment-ip-defragmented-packets.patch @@ -0,0 +1,67 @@ +From foo@baz Fri Jan 15 09:53:35 AM CET 2021 +From: Florian Westphal +Date: Wed, 6 Jan 2021 00:15:23 +0100 +Subject: net: ip: always refragment ip defragmented packets + +From: Florian Westphal + +[ Upstream commit bb4cc1a18856a73f0ff5137df0c2a31f4c50f6cf ] + +Conntrack reassembly records the largest fragment size seen in IPCB. +However, when this gets forwarded/transmitted, fragmentation will only +be forced if one of the fragmented packets had the DF bit set. + +In that case, a flag in IPCB will force fragmentation even if the +MTU is large enough. + +This should work fine, but this breaks with ip tunnels. +Consider client that sends a UDP datagram of size X to another host. + +The client fragments the datagram, so two packets, of size y and z, are +sent. DF bit is not set on any of these packets. + +Middlebox netfilter reassembles those packets back to single size-X +packet, before routing decision. + +packet-size-vs-mtu checks in ip_forward are irrelevant, because DF bit +isn't set. At output time, ip refragmentation is skipped as well +because x is still smaller than the mtu of the output device. + +If ttransmit device is an ip tunnel, the packet size increases to +x+overhead. + +Also, tunnel might be configured to force DF bit on outer header. + +In this case, packet will be dropped (exceeds MTU) and an ICMP error is +generated back to sender. + +But sender already respects the announced MTU, all the packets that +it sent did fit the announced mtu. + +Force refragmentation as per original sizes unconditionally so ip tunnel +will encapsulate the fragments instead. + +The only other solution I see is to place ip refragmentation in +the ip_tunnel code to handle this case. + +Fixes: d6b915e29f4ad ("ip_fragment: don't forward defragmented DF packet") +Reported-by: Christian Perle +Signed-off-by: Florian Westphal +Acked-by: Pablo Neira Ayuso +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -312,7 +312,7 @@ static int ip_finish_output(struct net * + if (skb_is_gso(skb)) + return ip_finish_output_gso(net, sk, skb, mtu); + +- if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU)) ++ if (skb->len > mtu || IPCB(skb)->frag_max_size) + return ip_fragment(net, sk, skb, mtu, ip_finish_output2); + + return ip_finish_output2(net, sk, skb); diff --git a/queue-4.14/net-vlan-avoid-leaks-on-register_vlan_dev-failures.patch b/queue-4.14/net-vlan-avoid-leaks-on-register_vlan_dev-failures.patch new file mode 100644 index 00000000000..22f9122eabc --- /dev/null +++ b/queue-4.14/net-vlan-avoid-leaks-on-register_vlan_dev-failures.patch @@ -0,0 +1,39 @@ +From foo@baz Fri Jan 15 09:53:35 AM CET 2021 +From: Jakub Kicinski +Date: Wed, 30 Dec 2020 19:40:27 -0800 +Subject: net: vlan: avoid leaks on register_vlan_dev() failures + +From: Jakub Kicinski + +[ Upstream commit 55b7ab1178cbf41f979ff83236d3321ad35ed2ad ] + +VLAN checks for NETREG_UNINITIALIZED to distinguish between +registration failure and unregistration in progress. + +Since commit cb626bf566eb ("net-sysfs: Fix reference count leak") +registration failure may, however, result in NETREG_UNREGISTERED +as well as NETREG_UNINITIALIZED. + +This fix is similer to cebb69754f37 ("rtnetlink: Fix +memory(net_device) leak when ->newlink fails") + +Fixes: cb626bf566eb ("net-sysfs: Fix reference count leak") +Signed-off-by: Jakub Kicinski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/8021q/vlan.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -272,7 +272,8 @@ static int register_vlan_device(struct n + return 0; + + out_free_newdev: +- if (new_dev->reg_state == NETREG_UNINITIALIZED) ++ if (new_dev->reg_state == NETREG_UNINITIALIZED || ++ new_dev->reg_state == NETREG_UNREGISTERED) + free_netdev(new_dev); + return err; + } diff --git a/queue-4.14/series b/queue-4.14/series index 0c79c70bd8d..d73947e9600 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1 +1,5 @@ powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__s.patch +net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch +net-vlan-avoid-leaks-on-register_vlan_dev-failures.patch +net-ip-always-refragment-ip-defragmented-packets.patch +net-fix-pmtu-check-in-nopmtudisc-mode.patch