You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
WinIO: socket operations can leave a stale completion packet #638
Under WinIO, sockets are associated with the I/O manager's completion port without FILE_SKIP_COMPLETION_PORT_ON_SUCCESS, so Windows queues a completion packet even for a WSARecv/WSASend that finishes immediately. Since #626 the WinIO paths answer Mgr.CbPending in that case. GHC's withOverlappedEx then calls getOverlappedResult without waiting (the handle is async), finds the request finished, completes it inline and returns, after which withRequest releases the HASKELL_OVERLAPPED. The packet Windows queued for it is still on the port. When processCompletion dequeues it, it reads the freed record: harmless while that memory still holds nullReq, but once it's been reused the I/O manager follows garbage and the program can crash.
Is the flag valid for sockets?@Mistuke suggested in in haskell/network#602 that it isn't. Microsoft documents it for sockets, with one stated exception (SetFileCompletionNotificationModes): "When the FileHandle parameter is a socket, this mode is only compatible with Layered Service Providers (LSP) that return Installable File Systems (IFS) handles." Ordinary sockets go straight to Windows' built-in TCP/IP provider and aren't affected; a non-IFS LSP is a DLL that some older firewalls and proxies inserted in front of it, and LSPs have been deprecated since Windows 8 and Windows Server 2012. libuv (the I/O library under Node.js) sets the flag on its TCP sockets too, skipping it when it detects a non-IFS LSP (where it sets the flag). The branch could add the same check if you'd like to cover that case.
Activity