
#8108: getGroupEntryForID in multi-threaded applications ------------------------------------+------------------------------------- Reporter: redneb | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: libraries/unix | Version: 7.6.3 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: Runtime crash Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- The following program {{{ #!haskell import Control.Monad import Control.Concurrent import System.Posix.User main = do void $ forkIO $ forever $ getGroupEntryForID 0 forever $ getGroupEntryForID 0 }}} segfaults when executed after less than a second. I've confirmed this with HP-2013.2.0.0/GHC-7.63/unix-2.6.0.1 in many different linuxes as well as Mac OS X 10.8. After some digging I found the reason for this failure. The underlying posix function used by getGroupEntryForID is: {{{ #!c int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result); }}} getgrgid_r returns its result with its last argument which is a pointer to a struct. The struct has to be allocated by the caller as usual. The problem is that the struct contains several strings. This is what the char *buf argument is for; the caller is supposed to allocate a large enough buffer to be used by getgrgid_r to store those strings. Then the caller has to read the struct *before* the auxiliary string buffer is deallocated. What complicates things even more is that we don't know in advance the right size for that buffer; we have to pick an arbitrary size and then keep doubling it while getgrgid_r returns ERANGE. The current implementation of getGroupEntryForID uses allocaBytes to allocate that buffer but then it does not unpack the struct inside the allocaBytes block. The posix functions getgrnam_r, getpwuid_r and getpwnam_r (used by getGroupEntryForName, getUserEntryForID and getUserEntryForName respectively) operate in the same fashion and are susceptible to the same bug. I am really surprised that people haven't been hitting that issue earlier. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8108 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler