linux-stable/net/ipv4
Eric Dumazet 3d501dd326 tcp: do not accept ACK of bytes we never sent
This patch is based on a detailed report and ideas from Yepeng Pan
and Christian Rossow.

ACK seq validation is currently following RFC 5961 5.2 guidelines:

   The ACK value is considered acceptable only if
   it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <=
   SND.NXT).  All incoming segments whose ACK value doesn't satisfy the
   above condition MUST be discarded and an ACK sent back.  It needs to
   be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a
   duplicate (SEG.ACK < SND.UNA), it can be ignored.  If the ACK
   acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an
   ACK, drop the segment, and return".  The "ignored" above implies that
   the processing of the incoming data segment continues, which means
   the ACK value is treated as acceptable.  This mitigation makes the
   ACK check more stringent since any ACK < SND.UNA wouldn't be
   accepted, instead only ACKs that are in the range ((SND.UNA -
   MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through.

This can be refined for new (and possibly spoofed) flows,
by not accepting ACK for bytes that were never sent.

This greatly improves TCP security at a little cost.

I added a Fixes: tag to make sure this patch will reach stable trees,
even if the 'blamed' patch was adhering to the RFC.

tp->bytes_acked was added in linux-4.2

Following packetdrill test (courtesy of Yepeng Pan) shows
the issue at hand:

0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1024) = 0

// ---------------- Handshake ------------------- //

// when window scale is set to 14 the window size can be extended to
// 65535 * (2^14) = 1073725440. Linux would accept an ACK packet
// with ack number in (Server_ISN+1-1073725440. Server_ISN+1)
// ,though this ack number acknowledges some data never
// sent by the server.

+0 < S 0:0(0) win 65535 <mss 1400,nop,wscale 14>
+0 > S. 0:0(0) ack 1 <...>
+0 < . 1:1(0) ack 1 win 65535
+0 accept(3, ..., ...) = 4

// For the established connection, we send an ACK packet,
// the ack packet uses ack number 1 - 1073725300 + 2^32,
// where 2^32 is used to wrap around.
// Note: we used 1073725300 instead of 1073725440 to avoid possible
// edge cases.
// 1 - 1073725300 + 2^32 = 3221241997

// Oops, old kernels happily accept this packet.
+0 < . 1:1001(1000) ack 3221241997 win 65535

// After the kernel fix the following will be replaced by a challenge ACK,
// and prior malicious frame would be dropped.
+0 > . 1:1(0) ack 1001

Fixes: 354e4aa391 ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Yepeng Pan <yepeng.pan@cispa.de>
Reported-by: Christian Rossow <rossow@cispa.de>
Acked-by: Neal Cardwell <ncardwell@google.com>
Link: https://lore.kernel.org/r/20231205161841.2702925-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-12-06 19:00:42 -08:00
..
bpfilter net: Use umd_cleanup_helper() 2023-05-31 13:06:57 +02:00
netfilter Including fixes from netfilter and bpf. 2023-11-09 17:09:35 -08:00
af_inet.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2023-10-19 13:29:01 -07:00
ah4.c net: ipv4: stop checking crypto_ahash_alignmask 2023-10-27 18:04:29 +08:00
arp.c neighbour: annotate lockless accesses to n->nud_state 2023-03-15 00:37:32 -07:00
bpf_tcp_ca.c bpf: Drop useless btf_vmlinux in bpf_tcp_ca 2023-07-18 17:31:10 -07:00
cipso_ipv4.c inet: move inet->is_icsk to inet->inet_flags 2023-08-16 11:09:17 +01:00
datagram.c inet: implement lockless getsockopt(IP_MULTICAST_IF) 2023-10-01 19:39:19 +01:00
devinet.c net: ipv4: fix one memleak in __inet_del_ifa() 2023-09-08 08:02:17 +01:00
esp4.c net: ipv4: fix typo in comments 2023-10-25 10:38:07 +01:00
esp4_offload.c xfrm: Support GRO for IPv4 ESP in UDP encapsulation 2023-10-06 07:30:40 +02:00
fib_frontend.c ipv4: Fix incorrect table ID in IOCTL path 2023-03-16 17:26:31 -07:00
fib_lookup.h
fib_notifier.c
fib_rules.c
fib_semantics.c ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr 2023-10-18 18:11:31 -07:00
fib_trie.c ipv4/fib: send notify when delete source address routes 2023-10-03 09:00:40 +02:00
fou_bpf.c bpf: Add __bpf_kfunc_{start,end}_defs macros 2023-11-01 22:33:53 -07:00
fou_core.c bpf,fou: Add bpf_skb_{set,get}_fou_encap kfuncs 2023-04-12 16:40:39 -07:00
fou_nl.c net: ynl: prefix uAPI header include with uapi/ 2023-05-26 10:30:14 +01:00
fou_nl.h net: ynl: prefix uAPI header include with uapi/ 2023-05-26 10:30:14 +01:00
gre_demux.c
gre_offload.c net: move gso declarations and functions to their own files 2023-06-10 00:11:41 -07:00
icmp.c xfrm: pass struct net to xfrm_decode_session wrappers 2023-10-06 08:31:53 +02:00
igmp.c ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet 2023-11-24 15:25:56 +00:00
inet_connection_sock.c tcp: allow again tcp_disconnect() when threads are waiting 2023-10-13 16:49:32 -07:00
inet_diag.c net: fill in MODULE_DESCRIPTION()s for SOCK_DIAG modules 2023-11-19 20:09:13 +00:00
inet_fragment.c net: dropreason: add SKB_DROP_REASON_FRAG_REASM_TIMEOUT 2022-10-31 20:14:27 -07:00
inet_hashtables.c net: set SOCK_RCU_FREE before inserting socket into hashtable 2023-11-10 08:37:09 +00:00
inet_timewait_sock.c inet: move inet->transparent to inet->inet_flags 2023-08-16 11:09:17 +01:00
inetpeer.c inetpeer: Fix data-races around sysctl. 2022-07-08 12:10:33 +01:00
ip_forward.c net: fix IPSTATS_MIB_OUTFORWDATAGRAMS increment after fragment check 2023-10-13 09:58:45 -07:00
ip_fragment.c networking: Update to register_net_sysctl_sz 2023-08-15 15:26:18 -07:00
ip_gre.c ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit() 2023-12-06 10:08:05 +01:00
ip_input.c ipv4: ignore dst hint for multipath routes 2023-09-01 08:11:51 +01:00
ip_options.c
ip_output.c net: fix IPSTATS_MIB_OUTPKGS increment in OutForwDatagrams. 2023-10-20 12:01:00 +01:00
ip_sockglue.c net: bpf: Use sockopt_lock_sock() in ip_sock_set_tos() 2023-10-27 15:41:28 -07:00
ip_tunnel.c bpf-next-for-netdev 2023-04-13 16:43:38 -07:00
ip_tunnel_core.c tunnels: fix kasan splat when generating ipv4 pmtu error 2023-08-04 18:24:52 -07:00
ip_vti.c xfrm: pass struct net to xfrm_decode_session wrappers 2023-10-06 08:31:53 +02:00
ipcomp.c xfrm: ipcomp: add extack to ipcomp{4,6}_init_state 2022-09-29 07:18:00 +02:00
ipconfig.c net: ipconfig: move ic_nameservers_fallback into #ifdef block 2023-05-22 11:17:55 +01:00
ipip.c ipip,ip_tunnel,sit: Add FOU support for externally controlled ipip devices 2023-04-12 16:40:39 -07:00
ipmr.c net: ipv4, ipv6: fix IPSTATS_MIB_OUTOCTETS increment duplicated 2023-08-30 09:44:09 +01:00
ipmr_base.c
Kconfig net/tcp: Add TCP-AO config and structures 2023-10-27 10:35:44 +01:00
Makefile net/tcp: Introduce TCP_AO setsockopt()s 2023-10-27 10:35:44 +01:00
metrics.c ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() 2023-01-23 21:37:25 -08:00
netfilter.c xfrm: pass struct net to xfrm_decode_session wrappers 2023-10-06 08:31:53 +02:00
netlink.c
nexthop.c nexthop: Do not increment dump sentinel at the end of the dump 2023-08-15 18:54:53 -07:00
ping.c bpf-next-for-netdev 2023-10-16 21:05:33 -07:00
proc.c net/tcp: Ignore specific ICMPs for TCP-AO connections 2023-10-27 10:35:45 +01:00
protocol.c
raw.c inet: implement lockless getsockopt(IP_MULTICAST_IF) 2023-10-01 19:39:19 +01:00
raw_diag.c net: fill in MODULE_DESCRIPTION()s for SOCK_DIAG modules 2023-11-19 20:09:13 +00:00
route.c ipv4: Correct/silence an endian warning in __ip_do_redirect 2023-11-21 12:55:22 +01:00
syncookies.c tcp: fix fastopen code vs usec TS 2023-11-03 09:16:42 +00:00
sysctl_net_ipv4.c tcp: Set pingpong threshold via sysctl 2023-10-16 14:55:32 -07:00
tcp.c net/tcp: Limit TCP_AO_REPAIR to non-listen sockets 2023-12-06 12:36:55 +01:00
tcp_ao.c net/tcp: Don't store TCP-AO maclen on reqsk 2023-12-06 12:36:56 +01:00
tcp_bbr.c net: implement lockless SO_MAX_PACING_RATE 2023-10-01 19:09:54 +01:00
tcp_bic.c
tcp_bpf.c tcp_bpf: properly release resources on error paths 2023-10-18 18:09:31 -07:00
tcp_cdg.c Random number generator fixes for Linux 6.1-rc1. 2022-10-16 15:27:07 -07:00
tcp_cong.c net: Update an existing TCP congestion control algorithm. 2023-03-22 22:53:00 -07:00
tcp_cubic.c bpf: Add __bpf_kfunc tag to all kfuncs 2023-02-02 00:25:14 +01:00
tcp_dctcp.c bpf: Add __bpf_kfunc tag to all kfuncs 2023-02-02 00:25:14 +01:00
tcp_dctcp.h
tcp_diag.c net: fill in MODULE_DESCRIPTION()s for SOCK_DIAG modules 2023-11-19 20:09:13 +00:00
tcp_fastopen.c inet: move inet->defer_connect to inet->inet_flags 2023-08-16 11:09:18 +01:00
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c
tcp_input.c tcp: do not accept ACK of bytes we never sent 2023-12-06 19:00:42 -08:00
tcp_ipv4.c net/tcp: Consistently align TCP-AO option in the header 2023-12-06 12:36:55 +01:00
tcp_lp.c tcp: rename tcp_time_stamp() to tcp_time_stamp_ts() 2023-10-23 09:35:01 +01:00
tcp_metrics.c tcp_metrics: optimize tcp_metrics_flush_all() 2023-10-03 10:05:22 +02:00
tcp_minisocks.c net/tcp: Consistently align TCP-AO option in the header 2023-12-06 12:36:55 +01:00
tcp_nv.c
tcp_offload.c net: move gso declarations and functions to their own files 2023-06-10 00:11:41 -07:00
tcp_output.c net/tcp: Don't store TCP-AO maclen on reqsk 2023-12-06 12:36:56 +01:00
tcp_plb.c prandom: remove prandom_u32_max() 2022-12-20 03:13:45 +01:00
tcp_rate.c
tcp_recovery.c tcp: fix excessive TLP and RACK timeouts from HZ rounding 2023-10-17 17:25:42 -07:00
tcp_scalable.c
tcp_sigpool.c net/tcp_sigpool: Fix some off by one bugs 2023-11-01 22:28:09 -07:00
tcp_timer.c tcp: add support for usec resolution in TCP TS values 2023-10-23 09:35:01 +01:00
tcp_ulp.c net/ulp: use consistent error code when blocking ULP 2023-01-19 09:26:16 -08:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c
udp.c ipsec-next-2023-10-28 2023-10-30 14:36:57 -07:00
udp_bpf.c bpf, sockmap: Fix an infinite loop error when len is 0 in tcp_bpf_recvmsg_parser() 2023-03-03 17:25:15 +01:00
udp_diag.c net: fill in MODULE_DESCRIPTION()s for SOCK_DIAG modules 2023-11-19 20:09:13 +00:00
udp_impl.h sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) 2023-06-24 15:50:13 -07:00
udp_offload.c udp: move udp->gro_enabled to udp->udp_flags 2023-09-14 16:16:36 +02:00
udp_tunnel_core.c ipv4: use tunnel flow flags for tunnel route lookups 2023-10-16 09:57:52 +01:00
udp_tunnel_nic.c udp_tunnel: Use flex array to simplify code 2023-10-03 11:39:34 +02:00
udp_tunnel_stub.c
udplite.c udplite: remove UDPLITE_BIT 2023-09-14 16:16:36 +02:00
xfrm4_input.c xfrm Fix use after free in __xfrm6_udp_encap_rcv. 2023-10-23 07:10:39 +02:00
xfrm4_output.c
xfrm4_policy.c sysctl-6.6-rc1 2023-08-29 17:39:15 -07:00
xfrm4_protocol.c
xfrm4_state.c
xfrm4_tunnel.c xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state 2022-09-29 07:18:00 +02:00