From bc4e5e6c2ec3d23020d977117a70717f543674e8 Mon Sep 17 00:00:00 2001 From: jprider63 Date: Tue, 13 Oct 2015 22:43:21 -0400 Subject: [PATCH 1/4] Added child_user and child_group to CreateProcess for unix. --- System/Process.hsc | 8 ++++++-- System/Process/Internals.hs | 21 +++++++++++++++++++-- cbits/runProcess.c | 24 ++++++++++++++++++++++++ include/runProcess.h | 2 ++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/System/Process.hsc b/System/Process.hsc index 4de9a264..a390c743 100644 --- a/System/Process.hsc +++ b/System/Process.hsc @@ -126,7 +126,9 @@ proc cmd args = CreateProcess { cmdspec = RawCommand cmd args, delegate_ctlc = False, detach_console = False, create_new_console = False, - new_session = False } + new_session = False, + child_group = Nothing, + child_user = Nothing } -- | Construct a 'CreateProcess' record for passing to 'createProcess', -- representing a command to be passed to the shell. @@ -142,7 +144,9 @@ shell str = CreateProcess { cmdspec = ShellCommand str, delegate_ctlc = False, detach_console = False, create_new_console = False, - new_session = False } + new_session = False, + child_group = Nothing, + child_user = Nothing } {- | This is the most general way to spawn an external process. The diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs index 40f2f92b..7d65546e 100644 --- a/System/Process/Internals.hs +++ b/System/Process/Internals.hs @@ -190,9 +190,19 @@ data CreateProcess = CreateProcess{ -- Default: @False@ -- -- @since 1.3.0.0 - new_session :: Bool -- ^ Use posix setsid to start the new process in a new session; does nothing on other platforms. + new_session :: Bool, -- ^ Use posix setsid to start the new process in a new session; does nothing on other platforms. -- -- @since 1.3.0.0 + child_group :: Maybe GroupID, -- ^ Use posix setgid to set child process's group id; does nothing on other platforms. + -- + -- Default: @Nothing@ + -- + -- @since X.X.X.X + child_user :: Maybe UserID -- ^ Use posix setuid to set child process's user id; does nothing on other platforms. + -- + -- Default: @Nothing@ + -- + -- @since X.X.X.X } data CmdSpec @@ -273,7 +283,9 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, delegate_ctlc = mb_delegate_ctlc, detach_console = mb_detach_console, create_new_console = mb_create_new_console, - new_session = mb_new_session } + new_session = mb_new_session, + child_group = mb_child_group, + child_user = mb_child_user } = do let (cmd,args) = commandToProcess cmdsp withFilePathException cmd $ @@ -283,6 +295,8 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, alloca $ \ pFailedDoing -> maybeWith withCEnvironment mb_env $ \pEnv -> maybeWith withFilePath mb_cwd $ \pWorkDir -> + maybeWith with mb_child_group $ \pChildGroup -> + maybeWith with mb_child_user $ \pChildUser -> withMany withFilePath (cmd:args) $ \cstrs -> withArray0 nullPtr cstrs $ \pargs -> do @@ -301,6 +315,7 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, c_runInteractiveProcess pargs pWorkDir pEnv fdin fdout fderr pfdStdInput pfdStdOutput pfdStdError + pChildGroup pChildUser (if mb_delegate_ctlc then 1 else 0) ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0) .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0) @@ -414,6 +429,8 @@ foreign import ccall unsafe "runInteractiveProcess" -> Ptr FD -> Ptr FD -> Ptr FD + -> Ptr CGid + -> Ptr CUid -> CInt -- reset child's SIGINT & SIGQUIT handlers -> CInt -- flags -> Ptr CString diff --git a/cbits/runProcess.c b/cbits/runProcess.c index 80196051..950635dc 100644 --- a/cbits/runProcess.c +++ b/cbits/runProcess.c @@ -40,6 +40,10 @@ extern void unblockUserSignals(void); #define forkChdirFailed 126 #define forkExecFailed 127 +// These are arbitrarily chosen -- JP +#define forkSetgidFailed 124 +#define forkSetuidFailed 125 + __attribute__((__noreturn__)) static void childFailed(int pipe, int failCode) { int err; @@ -57,6 +61,7 @@ runInteractiveProcess (char *const args[], char *workingDirectory, char **environment, int fdStdIn, int fdStdOut, int fdStdErr, int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, + gid_t *childGroup, uid_t *childUser, int reset_int_quit_handlers, int flags, char **failed_doing) @@ -144,6 +149,20 @@ runInteractiveProcess (char *const args[], if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) { setpgid(0, 0); } + + if ( childGroup) { + if ( setgid( *childGroup) != 0) { + // ERROR + childFailed(forkCommunicationFds[1], forkSetgidFailed); + } + } + + if ( childUser) { + if ( setuid( *childUser) != 0) { + // ERROR + childFailed(forkCommunicationFds[1], forkSetuidFailed); + } + } unblockUserSignals(); @@ -281,6 +300,11 @@ runInteractiveProcess (char *const args[], case forkExecFailed: *failed_doing = "runInteractiveProcess: exec"; break; + case forkSetgidFailed: + *failed_doing = "runInteractiveProcess: setgid"; + break; + case forkSetuidFailed: + *failed_doing = "runInteractiveProcess: setuid"; default: *failed_doing = "runInteractiveProcess: unknown"; break; diff --git a/include/runProcess.h b/include/runProcess.h index 63f1f237..d35e3e4f 100644 --- a/include/runProcess.h +++ b/include/runProcess.h @@ -62,6 +62,8 @@ extern ProcHandle runInteractiveProcess( char *const args[], int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, + gid_t *childGroup, + uid_t *childUser, int reset_int_quit_handlers, int flags, char **failed_doing); From 932fe345925950da9c9f6afd254d494257f2fa2b Mon Sep 17 00:00:00 2001 From: jprider63 Date: Wed, 14 Oct 2015 08:26:53 -0400 Subject: [PATCH 2/4] Addresses comments from #45. Feel free to squash. --- System/Process/Internals.hs | 14 +++++++------- cbits/runProcess.c | 10 +++++----- include/runProcess.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs index 7d65546e..f9a5800f 100644 --- a/System/Process/Internals.hs +++ b/System/Process/Internals.hs @@ -197,12 +197,12 @@ data CreateProcess = CreateProcess{ -- -- Default: @Nothing@ -- - -- @since X.X.X.X + -- @since 1.4.0.0 child_user :: Maybe UserID -- ^ Use posix setuid to set child process's user id; does nothing on other platforms. -- -- Default: @Nothing@ -- - -- @since X.X.X.X + -- @since 1.4.0.0 } data CmdSpec @@ -295,8 +295,8 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, alloca $ \ pFailedDoing -> maybeWith withCEnvironment mb_env $ \pEnv -> maybeWith withFilePath mb_cwd $ \pWorkDir -> - maybeWith with mb_child_group $ \pChildGroup -> - maybeWith with mb_child_user $ \pChildUser -> + let childGroup = maybe (-1) id mb_child_group in + let childUser = maybe (-1) id mb_child_user in withMany withFilePath (cmd:args) $ \cstrs -> withArray0 nullPtr cstrs $ \pargs -> do @@ -315,7 +315,7 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, c_runInteractiveProcess pargs pWorkDir pEnv fdin fdout fderr pfdStdInput pfdStdOutput pfdStdError - pChildGroup pChildUser + childGroup childUser (if mb_delegate_ctlc then 1 else 0) ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0) .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0) @@ -429,8 +429,8 @@ foreign import ccall unsafe "runInteractiveProcess" -> Ptr FD -> Ptr FD -> Ptr FD - -> Ptr CGid - -> Ptr CUid + -> CGid + -> CUid -> CInt -- reset child's SIGINT & SIGQUIT handlers -> CInt -- flags -> Ptr CString diff --git a/cbits/runProcess.c b/cbits/runProcess.c index 950635dc..90590045 100644 --- a/cbits/runProcess.c +++ b/cbits/runProcess.c @@ -61,7 +61,7 @@ runInteractiveProcess (char *const args[], char *workingDirectory, char **environment, int fdStdIn, int fdStdOut, int fdStdErr, int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, - gid_t *childGroup, uid_t *childUser, + gid_t childGroup, uid_t childUser, int reset_int_quit_handlers, int flags, char **failed_doing) @@ -150,15 +150,15 @@ runInteractiveProcess (char *const args[], setpgid(0, 0); } - if ( childGroup) { - if ( setgid( *childGroup) != 0) { + if ( childGroup != -1) { + if ( setgid( childGroup) != 0) { // ERROR childFailed(forkCommunicationFds[1], forkSetgidFailed); } } - if ( childUser) { - if ( setuid( *childUser) != 0) { + if ( childUser != -1) { + if ( setuid( childUser) != 0) { // ERROR childFailed(forkCommunicationFds[1], forkSetuidFailed); } diff --git a/include/runProcess.h b/include/runProcess.h index d35e3e4f..da27593f 100644 --- a/include/runProcess.h +++ b/include/runProcess.h @@ -62,8 +62,8 @@ extern ProcHandle runInteractiveProcess( char *const args[], int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, - gid_t *childGroup, - uid_t *childUser, + gid_t childGroup, + uid_t childUser, int reset_int_quit_handlers, int flags, char **failed_doing); From 296535ef2d1b0d6051a1db8adf402549acd87557 Mon Sep 17 00:00:00 2001 From: jprider63 Date: Wed, 14 Oct 2015 10:20:51 -0400 Subject: [PATCH 3/4] Revert "Addresses comments from #45. Feel free to squash." This reverts commit 932fe345925950da9c9f6afd254d494257f2fa2b. --- System/Process/Internals.hs | 14 +++++++------- cbits/runProcess.c | 10 +++++----- include/runProcess.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs index f9a5800f..7d65546e 100644 --- a/System/Process/Internals.hs +++ b/System/Process/Internals.hs @@ -197,12 +197,12 @@ data CreateProcess = CreateProcess{ -- -- Default: @Nothing@ -- - -- @since 1.4.0.0 + -- @since X.X.X.X child_user :: Maybe UserID -- ^ Use posix setuid to set child process's user id; does nothing on other platforms. -- -- Default: @Nothing@ -- - -- @since 1.4.0.0 + -- @since X.X.X.X } data CmdSpec @@ -295,8 +295,8 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, alloca $ \ pFailedDoing -> maybeWith withCEnvironment mb_env $ \pEnv -> maybeWith withFilePath mb_cwd $ \pWorkDir -> - let childGroup = maybe (-1) id mb_child_group in - let childUser = maybe (-1) id mb_child_user in + maybeWith with mb_child_group $ \pChildGroup -> + maybeWith with mb_child_user $ \pChildUser -> withMany withFilePath (cmd:args) $ \cstrs -> withArray0 nullPtr cstrs $ \pargs -> do @@ -315,7 +315,7 @@ createProcess_ fun CreateProcess{ cmdspec = cmdsp, c_runInteractiveProcess pargs pWorkDir pEnv fdin fdout fderr pfdStdInput pfdStdOutput pfdStdError - childGroup childUser + pChildGroup pChildUser (if mb_delegate_ctlc then 1 else 0) ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0) .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0) @@ -429,8 +429,8 @@ foreign import ccall unsafe "runInteractiveProcess" -> Ptr FD -> Ptr FD -> Ptr FD - -> CGid - -> CUid + -> Ptr CGid + -> Ptr CUid -> CInt -- reset child's SIGINT & SIGQUIT handlers -> CInt -- flags -> Ptr CString diff --git a/cbits/runProcess.c b/cbits/runProcess.c index 90590045..950635dc 100644 --- a/cbits/runProcess.c +++ b/cbits/runProcess.c @@ -61,7 +61,7 @@ runInteractiveProcess (char *const args[], char *workingDirectory, char **environment, int fdStdIn, int fdStdOut, int fdStdErr, int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, - gid_t childGroup, uid_t childUser, + gid_t *childGroup, uid_t *childUser, int reset_int_quit_handlers, int flags, char **failed_doing) @@ -150,15 +150,15 @@ runInteractiveProcess (char *const args[], setpgid(0, 0); } - if ( childGroup != -1) { - if ( setgid( childGroup) != 0) { + if ( childGroup) { + if ( setgid( *childGroup) != 0) { // ERROR childFailed(forkCommunicationFds[1], forkSetgidFailed); } } - if ( childUser != -1) { - if ( setuid( childUser) != 0) { + if ( childUser) { + if ( setuid( *childUser) != 0) { // ERROR childFailed(forkCommunicationFds[1], forkSetuidFailed); } diff --git a/include/runProcess.h b/include/runProcess.h index da27593f..d35e3e4f 100644 --- a/include/runProcess.h +++ b/include/runProcess.h @@ -62,8 +62,8 @@ extern ProcHandle runInteractiveProcess( char *const args[], int *pfdStdInput, int *pfdStdOutput, int *pfdStdError, - gid_t childGroup, - uid_t childUser, + gid_t *childGroup, + uid_t *childUser, int reset_int_quit_handlers, int flags, char **failed_doing); From 2397d4f63417776fffde61b62ba5d6518a1cb8f5 Mon Sep 17 00:00:00 2001 From: jprider63 Date: Wed, 14 Oct 2015 10:22:11 -0400 Subject: [PATCH 4/4] Updated `CreateProcess` documentation after revert. --- System/Process/Internals.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs index 7d65546e..bbf6e375 100644 --- a/System/Process/Internals.hs +++ b/System/Process/Internals.hs @@ -197,12 +197,12 @@ data CreateProcess = CreateProcess{ -- -- Default: @Nothing@ -- - -- @since X.X.X.X + -- @since 1.4.0.0 child_user :: Maybe UserID -- ^ Use posix setuid to set child process's user id; does nothing on other platforms. -- -- Default: @Nothing@ -- - -- @since X.X.X.X + -- @since 1.4.0.0 } data CmdSpec