process 1.6.5.1 → 1.6.6.0
raw patch · 8 files changed
+63/−12 lines, 8 filesdep ~Win32
Dependency ranges changed: Win32
Files
- System/Process.hs +2/−2
- System/Process/Common.hs +1/−1
- System/Process/Internals.hs +1/−0
- System/Process/Posix.hs +12/−5
- cbits/runProcess.c +30/−3
- changelog.md +12/−0
- include/runProcess.h +4/−0
- process.cabal +1/−1
System/Process.hs view
@@ -404,8 +404,8 @@ -- @readProcess@, the forked process will be terminated and @readProcess@ will -- wait (block) until the process has been terminated. ----- Output is returned strictly, so this is not suitable for--- interactive applications.+-- Output is returned strictly, so this is not suitable for launching processes+-- that require interaction over the standard file streams. -- -- This function throws an 'IOError' if the process 'ExitCode' is -- anything other than 'ExitSuccess'. If instead you want to get the
System/Process/Common.hs view
@@ -74,7 +74,7 @@ std_in :: StdStream, -- ^ How to determine stdin std_out :: StdStream, -- ^ How to determine stdout std_err :: StdStream, -- ^ How to determine stderr- close_fds :: Bool, -- ^ Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit)+ close_fds :: Bool, -- ^ Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit). This implementation will call close an every fd from 3 to the maximum of open files, which can be slow for high maximum of open files. create_group :: Bool, -- ^ Create a new process group delegate_ctlc:: Bool, -- ^ Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details). --
System/Process/Internals.hs view
@@ -46,6 +46,7 @@ #else pPrPr_disableITimers, c_execvpe, ignoreSignal, defaultSignal,+ runInteractiveProcess_lock, #endif withFilePathException, withCEnvironment, translate,
System/Process/Posix.hs view
@@ -17,6 +17,7 @@ , createPipeInternal , createPipeInternalFd , interruptProcessGroupOfInternal+ , runInteractiveProcess_lock ) where import Control.Concurrent@@ -93,7 +94,7 @@ withCEnvironment :: [(String,String)] -> (Ptr CString -> IO a) -> IO a withCEnvironment envir act = let env' = map (\(name, val) -> name ++ ('=':val)) envir- in withMany withCString env' (\pEnv -> withArray0 nullPtr pEnv act)+ in withMany withFilePath env' (\pEnv -> withArray0 nullPtr pEnv act) -- ----------------------------------------------------------------------------- -- POSIX runProcess with signal handling in the child@@ -138,10 +139,7 @@ when mb_delegate_ctlc startDelegateControlC - -- runInteractiveProcess() blocks signals around the fork().- -- Since blocking/unblocking of signals is a global state- -- operation, we better ensure mutual exclusion of calls to- -- runInteractiveProcess().+ -- See the comment on runInteractiveProcess_lock proc_handle <- withMVar runInteractiveProcess_lock $ \_ -> c_runInteractiveProcess pargs pWorkDir pEnv fdin fdout fderr@@ -174,6 +172,15 @@ } {-# NOINLINE runInteractiveProcess_lock #-}+-- | 'runInteractiveProcess' blocks signals around the fork().+-- Since blocking/unblocking of signals is a global state operation, we need to+-- ensure mutual exclusion of calls to 'runInteractiveProcess'.+-- This lock is exported so that other libraries which also need to fork()+-- (and also need to make the same global state changes) can protect their changes+-- with the same lock.+-- See https://github.com/haskell/process/pull/154.+--+-- @since 1.6.6.0 runInteractiveProcess_lock :: MVar () runInteractiveProcess_lock = unsafePerformIO $ newMVar ()
cbits/runProcess.c view
@@ -33,6 +33,10 @@ extern void blockUserSignals(void); extern void unblockUserSignals(void); +// These are arbitrarily chosen -- JP+#define forkSetgidFailed 124+#define forkSetuidFailed 125+ // See #1593. The convention for the exit code when // exec() fails seems to be 127 (gleened from C's // system()), but there's no equivalent convention for@@ -40,9 +44,8 @@ #define forkChdirFailed 126 #define forkExecFailed 127 -// These are arbitrarily chosen -- JP-#define forkSetgidFailed 124-#define forkSetuidFailed 125+#define forkGetpwuidFailed 128+#define forkInitgroupsFailed 129 __attribute__((__noreturn__)) static void childFailed(int pipe, int failCode) {@@ -182,6 +185,23 @@ } if ( childUser) {+ // Using setuid properly first requires that we initgroups.+ // However, to do this we must know the username of the user we are+ // switching to.+ struct passwd pw;+ struct passwd *res = NULL;+ int buf_len = sysconf(_SC_GETPW_R_SIZE_MAX);+ char *buf = malloc(buf_len);+ gid_t suppl_gid = childGroup ? *childGroup : getgid();+ if ( getpwuid_r(*childUser, &pw, buf, buf_len, &res) != 0) {+ childFailed(forkCommunicationFds[1], forkGetpwuidFailed);+ }+ if ( res == NULL ) {+ childFailed(forkCommunicationFds[1], forkGetpwuidFailed);+ }+ if ( initgroups(res->pw_name, suppl_gid) != 0) {+ childFailed(forkCommunicationFds[1], forkInitgroupsFailed);+ } if ( setuid( *childUser) != 0) { // ERROR childFailed(forkCommunicationFds[1], forkSetuidFailed);@@ -329,6 +349,13 @@ break; case forkSetuidFailed: *failed_doing = "runInteractiveProcess: setuid";+ break;+ case forkGetpwuidFailed:+ *failed_doing = "runInteractiveProcess: getpwuid";+ break;+ case forkInitgroupsFailed:+ *failed_doing = "runInteractiveProcess: initgroups";+ break; default: *failed_doing = "runInteractiveProcess: unknown"; break;
changelog.md view
@@ -1,5 +1,17 @@ # Changelog for [`process` package](http://hackage.haskell.org/package/process) +## 1.6.6.0 *October 2019*++* Fix a potential privilege escalation issue (or, more precisely, privileges+ not being dropped when this was the user's intent) where the groups of the+ spawning process's user would be incorrectly retained due to a missing call to+ `initgroups` [#149].+* Bug fix: Prevent stripping undecodable bytes from environment variables+ when in a non-unicode locale.+ [#152](https://github.com/haskell/process/issues/152)+* Expose `runInteractiveProcess_lock` in `System.Process.Internals`+ [#154](https://github.com/haskell/process/pull/154)+ ## 1.6.5.1 *June 2019* * Version bound bumps
include/runProcess.h view
@@ -21,6 +21,10 @@ #include <unistd.h> #include <sys/types.h>+#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))+#include <pwd.h>+#include <grp.h>+#endif #ifdef HAVE_FCNTL_H #include <fcntl.h>
process.cabal view
@@ -1,5 +1,5 @@ name: process-version: 1.6.5.1+version: 1.6.6.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE