Skip to content

WinIO: socket operations can leave a stale completion packet #638

Open

Description

@thomasjm

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.

Repro: https://github.com/codedownio/network-winio-skip-completion-repro

Possible fix: set FILE_SKIP_COMPLETION_PORT_ON_SUCCESS when a socket is associated (in socket and accept), as GHC does for its own file handles: https://github.com/codedownio/network/tree/winio-skip-completion-on-success.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions