Ticket #123 (new defect)
poor interaction with programs that fork or exec
|Reported by:||MtnViewMark||Owned by:|
Haskeline under either defaultBehavior or preferTerm opens /dev/tty. If the program then either forks or execs, this file is left open in the new process (for fork), or for the replacing executable (for exec).
Management of open files is a common issue for programs that fork and/or exec. For those files that the program doesn't want to survive past the fork/exec, the usual method is to a) close such files in the child right after forking, and b) set the FD_CLOEXEC flag on the file descriptors so they are closed on exec (see System.Posix.IO)
Haskeline doesn't give programs enough leverage to do either of these for the /dev/tty file that it opens (and perhaps the history file as well, if that is left open). In forks that aren't expected to interact with the user, /dev/tty is left open. This may leave a connection to a particular terminal open well after the terminal is released by by the original process. In execs the situation can lead to a security breach: The program may have arranged for stdin/stdout/stderr to refer to a new terminal or other files before execing. Haskeline's surviving open of /dev/tty gives the exec'd program access to the original terminal.
I can see two approaches to fixing this:
- Offer a way to create a terminal based Behavior but on a supplied terminal Handle or Fd.
- Expose a way access the terminal Handles Haskeline is using.
In either case, it is almost certainly wrong for such files to survive an exec, and so Haskeline should ensure that all opened files have had
setCloseOnExec :: Fd -> IO () setCloseOnExec fd = setFdOption fd CloseOnExec True
called on their underlying file descriptors.