linux/net/ipv4
Michal Kubeček ef09c9ff34 net: account for current skb length when deciding about UFO
[ Upstream commit a5cb659bbc ]

Our customer encountered stuck NFS writes for blocks starting at specific
offsets w.r.t. page boundary caused by networking stack sending packets via
UFO enabled device with wrong checksum. The problem can be reproduced by
composing a long UDP datagram from multiple parts using MSG_MORE flag:

  sendto(sd, buff, 1000, MSG_MORE, ...);
  sendto(sd, buff, 1000, MSG_MORE, ...);
  sendto(sd, buff, 3000, 0, ...);

Assume this packet is to be routed via a device with MTU 1500 and
NETIF_F_UFO enabled. When second sendto() gets into __ip_append_data(),
this condition is tested (among others) to decide whether to call
ip_ufo_append_data():

  ((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))

At the moment, we already have skb with 1028 bytes of data which is not
marked for GSO so that the test is false (fragheaderlen is usually 20).
Thus we append second 1000 bytes to this skb without invoking UFO. Third
sendto(), however, has sufficient length to trigger the UFO path so that we
end up with non-UFO skb followed by a UFO one. Later on, udp_send_skb()
uses udp_csum() to calculate the checksum but that assumes all fragments
have correct checksum in skb->csum which is not true for UFO fragments.

When checking against MTU, we need to add skb->len to length of new segment
if we already have a partially filled skb and fragheaderlen only if there
isn't one.

In the IPv6 case, skb can only be null if this is the first segment so that
we have to use headersize (length of the first IPv6 header) rather than
fragheaderlen (length of IPv6 header of further fragments) for skb == NULL.

