From ad318128f5e2276cd8dcb1d3de516d657b05ff7d Mon Sep 17 00:00:00 2001 From: Alexander Aprelev Date: Wed, 1 Oct 2025 15:15:20 -0700 Subject: [PATCH] [io] Fix race between closing socket and requesting its type. Fixes https://github.com/dart-lang/sdk/issues/61582 Revert "[io/socket] Make Socket::fd_ atomic since it can get updated from multiple threads." Revert "[gardening] Fix fuchsia build - assign atomic to intptr_t before reinterpret_cast to pointer." TEST=ci Change-Id: Ia755d6623e46b7940800a12bf4a5d8d9cb674522 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/451822 Reviewed-by: Slava Egorov Commit-Queue: Alexander Aprelev --- runtime/bin/socket.cc | 5 +++++ runtime/bin/socket.h | 2 +- runtime/bin/socket_base_win.cc | 4 ---- runtime/bin/socket_fuchsia.cc | 5 ++--- runtime/bin/socket_win.cc | 8 +++----- sdk/lib/_internal/vm/bin/stdio_patch.dart | 6 ++++++ 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc index 0de173f2b70..1d14d428468 100644 --- a/runtime/bin/socket.cc +++ b/runtime/bin/socket.cc @@ -953,6 +953,11 @@ void FUNCTION_NAME(Socket_GetFD)(Dart_NativeArguments args) { void FUNCTION_NAME(Socket_GetType)(Dart_NativeArguments args) { Socket* socket = Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); + if (socket->fd() < 0) { + OSError os_error(-1, "Socket is closed.", OSError::kUnknown); + Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); + return; + } OSError os_error; intptr_t type = SocketBase::GetType(socket->fd()); if (type >= 0) { diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h index a5a998ad237..9a53d51774d 100644 --- a/runtime/bin/socket.h +++ b/runtime/bin/socket.h @@ -124,7 +124,7 @@ class Socket : public ReferenceCounted { static bool short_socket_read_; static bool short_socket_write_; - std::atomic fd_; + intptr_t fd_; Dart_Port isolate_port_; Dart_Port port_; uint8_t* udp_receive_buffer_; diff --git a/runtime/bin/socket_base_win.cc b/runtime/bin/socket_base_win.cc index 25c40caf7d5..966dada4de8 100644 --- a/runtime/bin/socket_base_win.cc +++ b/runtime/bin/socket_base_win.cc @@ -215,10 +215,6 @@ void SocketBase::GetError(intptr_t fd, OSError* os_error) { } int SocketBase::GetType(intptr_t fd) { - if (fd < 0) { - return -1; - } - Handle* handle = reinterpret_cast(fd); switch (GetFileType(handle->handle())) { case FILE_TYPE_CHAR: diff --git a/runtime/bin/socket_fuchsia.cc b/runtime/bin/socket_fuchsia.cc index 11093899a60..885ec97063d 100644 --- a/runtime/bin/socket_fuchsia.cc +++ b/runtime/bin/socket_fuchsia.cc @@ -55,9 +55,8 @@ void Socket::SetClosedFd() { } void Socket::CloseFd() { - intptr_t fd_handle = fd(); - ASSERT(fd_handle != kClosedFd); - IOHandle* handle = reinterpret_cast(fd_handle); + ASSERT(fd_ != kClosedFd); + IOHandle* handle = reinterpret_cast(fd_); ASSERT(handle != nullptr); handle->Release(); SetClosedFd(); diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc index fbb5bb6a3b6..a64dceeb390 100644 --- a/runtime/bin/socket_win.cc +++ b/runtime/bin/socket_win.cc @@ -26,15 +26,13 @@ Socket::Socket(intptr_t fd) port_(ILLEGAL_PORT), udp_receive_buffer_(nullptr) { ASSERT(fd_ != kClosedFd); - intptr_t fd_handle = fd_; - Handle* handle = reinterpret_cast(fd_handle); + Handle* handle = reinterpret_cast(fd_); ASSERT(handle != nullptr); } void Socket::CloseFd() { - intptr_t fd_handle = fd(); - ASSERT(fd_handle != kClosedFd); - Handle* handle = reinterpret_cast(fd_handle); + ASSERT(fd_ != kClosedFd); + Handle* handle = reinterpret_cast(fd_); ASSERT(handle != nullptr); handle->Release(); SetClosedFd(); diff --git a/sdk/lib/_internal/vm/bin/stdio_patch.dart b/sdk/lib/_internal/vm/bin/stdio_patch.dart index e4074dfbf74..d97d5a03b92 100644 --- a/sdk/lib/_internal/vm/bin/stdio_patch.dart +++ b/sdk/lib/_internal/vm/bin/stdio_patch.dart @@ -48,6 +48,12 @@ class _StdIOUtils { } static int _nativeSocketType(_NativeSocket nativeSocket) { + if (nativeSocket.isClosed) { + throw FileSystemException("Socket is closed"); + } + if (nativeSocket.isClosing) { + throw FileSystemException("Socket is being closed"); + } var result = _getSocketType(nativeSocket); if (result is OSError) { throw FileSystemException("Error retrieving socket type", "", result);