Skip to content

Memory violation bug in System.Posix.Env.putEnv

putEnv frees the marshaled string after calling c_putenv. This leads to unpredictable behavior, as the string becomes part of the environment and should not be freed.

See SUSv2:

  1. .. the string pointed to by string shall become part of the

environment ...

The issue is reproducible with the following QC property:

import           Test.QuickCheck
import           Test.QuickCheck.Property
import           System.Posix.Env
import           Data.IORef
import qualified Data.Map as Map
import           Control.Applicative

isValidKey :: String -> Bool
isValidKey   k = '\NUL' `notElem` k && '=' `notElem` k && (not . null) k

isValidValue :: String -> Bool
isValidValue v = '\NUL' `notElem` v && (not . null) v

main :: IO ()
main = do
  env' <- getEnvironment >>= newIORef . Map.fromList
  quickCheck $ \k v -> isValidKey k ==> isValidValue v ==> morallyDubiousIOProperty $ do
    putEnv (k ++ "=" ++ v)
    modifyIORef env' (Map.insert k v)
    (==) <$> readIORef env' <*> (Map.fromList <$> getEnvironment)
Trac metadata
Trac field Value
Version 7.4.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/unix
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Edited by Simon Hengel
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information