Fixes: e89e9cf539 ("[IPv4/IPv6]: UFO Scatter-gather approach")
Fixes: e4c5e13aa4 ("ipv6: Should use consistent conditional judgement for
	ip6 fragment between __ip6_append_data and ip6_finish_output")
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Acked-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2017-08-11 08:49:37 -07:00
..
netfilter netfilter: use fwmark_reflect in nf_send_reset 2017-08-11 08:49:35 -07:00
af_inet.c net: ping: do not abuse udp_poll() 2017-06-14 15:05:52 +02:00
ah4.c ah4: Fix error return in ah_input(). 2015-08-25 13:38:50 -07:00
arp.c NET: Fix /proc/net/arp for AX.25 2017-06-17 06:41:50 +02:00
cipso_ipv4.c netlabel: out of bound access in cipso_v4_validate() 2017-02-18 15:11:41 +01:00
datagram.c net: Set sk_txhash from a random number 2015-07-29 22:44:04 -07:00
devinet.c netconf: add a notif when settings are created 2016-09-01 15:18:08 -07:00
esp4.c esp4: Fix integrity verification when ESN are used 2016-11-30 11:09:39 +01:00
fib_frontend.c ipv4: initialize fib_trie prior to register_netdev_notifier call. 2017-08-11 08:49:32 -07:00
fib_lookup.h ipv4: consider TOS in fib_select_default 2015-07-24 22:46:11 -07:00
fib_rules.c switchdev: remove FIB offload infrastructure 2016-09-28 04:48:00 -04:00
fib_semantics.c ipv4: add reference counting to metrics 2017-06-07 12:07:46 +02:00
fib_trie.c net: Improve handling of failures on link and route dumps 2017-06-07 12:07:44 +02:00
fou.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
gre_demux.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-06-30 05:03:36 -04:00
gre_offload.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
icmp.c net: icmp_route_lookup should use rt dev to determine L3 domain 2016-11-09 18:49:39 -05:00
igmp.c igmp: add a missing spin_lock_init() 2017-07-05 14:40:15 +02:00
inet_connection_sock.c dccp/tcp: do not inherit mc_list from parent 2017-06-07 12:07:42 +02:00
inet_diag.c net: inet: diag: expose the socket mark to privileged processes. 2016-09-08 16:13:09 -07:00
inet_fragment.c net: disable fragment reassembly if high_thresh is zero 2016-06-05 22:56:42 -04:00
inet_hashtables.c net: Require exact match for TCP socket lookups if dif is l3mdev 2016-10-17 10:17:05 -04:00
inet_timewait_sock.c timers, net/ipv4/inet: Initialize connection request timers as pinned 2016-07-07 10:35:06 +02:00
inetpeer.c net: Add helper function to compare inetpeer addresses 2015-08-28 13:32:36 -07:00
ip_forward.c ipv4: allow local fragmentation in ip_finish_output_gso() 2016-11-03 16:10:26 -04:00
ip_fragment.c net: rename IP_INC_STATS_BH() 2016-04-27 22:48:23 -04:00
ip_gre.c net/ip_tunnels: Introduce tunnel_id_to_key32() and key32_to_tunnel_id() 2016-09-10 20:53:55 -07:00
ip_input.c net: VRF: Pass original iif to ip_route_input() 2016-09-16 04:24:07 -04:00
ip_options.c net: ipv4: Convert IP network timestamps to be y2038 safe 2016-03-01 17:18:44 -05:00
ip_output.c net: account for current skb length when deciding about UFO 2017-08-11 08:49:37 -07:00
ip_sockglue.c net-timestamp: avoid use-after-free in ip_recv_error 2017-05-03 08:36:36 -07:00
ip_tunnel.c ip_tunnel: add collect_md mode to IPIP tunnel 2016-09-17 10:13:07 -04:00
ip_tunnel_core.c net: Specify the owning module for lwtunnel ops 2017-02-04 09:47:11 +01:00
ip_vti.c vti: use right inner_mode for inbound inter address family policy checks 2016-09-09 09:02:08 +02:00
ipcomp.c ipv4: coding style: comparison for equality with NULL 2015-04-03 12:11:15 -04:00
ipconfig.c net: ipconfig: Fix NULL pointer dereference on RARP/BOOTP/DHCP timeout 2016-08-22 21:04:41 -07:00
ipip.c ip_tunnel: add collect_md mode to IPIP tunnel 2016-09-17 10:13:07 -04:00
ipmr.c ipv4: allow local fragmentation in ip_finish_output_gso() 2016-11-03 16:10:26 -04:00
Kconfig tcp: Set DEFAULT_TCP_CONG to bbr if DEFAULT_BBR is set 2016-11-28 12:15:00 -05:00
Makefile tcp_bbr: add BBR congestion control 2016-09-21 00:23:01 -04:00
netfilter.c netfilter: use skb_to_full_sk in ip_route_me_harder 2017-07-05 14:40:28 +02:00
ping.c ping: implement proper locking 2017-05-03 08:36:34 -07:00
proc.c net: Suppress the "Comparison to NULL could be written" warnings 2016-09-30 01:50:45 -04:00
protocol.c net: Export inet_offloads and inet6_offloads 2014-09-19 17:15:31 -04:00
raw.c ipv4, ipv6: ensure raw socket message is big enough to hold an IP header 2017-05-14 14:00:21 +02:00
route.c ipv4: add reference counting to metrics 2017-06-07 12:07:46 +02:00
syncookies.c ipv4: ipv6: initialize treq->txhash in cookie_v[46]_check() 2017-08-11 08:49:32 -07:00
sysctl_net_ipv4.c ipv4: make tcp_notsent_lowat sysctl knob behave as true unsigned int 2017-08-11 08:49:35 -07:00
tcp.c tcp: reset sk_rx_dst in tcp_disconnect() 2017-07-21 07:42:17 +02:00
tcp_bbr.c tcp_bbr: init pacing rate on first RTT sample 2017-08-11 08:49:32 -07:00
tcp_bic.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_cdg.c tcp: cdg: rename struct minmax in tcp_cdg.c to avoid a naming conflict 2016-09-21 00:22:59 -04:00
tcp_cong.c tcp: disallow cwnd undo when switching congestion control 2017-06-14 15:05:52 +02:00
tcp_cubic.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_dctcp.c dctcp: avoid bogus doubling of cwnd after loss 2016-10-31 15:16:28 -04:00
tcp_diag.c net: diag: Fix refcnt leak in error path destroying socket 2016-08-23 23:11:36 -07:00
tcp_fastopen.c tcp: initialize max window for a new fastopen socket 2017-02-04 09:47:10 +01:00
tcp_highspeed.c tcp: add tcp_in_slow_start helper 2015-07-09 14:22:52 -07:00
tcp_htcp.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_hybla.c tcp: do not slow start when cwnd equals ssthresh 2015-07-09 14:22:52 -07:00
tcp_illinois.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_input.c tcp: eliminate negative reordering in tcp_clean_rtx_queue 2017-06-07 12:07:44 +02:00
tcp_ipv4.c dccp/tcp: fix routing redirect race 2017-03-22 12:43:34 +01:00
tcp_lp.c tcp: fix wraparound issue in tcp_lp 2017-05-14 14:00:21 +02:00
tcp_metrics.c tcp: make nla_policy const 2016-09-01 14:09:01 -07:00
tcp_minisocks.c tcp: do not inherit fastopen_req from parent 2017-05-14 14:00:21 +02:00
tcp_nv.c tcp: add NV congestion control 2016-06-10 23:07:49 -07:00
tcp_offload.c gso: Support partial splitting at the frag_list pointer 2016-09-19 20:59:34 -04:00
tcp_output.c tcp: do not underestimate skb->truesize in tcp_trim_head() 2017-05-14 14:00:20 +02:00
tcp_probe.c tcp: tcp_probe: use spin_lock_bh() 2017-06-17 06:41:49 +02:00
tcp_rate.c tcp: export data delivery rate 2016-09-21 00:23:00 -04:00
tcp_recovery.c tcp: do not assume TCP code is non preemptible 2016-05-02 17:02:25 -04:00
tcp_scalable.c tcp: add tcp_in_slow_start helper 2015-07-09 14:22:52 -07:00
tcp_timer.c tcp: fix various issues for sockets morphing to listen state 2017-03-22 12:43:33 +01:00
tcp_vegas.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_vegas.h tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_veno.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_westwood.c tcp: replace cnt & rtt with struct in pkts_acked() 2016-05-11 14:43:19 -04:00
tcp_yeah.c tcp: cwnd does not increase in TCP YeAH 2016-09-08 17:16:12 -07:00
tunnel4.c tunnels: correct conditional build of MPLS and IPv6 2016-07-11 13:27:06 -07:00
udp.c udplite: call proper backlog handlers 2016-11-24 15:32:14 -05:00
udp_diag.c net: inet: diag: expose the socket mark to privileged processes. 2016-09-08 16:13:09 -07:00
udp_impl.h udplite: call proper backlog handlers 2016-11-24 15:32:14 -05:00
udp_offload.c net: add recursion limit to GRO 2016-10-20 14:32:22 -04:00
udp_tunnel.c net: Remove deprecated tunnel specific UDP offload functions 2016-06-17 20:23:32 -07:00
udplite.c udplite: call proper backlog handlers 2016-11-24 15:32:14 -05:00
xfrm4_input.c netfilter: Pass net into okfn 2015-09-17 17:18:37 -07:00
xfrm4_mode_beet.c ipv4: ERROR: code indent should use tabs where possible 2013-12-26 13:43:21 -05:00
xfrm4_mode_transport.c [IPSEC]: Use IPv6 calling convention as the convention for x->mode->output 2007-10-10 16:55:54 -07:00
xfrm4_mode_tunnel.c ipv4: hash net ptr into fragmentation bucket selection 2015-03-25 14:07:04 -04:00
xfrm4_output.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2015-10-24 06:54:12 -07:00
xfrm4_policy.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-09-12 15:52:44 -07:00
xfrm4_protocol.c xfrm4: Remove duplicate semicolon 2014-06-30 07:49:47 +02:00
xfrm4_state.c inet: make no_pmtu_disc per namespace and kill ipv4_config 2013-12-18 16:58:20 -05:00
xfrm4_tunnel.c sit: add IPv4 over IPv4 support 2013-05-31 17:19:05 -07:00