Skip to content

Intermittent crash/hang with TLS on Windows under poor network conditions #191

@enolan

Description

@enolan

I can get a simple http-conduit program to crash or hang fairly often when the connection has occasional data corruption. I've also observed the hang when only simulating packet loss. Here's a repo with my test case. The program is tiny:

module Main where
import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy.Char8 as LC8

main :: IO ()
main = do
    man <- newManager tlsManagerSettings
    req <- parseUrl "https://s3.amazonaws.com/hackage.fpcomplete.com/package/lens-4.12.3.tar.gz"
    response <- httpLbs req man
    LC8.putStrLn $ responseBody response

Using Clumsy in tamper mode set to 20%, it'll crash or hang maybe half the time.

When I instrument API calls with API Monitor I can see that the crashes happen immediately after a call to recv() fails. recv() returns SOCKET_ERROR which is a constant equal to -1. (When it's successful, recv() returns the number of bytes received.) Then memcpy() is called with the length set to -1. This causes the Windows equivalent of a segfault. Somewhere, the return value of recv() isn't getting checked.

The same thing with a cleartext HTTP connection is no problem. I also set up a simple cleartext HTTP server on a Linux machine and injected RSTs with tcpkill. This doesn't make it crash either.

I found this in the course of debugging commercialhaskell/stack#1689 (in the course of getting Idris building on AppVeyor). Stack hasn't ever crashed on me, but it seems likely the hangs and crashes in the simple http-conduit program are related to the hangs in Stack.

To reproduce:

  1. Clone the testcase repo
  2. stack build
  3. Download Clumsy
  4. Set Clumsy parameters to something like this and hit start.
  5. stack exec bad-memcpy-crash

You may have to run it several times. When it crashes you should see the Windows crash dialog and if you have Visual Studio installed, an offer to open a debugger.

Let me know if there's more I can do to figure this out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions