[GHC] #8108: getGroupEntryForID in multi-threaded applications
GHC
ghc-devs at haskell.org
Thu Aug 1 23:58:55 CEST 2013
#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
More information about the ghc-tickets
mailing list