haskell-tls / hs-tls

TLS/SSL implementation in haskell
Other
402 stars 87 forks source link

segfault in TLS handshake #72

Closed slrnsc closed 10 years ago

slrnsc commented 10 years ago

The base64-encoded tar.gz below (github does not seem to allow attachments) is a fairly minimal testcase for a segfault. Run with ./run.sh and provide the same password three times before hitting enter for the rest of the key-generation setup. It will open an xterm to show the output of the OpenSSL client. Notably, I cannot produce a crash using the equivalent GnuTLS command (gnutls-cli --no-ca-verification --x509certfile debugmin.crt --x509keyfile debugmin-plaintext.key 127.0.0.1 -p 12342).

The crash is intermittent and may take 5-20 seconds (1-4 tries) to occur. Sometimes the runtime aborts and other times the program segfaults. The backtrace from the abort looks like:

before
debugmin: internal error: scavenge_stack: weird activation record found on stack: 54
    (GHC version 7.8.2 for x86_64_unknown_linux)
    Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff5dff700 (LWP 22754)]
0x00007ffff6ab1d67 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff6ab1d67 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff6ab3118 in abort () from /usr/lib/libc.so.6
#2  0x00000000007158b1 in rtsFatalInternalErrorFn ()
#3  0x00000000007154e9 in barf ()
#4  0x0000000000761483 in scavenge_stack ()
#5  0x0000000000760abd in scavenge_one ()
#6  0x0000000000761558 in scavenge_large ()
#7  0x000000000076166f in scavenge_find_work ()
#8  0x0000000000761791 in scavenge_loop1 ()
#9  0x00000000007315c3 in scavenge_until_all_done ()
#10 0x0000000000730296 in GarbageCollect ()
#11 0x000000000071ba22 in scheduleDoGC ()
#12 0x000000000071a300 in schedule ()
#13 0x000000000071caff in scheduleWorker ()
#14 0x000000000072c233 in workerStart ()
#15 0x00007ffff75b6124 in start_thread () from /usr/lib/libpthread.so.0
#16 0x00007ffff6b674bd in clone () from /usr/lib/libc.so.6
(gdb) q

debug.tar.gz:

H4sIALyXkFMAA+1YbW/bNhDOV+tXXL1gs5HIsZzYxpKlQGCna7HECeJiLyiKgJFoS7MkaiTdxBj6
33dH2hadJuiANemA6oBE4vHejw9JOeI38+ne1pNSG6nf7dIz6HfbZhwcHJjnkraCzv7BQRDs93r9
rXbQ7nWDLeg+bViW5kozCbCViegzclyq5wjoeSky/c/YjPszvlAtFX95H6b/QfBo/7vY7GX/O/02
9X+/3cP+t798KJ/SN97/717s3ST5noo9T3ENPr/zcpbxY7MusiT3PFHwXKkUpjwvcImAz7jqdHv4
TKdCJjrOQCoGvphrqG+TcgvF6ms9M5nk7pwr7BcpS3LN77RVK/X4X+Dn/BZoYT4svOE0VLJ0etdt
/wi+MRGxhYL9XtcNgmTBV8k0/5e2pcbIQrbBeETv5VpGZFhaHlntr93oR8jif9XtVvwUS5ww3rN4
fwj/+72g4+z/HcR/p98/qPD/HIRpz1MO57iE4TbmkntJVgipYcT1rZCze8PWWIQzrlfcgci1FGnr
XOQsus/EZziXkuf6vpG3Z+MHWK3TOy3Z2opcFFq0rlgeiWzFHDLNWr8jtj9htF4lKd/gDvmEzVPd
GqRMKc/LFq/Qz5sLOIaJefF8/x7vYrzJSyJUo8IcHgIyGk07OoZIeLUUd8sbpjgO6yv41C2bDlJk
/0KPhpHZ2YG62QaaDuPextHckHX3jqZXu8V91pZeDQVsmwhqaaI0zwdpgiVWWEDjGPmYC//AJYrp
WHIWDXnKFhCsjlvP+0QREzTR+i+XiT5o2snclPkYCLUdr6YwMvjJB2UihJNX129Gp297MNboPoPI
duJSCi1CkaI81zaZi0InIjd6cMURYidRJCHwaph8ZNkNkiT2m5zrnnXchmTUOxkOr65PRn9AG+tj
47UaqF7MNfo+w/3eTiT5FHuzbu02lCViYcgLbTNdJ0p2jvAE0nOZUzm8+1JOwWwmZekeNcj1soCN
eDcWSu9eN6loKwRYvaUkpiBEStMhllDzU4JUsbgUVD5kRWo5F6GXhKVngkUEA2iQuwHHIm0bz03L
uZTJBwx4xfRq5oBEE7Q+xngO8uji5k8ertQcCxjKUnkpjq8EtuX0pmUMziRu9FG+MclYAY0XL9pN
lHjMWamyCnqJOCt8esdQluaTSYKHMG/aRWjq8AMWNSTc2KqICQLgjE80cCmpKfgQ1Oc6Ocd1AJQN
2iBHh1Df2UEBVLlKprEGMSMVMbP2daoumWQZLfwxl7he7BDF/wZlGL+xXDvhH8NbOec4v7ucfy3E
jNQbiAFKalxym47Y4MTJjuSpPc788PXpOpKR0DHm4cyOY4a5u14MgxxQoGYwWC8VsuGO3tkyvoeP
rsl5QUjbtLrirQyvxr/iyYgwJsPvcMUHnfcksFsKDJICjxaaD+3bPNH8WuGSNnnUyDP+Yb3p7MAN
0Sxu+zrCG2DstKIRFnI6MKAAgxGKbIEgz65GPzcdkDciAeU+cMMJ8vUjiPFAwZLMOJTujhxBNtFc
0pbroD/C88Ti3e7qHma/Rgn6JzhcMh17mLSLiQemnMWyMfvxK10Q7f3vHOsxwViexsdn7n/tg6D8
/t/v0Pdfp9PvVve/56CbeZJGh1B+7q3eSh5+FHi1aRyCb68TuCn4Zg4/sLQShVYbomsLdKs59Gqt
jV8XPI9eHOM4xC+rlLMcZbcbV+fN9VwphLcgZ6Dkhroz49ya1tzNa1YpLJyok//r59mTk8W/nOdP
8suPpc/9/tPplvjv4odfOwj6/V6F/+cg5/efYpakqbMTEGzNP3uzu8NzMQOfQ/02puufxpvOEd5n
YfWbi7q2dz/wQzreWnsP49LHgz2ny18qQpbSRfjQfEYcgUo5L6BLRnNeh++90sQ3i8+KKqqooooq
qqiiiiqqqKKKKqqoov9K/wBO3UdpACgAAA==
slrnsc commented 10 years ago

