lpeterse / haskell-socket

A Haskell binding to the POSIX sockets API
MIT License
47 stars 10 forks source link

Use after free (probably due to MVar finalizer) #60

Closed lpeterse closed 6 years ago

lpeterse commented 6 years ago

Writing this test for getAddress reveals a use-after-free bug:

group98 :: TestTree
group98  = testGroup "getAddress" [

    testCase "getAddress" $ bracket
      ( socket :: IO (Socket Inet Stream Default) )
      ( \s -> do
          addr <- getAddress s
          assertEqual "" ( SocketAddressInet (inetAddressFromTuple (127,0,0,1)) 8080 ) addr
      ) close
  ]
    getAddress
      getAddress:                                                FAIL
        Exception: eBadFileDescriptor

The result is reproducable and independant from the RTS chosen.

Modifying the test makes the eBadFileDescriptor disappear:

group98 :: TestTree
group98  = testGroup "getAddress" [

    testCase "getAddress" $ bracket
      ( socket :: IO (Socket Inet Stream Default) )
      ( \s -> do
          addr <- getAddress s
          assertEqual "" ( SocketAddressInet (inetAddressFromTuple (127,0,0,1)) 8080 ) addr
      ) ( const $ pure () )
  ]
    getAddress
      getAddress:                                                FAIL
        test/test.hs:442:
        expected: SocketAddressInet {inetAddress = InetAddress 127.0.0.1, inetPort = InetPort 8080}
         but got: SocketAddressInet {inetAddress = InetAddress 0.0.0.0, inetPort = InetPort 0}
lpeterse commented 6 years ago

Wrong argument order for bracket m(