mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibCore: Fix race condition in PosixSocketHelper::read on Windows
CancelIo introduces a race condition: if data arrives between calls to WSARecv and CancelIo it will be lost. See also: https://vstinner.github.io/asyncio-proactor-wsarecv-cancellation-data-loss.html
This commit is contained in:
parent
e0d7278820
commit
75b0e9a199
Notes:
github-actions[bot]
2025-06-17 18:57:52 +00:00
Author: https://github.com/stasoid
Commit: 75b0e9a199
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5045
Reviewed-by: https://github.com/gmta ✅
1 changed files with 8 additions and 14 deletions
|
@ -29,25 +29,19 @@ ErrorOr<Bytes> PosixSocketHelper::read(Bytes buffer, int flags)
|
||||||
return Error::from_errno(ENOTCONN);
|
return Error::from_errno(ENOTCONN);
|
||||||
|
|
||||||
// FIXME: also take into account if PosixSocketHelper is blocking/non-blocking (see set_blocking)
|
// FIXME: also take into account if PosixSocketHelper is blocking/non-blocking (see set_blocking)
|
||||||
bool blocking = !(flags & MSG_DONTWAIT);
|
bool non_blocking = flags & MSG_DONTWAIT;
|
||||||
|
|
||||||
|
if (non_blocking && !TRY(can_read_without_blocking(0)))
|
||||||
|
return Error::from_errno(EWOULDBLOCK);
|
||||||
|
|
||||||
WSABUF buf = make_wsa_buf(buffer);
|
WSABUF buf = make_wsa_buf(buffer);
|
||||||
DWORD nread = 0;
|
DWORD nread = 0;
|
||||||
DWORD fl = 0;
|
DWORD fl = 0;
|
||||||
OVERLAPPED ov = {};
|
|
||||||
|
|
||||||
if (WSARecv(m_fd, &buf, 1, &nread, &fl, blocking ? NULL : &ov, NULL) == SOCKET_ERROR) {
|
if (WSARecv(m_fd, &buf, 1, &nread, &fl, NULL, NULL) == SOCKET_ERROR) {
|
||||||
|
if (GetLastError() == WSAECONNRESET)
|
||||||
auto error = GetLastError();
|
|
||||||
|
|
||||||
if (error == WSA_IO_PENDING) {
|
|
||||||
CancelIo(to_handle(m_fd));
|
|
||||||
return Error::from_errno(EWOULDBLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == WSAECONNRESET)
|
|
||||||
return Error::from_errno(ECONNRESET);
|
return Error::from_errno(ECONNRESET);
|
||||||
|
return Error::from_windows_error();
|
||||||
return Error::from_windows_error(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nread == 0)
|
if (nread == 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue