linux-stable/net/ipv4
Dong Chenchen e71c332bcf net: Remove acked SYN flag from packet in the transmit queue correctly
[ Upstream commit f99cd56230 ]

syzkaller report:

 kernel BUG at net/core/skbuff.c:3452!
 invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.7.0-rc4-00009-gbee0e7762ad2-dirty #135
 RIP: 0010:skb_copy_and_csum_bits (net/core/skbuff.c:3452)
 Call Trace:
 icmp_glue_bits (net/ipv4/icmp.c:357)
 __ip_append_data.isra.0 (net/ipv4/ip_output.c:1165)
 ip_append_data (net/ipv4/ip_output.c:1362 net/ipv4/ip_output.c:1341)
 icmp_push_reply (net/ipv4/icmp.c:370)
 __icmp_send (./include/net/route.h:252 net/ipv4/icmp.c:772)
 ip_fragment.constprop.0 (./include/linux/skbuff.h:1234 net/ipv4/ip_output.c:592 net/ipv4/ip_output.c:577)
 __ip_finish_output (net/ipv4/ip_output.c:311 net/ipv4/ip_output.c:295)
 ip_output (net/ipv4/ip_output.c:427)
 __ip_queue_xmit (net/ipv4/ip_output.c:535)
 __tcp_transmit_skb (net/ipv4/tcp_output.c:1462)
 __tcp_retransmit_skb (net/ipv4/tcp_output.c:3387)
 tcp_retransmit_skb (net/ipv4/tcp_output.c:3404)
 tcp_retransmit_timer (net/ipv4/tcp_timer.c:604)
 tcp_write_timer (./include/linux/spinlock.h:391 net/ipv4/tcp_timer.c:716)

The panic issue was trigered by tcp simultaneous initiation.
The initiation process is as follows:

      TCP A                                            TCP B

  1.  CLOSED                                           CLOSED

  2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...

  3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT

  4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

  5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...

  // TCP B: not send challenge ack for ack limit or packet loss
  // TCP A: close
	tcp_close
	   tcp_send_fin
              if (!tskb && tcp_under_memory_pressure(sk))
                  tskb = skb_rb_last(&sk->tcp_rtx_queue); //pick SYN_ACK packet
           TCP_SKB_CB(tskb)->tcp_flags |= TCPHDR_FIN;  // set FIN flag

  6.  FIN_WAIT_1  --> <SEQ=100><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ...

  // TCP B: send challenge ack to SYN_FIN_ACK

  7.               ... <SEQ=301><ACK=101><CTL=ACK>   <-- SYN-RECEIVED //challenge ack

  // TCP A:  <SND.UNA=101>

  8.  FIN_WAIT_1 --> <SEQ=101><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ... // retransmit panic

	__tcp_retransmit_skb  //skb->len=0
	    tcp_trim_head
		len = tp->snd_una - TCP_SKB_CB(skb)->seq // len=101-100
		    __pskb_trim_head
			skb->data_len -= len // skb->len=-1, wrap around
	    ... ...
	    ip_fragment
		icmp_glue_bits //BUG_ON