ghc 7.9 seems to fix this.

benmos commented 9 years ago

For anyone wanting to quickly glance at the Haskell code contained above, it's:

module Main where
import Network
import Network.Socket
import Control.Monad
import Control.Concurrent
import Network.TLS
import Network.TLS.Extra
import Crypto.Random
import Data.X509
import Data.X509.File
import Data.Default.Class

myForkIO = forkIO
--myForkIO = forkOS
--myForkIO = id

main :: IO ()
main = do
    let base = "debugmin"
    let keys = Keys (base ++ ".crt") (base ++ "-plaintext.key") (base ++ ".combined.crt")
    withSocketsDo $ do
        listenClientsTLS keys
        forever $ threadDelay 100000000

listenClientsTLS :: Keys -> IO ()
listenClientsTLS keys = do
    let port = 12342
    sock <- socket AF_INET6 Stream defaultProtocol
    setSocketOption sock ReuseAddr 1
    bind sock (SockAddrInet6 port 0 iN6ADDR_ANY 0)
    listen sock 1
    putStrLn "listening"
    myForkIO $ forever $ acceptClientTLS keys sock; return ()

acceptClientTLS :: Keys -> Socket -> IO ()
acceptClientTLS keys socket = do
    (h,host,_) <- Network.accept socket
    pool <- createEntropyPool
    creds <- credentialLoadX509 (keysCert $ keys) (keysPrivKey $ keys)
    x509 <- readSignedObject $ keysCert $ keys
    privKey <- readKeyFile $ keysPrivKey $ keys
    clientCert <- (fmap (!!0) $ readSignedObject $ keysClientCert $ keys) :: IO (SignedExact Certificate)
    let creds' = case creds of
        Left err -> error $ "reading private key: "++err
        Right ok -> ok
    let tlsParams = ServerParams
        { serverWantClientCert = True
        , serverHooks = (def :: ServerHooks)
        , serverCACertificates = x509
        , serverDHEParams = Nothing
        , serverShared = (def :: Shared)
            { sharedCredentials = Credentials [creds'] }
        , serverSupported = (def :: Supported)
            { supportedVersions = [TLS12]
            , supportedCiphers = ciphersuite_strong
            }
        }
    tlsContext <- contextNew h tlsParams (cprgCreate pool :: SystemRNG)
    myForkIO (do putStrLn "before"; handshake tlsContext; putStrLn "after")
    return ()

data Keys = Keys
    { keysCert :: FilePath
    , keysPrivKey :: FilePath
    , keysClientCert :: FilePath
    }