mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
netfilter: conntrack: handle tcp challenge acks during connection reuse
[ Upstream commit c410cb974f2ba562920ecb8492ee66945dcf88af ] When a connection is re-used, following can happen: [ connection starts to close, fin sent in either direction ] > syn # initator quickly reuses connection < ack # peer sends a challenge ack > rst # rst, sequence number == ack_seq of previous challenge ack > syn # this syn is expected to pass Problem is that the rst will fail window validation, so it gets tagged as invalid. If ruleset drops such packets, we get repeated syn-retransmits until initator gives up or peer starts responding with syn/ack. Before the commit indicated in the "Fixes" tag below this used to work: The challenge-ack made conntrack re-init state based on the challenge ack itself, so the following rst would pass window validation. Add challenge-ack support: If we get ack for syn, record the ack_seq, and then check if the rst sequence number matches the last ack number seen in reverse direction. Fixes: c7aab4f17021 ("netfilter: nf_conntrack_tcp: re-init for syn packets only") Reported-by: Michal Tesar <mtesar@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
bb03899b9b
commit
5d947222e4
@ -1068,6 +1068,13 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
|
||||
ct->proto.tcp.last_flags |=
|
||||
IP_CT_EXP_CHALLENGE_ACK;
|
||||
}
|
||||
|
||||
/* possible challenge ack reply to syn */
|
||||
if (old_state == TCP_CONNTRACK_SYN_SENT &&
|
||||
index == TCP_ACK_SET &&
|
||||
dir == IP_CT_DIR_REPLY)
|
||||
ct->proto.tcp.last_ack = ntohl(th->ack_seq);
|
||||
|
||||
spin_unlock_bh(&ct->lock);
|
||||
nf_ct_l4proto_log_invalid(skb, ct, state,
|
||||
"packet (index %d) in dir %d ignored, state %s",
|
||||
@ -1193,6 +1200,14 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
|
||||
* segments we ignored. */
|
||||
goto in_window;
|
||||
}
|
||||
|
||||
/* Reset in response to a challenge-ack we let through earlier */
|
||||
if (old_state == TCP_CONNTRACK_SYN_SENT &&
|
||||
ct->proto.tcp.last_index == TCP_ACK_SET &&
|
||||
ct->proto.tcp.last_dir == IP_CT_DIR_REPLY &&
|
||||
ntohl(th->seq) == ct->proto.tcp.last_ack)
|
||||
goto in_window;
|
||||
|
||||
break;
|
||||
default:
|
||||
/* Keep compilers happy. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user