If we use tcp_trim_head() to remove acked SYN from packet that contains data
or other flags, skb->len will be incorrectly decremented. We can remove SYN
flag that has been acked from rtx_queue earlier than tcp_trim_head(), which
can fix the problem mentioned above.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Co-developed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Link: https://lore.kernel.org/r/20231210020200.1539875-1-dongchenchen2@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-12-20 15:32:33 +01:00
..
netfilter treewide: Remove uninitialized_var() usage 2023-08-11 11:33:32 +02:00
Kconfig tcp: configurable source port perturb table size 2022-12-08 11:16:31 +01:00
Makefile
af_inet.c tcp/udp: Make early_demux back namespacified. 2022-11-10 15:47:22 +01:00
ah4.c
arp.c arp: fix arp_filter on l3slave devices 2018-04-12 12:32:22 +02:00
cipso_ipv4.c cipso: Fix data-races around sysctl. 2022-07-21 20:42:44 +02:00
datagram.c inet: stop leaking jiffies on the wire 2019-11-10 11:25:37 +01:00
devinet.c net: return correct error code 2021-12-08 08:46:53 +01:00
esp4.c net: ipv4: fix return value check in esp_remove_trailer 2023-10-25 11:13:31 +02:00
esp4_offload.c xfrm: Linearize the skb after offloading if needed. 2023-06-28 10:14:19 +02:00
fib_frontend.c ipv4: Fix incorrect table ID in IOCTL path 2023-03-22 13:26:14 +01:00
fib_lookup.h
fib_notifier.c
fib_rules.c
fib_semantics.c net: Fix the arp error in some cases 2020-06-30 15:38:00 -04:00
fib_trie.c ipv4: Silence suspicious RCU usage warning 2020-08-21 09:48:00 +02:00
fou.c net: fou: do not use guehdr after iptunnel_pull_offloads in gue_udp_recv 2019-04-27 09:35:34 +02:00
gre_demux.c gre: fix uninit-value in __iptunnel_pull_header 2020-03-20 10:54:07 +01:00
gre_offload.c net: gre: recompute gre csum for sctp over gre tunnels 2020-08-21 09:48:01 +02:00
icmp.c icmp: guard against too small mtu 2023-04-20 12:02:10 +02:00
igmp.c ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet 2023-12-08 08:42:00 +01:00
inet_connection_sock.c tcp: Fix listen() regression in 4.14.303. 2023-03-11 16:26:55 +01:00
inet_diag.c inet_diag: Fix error path to cancel the meseage in inet_req_diag_fill() 2020-11-24 13:05:37 +01:00
inet_fragment.c net: IP defrag: encapsulate rbtree defrag code into callable functions 2019-04-27 09:35:40 +02:00
inet_hashtables.c inet: fix fast path in __inet_hash_connect() 2023-03-11 16:26:42 +01:00
inet_timewait_sock.c soreuseport: initialise timewait reuseport field 2018-05-16 10:10:24 +02:00
inetpeer.c inetpeer: Fix data-races around sysctl. 2022-07-21 20:42:44 +02:00
ip_forward.c
ip_fragment.c net: IP defrag: encapsulate rbtree defrag code into callable functions 2019-04-27 09:35:40 +02:00
ip_gre.c ip_gre: Make o_seqno start from 0 in native mode 2022-05-12 12:17:07 +02:00
ip_input.c tcp/udp: Make early_demux back namespacified. 2022-11-10 15:47:22 +01:00
ip_options.c vrf: check accept_source_route on the original netdevice 2019-04-17 08:37:48 +02:00
ip_output.c lwt: Check LWTUNNEL_XMIT_CONTINUE strictly 2023-09-23 10:46:55 +02:00
ip_sockglue.c ip: on queued skb use skb_header_pointer instead of pskb_may_pull 2019-01-23 08:09:47 +01:00
ip_tunnel.c net: tunnels: annotate lockless accesses to dev->needed_headroom 2023-03-22 13:26:14 +01:00
ip_tunnel_core.c ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL 2019-08-04 09:32:03 +02:00
ip_vti.c ip_vti: fix potential slab-use-after-free in decode_session6 2023-08-30 16:35:12 +02:00
ipcomp.c
ipconfig.c net: ipconfig: Don't override command-line hostnames or domains 2021-06-30 08:48:47 -04:00
ipip.c net: ipip: fix wrong address family in init error path 2020-06-03 08:17:31 +02:00
ipmr.c ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on failure path 2022-02-16 12:44:51 +01:00
netfilter.c
ping.c ping: fix address binding wrt vrf 2022-05-18 09:18:09 +02:00
proc.c tcp: tcp_fragment() should apply sane memory limits 2019-06-17 19:52:44 +02:00
protocol.c
raw.c net: add missing SOF_TIMESTAMPING_OPT_ID support 2022-04-20 09:08:28 +02:00
raw_diag.c inet_diag: return classid for all socket types 2020-03-20 10:54:13 +01:00
route.c ipv4: Correct/silence an endian warning in __ip_do_redirect 2023-12-08 08:41:59 +01:00
syncookies.c net: Update window_clamp if SOCK_RCVBUF is set 2020-11-18 18:28:00 +01:00
sysctl_net_ipv4.c tcp/udp: Make early_demux back namespacified. 2022-11-10 15:47:22 +01:00
tcp.c tcp: annotate data-races around fastopenq.max_qlen 2023-08-11 11:33:50 +02:00
tcp_bbr.c tcp_bbr: fix u32 wrap bug in round logic if bbr_init() called after 2B packets 2021-08-26 08:37:02 -04:00
tcp_bic.c
tcp_cdg.c tcp: cdg: allow tcp_cdg_release() to be called multiple times 2022-11-25 17:36:54 +01:00
tcp_cong.c tcp: Set INET_ECN_xmit configuration in tcp_reinit_congestion_control 2020-12-08 10:17:33 +01:00
tcp_cubic.c tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited flows 2021-12-08 08:46:49 +01:00
tcp_dctcp.c tcp: Ensure DCTCP reacts to losses 2019-04-17 08:37:47 +02:00
tcp_diag.c
tcp_fastopen.c tcp: annotate data-races around fastopenq.max_qlen 2023-08-11 11:33:50 +02:00
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c net/tcp/illinois: replace broken algorithm reference link 2018-05-30 07:52:06 +02:00
tcp_input.c tcp: do not accept ACK of bytes we never sent 2023-12-13 16:46:15 +01:00
tcp_ipv4.c dccp/tcp: Reset saddr on failure after inet6?_hash_connect(). 2022-12-08 11:16:30 +01:00
tcp_lp.c
tcp_metrics.c tcp_metrics: do not create an entry from tcp_init_metrics() 2023-11-20 10:27:33 +01:00
tcp_minisocks.c tcp: tcp_check_req() can be called from process context 2023-03-11 16:26:53 +01:00
tcp_nv.c tcp_nv: fix potential integer overflow in tcpnv_acked 2018-04-26 11:02:13 +02:00
tcp_offload.c gso: validate gso_type in GSO handlers 2018-01-31 14:03:47 +01:00
tcp_output.c net: Remove acked SYN flag from packet in the transmit queue correctly 2023-12-20 15:32:33 +01:00
tcp_probe.c
tcp_rate.c
tcp_recovery.c tcp: fix TLP timer not set when CA_STATE changes from DISORDER to OPEN 2021-02-03 23:22:23 +01:00
tcp_scalable.c
tcp_timer.c net: tcp: fix unexcepted socket die when snd_wnd is 0 2023-09-23 10:46:55 +02:00
tcp_ulp.c tcp, ulp: add alias for all ulp modules 2018-09-15 09:45:29 +02:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c
udp.c tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct(). 2023-04-26 11:18:57 +02:00
udp_diag.c inet_diag: return classid for all socket types 2020-03-20 10:54:13 +01:00
udp_impl.h
udp_offload.c net: Fix gro aggregation for udp encaps with zero csum 2021-03-17 16:34:28 +01:00
udp_tunnel.c net/tunnel: wait until all sk_user_data reader finish before releasing the sock 2023-01-18 09:26:19 +01:00
udplite.c tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct(). 2023-04-26 11:18:57 +02:00
xfrm4_input.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-11-04 14:52:37 +01:00
xfrm4_mode_beet.c
xfrm4_mode_transport.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-11-04 14:52:37 +01:00
xfrm4_mode_tunnel.c
xfrm4_output.c xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish 2020-05-02 17:24:18 +02:00
xfrm4_policy.c xfrm: Don't accidentally set RTO_ONLINK in decode_session4() 2022-02-23 11:57:34 +01:00
xfrm4_protocol.c net: xfrm: unexport __init-annotated xfrm4_protocol_init() 2022-06-14 16:53:58 +02:00
xfrm4_state.c
xfrm4_tunnel.c