@@ -476,6 +476,10 @@ reset_signal_handlers(const sigset_t *child_sigmask)
476
476
#endif /* VFORK_USABLE */
477
477
478
478
479
+ /* To avoid signeness churn on platforms where gid and uid are unsigned. */
480
+ #define RESERVED_GID (gid_t)-1
481
+ #define RESERVED_UID (uid_t)-1
482
+
479
483
/*
480
484
* This function is code executed in the child process immediately after
481
485
* (v)fork to set things up and call exec().
@@ -518,9 +522,9 @@ child_exec(char *const exec_array[],
518
522
int errpipe_read , int errpipe_write ,
519
523
int close_fds , int restore_signals ,
520
524
int call_setsid , pid_t pgid_to_set ,
521
- int call_setgid , gid_t gid ,
522
- int call_setgroups , size_t groups_size , const gid_t * groups ,
523
- int call_setuid , uid_t uid , int child_umask ,
525
+ gid_t gid ,
526
+ size_t groups_size , const gid_t * groups ,
527
+ uid_t uid , int child_umask ,
524
528
const void * child_sigmask ,
525
529
PyObject * py_fds_to_keep ,
526
530
PyObject * preexec_fn ,
@@ -619,17 +623,17 @@ child_exec(char *const exec_array[],
619
623
#endif
620
624
621
625
#ifdef HAVE_SETGROUPS
622
- if (call_setgroups )
626
+ if (groups )
623
627
POSIX_CALL (setgroups (groups_size , groups ));
624
628
#endif /* HAVE_SETGROUPS */
625
629
626
630
#ifdef HAVE_SETREGID
627
- if (call_setgid )
631
+ if (gid != RESERVED_GID )
628
632
POSIX_CALL (setregid (gid , gid ));
629
633
#endif /* HAVE_SETREGID */
630
634
631
635
#ifdef HAVE_SETREUID
632
- if (call_setuid )
636
+ if (uid != RESERVED_UID )
633
637
POSIX_CALL (setreuid (uid , uid ));
634
638
#endif /* HAVE_SETREUID */
635
639
@@ -724,9 +728,9 @@ do_fork_exec(char *const exec_array[],
724
728
int errpipe_read , int errpipe_write ,
725
729
int close_fds , int restore_signals ,
726
730
int call_setsid , pid_t pgid_to_set ,
727
- int call_setgid , gid_t gid ,
728
- int call_setgroups , size_t groups_size , const gid_t * groups ,
729
- int call_setuid , uid_t uid , int child_umask ,
731
+ gid_t gid ,
732
+ size_t groups_size , const gid_t * groups ,
733
+ uid_t uid , int child_umask ,
730
734
const void * child_sigmask ,
731
735
PyObject * py_fds_to_keep ,
732
736
PyObject * preexec_fn ,
@@ -737,10 +741,7 @@ do_fork_exec(char *const exec_array[],
737
741
738
742
#ifdef VFORK_USABLE
739
743
if (child_sigmask ) {
740
- /* These are checked by our caller; verify them in debug builds. */
741
- assert (!call_setuid );
742
- assert (!call_setgid );
743
- assert (!call_setgroups );
744
+ /* Checked by our caller; verify this in debug builds. */
744
745
assert (preexec_fn == Py_None );
745
746
746
747
pid = vfork ();
@@ -777,8 +778,8 @@ do_fork_exec(char *const exec_array[],
777
778
p2cread , p2cwrite , c2pread , c2pwrite ,
778
779
errread , errwrite , errpipe_read , errpipe_write ,
779
780
close_fds , restore_signals , call_setsid , pgid_to_set ,
780
- call_setgid , gid , call_setgroups , groups_size , groups ,
781
- call_setuid , uid , child_umask , child_sigmask ,
781
+ gid , groups_size , groups ,
782
+ uid , child_umask , child_sigmask ,
782
783
py_fds_to_keep , preexec_fn , preexec_fn_args_tuple );
783
784
_exit (255 );
784
785
return 0 ; /* Dead code to avoid a potential compiler warning. */
@@ -799,9 +800,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
799
800
int errpipe_read , errpipe_write , close_fds , restore_signals ;
800
801
int call_setsid ;
801
802
pid_t pgid_to_set = -1 ;
802
- int call_setgid = 0 , call_setgroups = 0 , call_setuid = 0 ;
803
- uid_t uid ;
804
- gid_t gid , * groups = NULL ;
803
+ gid_t * groups = NULL ;
805
804
int child_umask ;
806
805
PyObject * cwd_obj , * cwd_obj2 = NULL ;
807
806
const char * cwd ;
@@ -951,34 +950,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
951
950
}
952
951
Py_DECREF (elem );
953
952
}
954
- call_setgroups = 1 ;
955
953
956
954
#else /* HAVE_SETGROUPS */
957
955
PyErr_BadInternalCall ();
958
956
goto cleanup ;
959
957
#endif /* HAVE_SETGROUPS */
960
958
}
961
959
960
+ gid_t gid = RESERVED_GID ;
962
961
if (gid_object != Py_None ) {
963
962
#ifdef HAVE_SETREGID
964
963
if (!_Py_Gid_Converter (gid_object , & gid ))
965
964
goto cleanup ;
966
965
967
- call_setgid = 1 ;
968
-
969
966
#else /* HAVE_SETREGID */
970
967
PyErr_BadInternalCall ();
971
968
goto cleanup ;
972
969
#endif /* HAVE_SETREUID */
973
970
}
974
971
972
+ uid_t uid = RESERVED_UID ;
975
973
if (uid_object != Py_None ) {
976
974
#ifdef HAVE_SETREUID
977
975
if (!_Py_Uid_Converter (uid_object , & uid ))
978
976
goto cleanup ;
979
977
980
- call_setuid = 1 ;
981
-
982
978
#else /* HAVE_SETREUID */
983
979
PyErr_BadInternalCall ();
984
980
goto cleanup ;
@@ -1002,7 +998,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
1002
998
/* Use vfork() only if it's safe. See the comment above child_exec(). */
1003
999
sigset_t old_sigs ;
1004
1000
if (preexec_fn == Py_None && allow_vfork &&
1005
- ! call_setuid && ! call_setgid && ! call_setgroups ) {
1001
+ uid == RESERVED_UID && gid == RESERVED_GID && groups_list == Py_None ) {
1006
1002
/* Block all signals to ensure that no signal handlers are run in the
1007
1003
* child process while it shares memory with us. Note that signals
1008
1004
* used internally by C libraries won't be blocked by
@@ -1025,8 +1021,8 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
1025
1021
p2cread , p2cwrite , c2pread , c2pwrite ,
1026
1022
errread , errwrite , errpipe_read , errpipe_write ,
1027
1023
close_fds , restore_signals , call_setsid , pgid_to_set ,
1028
- call_setgid , gid , call_setgroups , num_groups , groups ,
1029
- call_setuid , uid , child_umask , old_sigmask ,
1024
+ gid , num_groups , groups_list != Py_None ? groups : NULL ,
1025
+ uid , child_umask , old_sigmask ,
1030
1026
py_fds_to_keep , preexec_fn , preexec_fn_args_tuple );
1031
1027
1032
1028
/* Parent (original) process */
0 commit comments