Skip to content

Commit 6f0012e

Browse files
edumazetkuba-moo
authored andcommitted
tcp: add a missing nf_reset_ct() in 3WHS handling
When the third packet of 3WHS connection establishment contains payload, it is added into socket receive queue without the XFRM check and the drop of connection tracking context. This means that if the data is left unread in the socket receive queue, conntrack module can not be unloaded. As most applications usually reads the incoming data immediately after accept(), bug has been hiding for quite a long time. Commit 68822bd ("net: generalize skb freeing deferral to per-cpu lists") exposed this bug because even if the application reads this data, the skb with nfct state could stay in a per-cpu cache for an arbitrary time, if said cpu no longer process RX softirqs. Many thanks to Ilya Maximets for reporting this issue, and for testing various patches: https://lore.kernel.org/netdev/[email protected]/ Note that I also added a missing xfrm4_policy_check() call, although this is probably not a big issue, as the SYN packet should have been dropped earlier. Fixes: b59c270 ("[NETFILTER]: Keep conntrack reference until IPsec policy checks are done") Reported-by: Ilya Maximets <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Cc: Florian Westphal <[email protected]> Cc: Pablo Neira Ayuso <[email protected]> Cc: Steffen Klassert <[email protected]> Tested-by: Ilya Maximets <[email protected]> Reviewed-by: Ilya Maximets <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 935336c commit 6f0012e

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

net/ipv4/tcp_ipv4.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
19641964
struct sock *nsk;
19651965

19661966
sk = req->rsk_listener;
1967-
drop_reason = tcp_inbound_md5_hash(sk, skb,
1967+
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
1968+
drop_reason = SKB_DROP_REASON_XFRM_POLICY;
1969+
else
1970+
drop_reason = tcp_inbound_md5_hash(sk, skb,
19681971
&iph->saddr, &iph->daddr,
19691972
AF_INET, dif, sdif);
19701973
if (unlikely(drop_reason)) {
@@ -2016,6 +2019,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
20162019
}
20172020
goto discard_and_relse;
20182021
}
2022+
nf_reset_ct(skb);
20192023
if (nsk == sk) {
20202024
reqsk_put(req);
20212025
tcp_v4_restore_cb(skb);

0 commit comments

Comments
 (0)