Page MenuHomeFreeBSD

tcp: address a wire level race with 2 ACKs at the end of TCP handshake
ClosedPublic

Authored by glebius on Aug 7 2022, 7:18 PM.
Tags
None
Referenced Files
Unknown Object (File)
Oct 9 2024, 11:48 AM
Unknown Object (File)
Sep 20 2024, 12:37 PM
Unknown Object (File)
Sep 19 2024, 6:25 PM
Unknown Object (File)
Sep 19 2024, 3:14 AM
Unknown Object (File)
Aug 4 2024, 12:38 PM
Unknown Object (File)
Aug 2 2024, 1:57 AM
Unknown Object (File)
Jul 8 2024, 3:57 AM
Unknown Object (File)
Jul 3 2024, 10:57 AM
Subscribers

Details

Summary

Imagine we are in SYN-RCVD state and two ACKs arrive at the same time,
both valid, e.g. coming from the same host and with valid sequence.

First packet would locate the listening socket in the inpcb database,
write-lock it and start expanding the syncache entry into a socket.
Meanwhile second packet would wait on the write lock of the listening
socket. First packet will create a new ESTABLISHED socket, free the
syncache entry and unlock the listening socket. Second packet would
call into syncache_expand(), but this time it will fail as there
is no syncache entry. Second packet would generate RST, effectively
resetting the remote connection.

It seems to me, that it is impossible to solve this problem with
just rearranging locks, as the race happens at a wire level.

To solve the problem, for an ACK packet arrived on a listening socket,
that failed syncache lookup, perform a second non-wildcard lookup right.
That lookup may find the new born socket. Otherwise, we indeed send RST.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 46773
Build 43662: arc lint + arc unit