@@ -518,9 +518,9 @@ child_exec(char *const exec_array[],
518
518
int errpipe_read , int errpipe_write ,
519
519
int close_fds , int restore_signals ,
520
520
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 ,
521
+ gid_t gid ,
522
+ Py_ssize_t groups_size , const gid_t * groups ,
523
+ uid_t uid , int child_umask ,
524
524
const void * child_sigmask ,
525
525
PyObject * py_fds_to_keep ,
526
526
PyObject * preexec_fn ,
@@ -619,17 +619,17 @@ child_exec(char *const exec_array[],
619
619
#endif
620
620
621
621
#ifdef HAVE_SETGROUPS
622
- if (call_setgroups )
622
+ if (groups_size > 0 )
623
623
POSIX_CALL (setgroups (groups_size , groups ));
624
624
#endif /* HAVE_SETGROUPS */
625
625
626
626
#ifdef HAVE_SETREGID
627
- if (call_setgid )
627
+ if (gid != ( gid_t ) - 1 )
628
628
POSIX_CALL (setregid (gid , gid ));
629
629
#endif /* HAVE_SETREGID */
630
630
631
631
#ifdef HAVE_SETREUID
632
- if (call_setuid )
632
+ if (uid != ( uid_t ) - 1 )
633
633
POSIX_CALL (setreuid (uid , uid ));
634
634
#endif /* HAVE_SETREUID */
635
635
@@ -724,9 +724,9 @@ do_fork_exec(char *const exec_array[],
724
724
int errpipe_read , int errpipe_write ,
725
725
int close_fds , int restore_signals ,
726
726
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 ,
727
+ gid_t gid ,
728
+ Py_ssize_t groups_size , const gid_t * groups ,
729
+ uid_t uid , int child_umask ,
730
730
const void * child_sigmask ,
731
731
PyObject * py_fds_to_keep ,
732
732
PyObject * preexec_fn ,
@@ -738,9 +738,9 @@ do_fork_exec(char *const exec_array[],
738
738
#ifdef VFORK_USABLE
739
739
if (child_sigmask ) {
740
740
/* These are checked by our caller; verify them in debug builds. */
741
- assert (! call_setuid );
742
- assert (! call_setgid );
743
- assert (! call_setgroups );
741
+ assert (uid == ( uid_t ) - 1 );
742
+ assert (gid == ( gid_t ) - 1 );
743
+ assert (groups_size < 0 );
744
744
assert (preexec_fn == Py_None );
745
745
746
746
pid = vfork ();
@@ -777,8 +777,8 @@ do_fork_exec(char *const exec_array[],
777
777
p2cread , p2cwrite , c2pread , c2pwrite ,
778
778
errread , errwrite , errpipe_read , errpipe_write ,
779
779
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 ,
780
+ gid , groups_size , groups ,
781
+ uid , child_umask , child_sigmask ,
782
782
py_fds_to_keep , preexec_fn , preexec_fn_args_tuple );
783
783
_exit (255 );
784
784
return 0 ; /* Dead code to avoid a potential compiler warning. */
@@ -799,9 +799,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
799
799
int errpipe_read , errpipe_write , close_fds , restore_signals ;
800
800
int call_setsid ;
801
801
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 ;
802
+ gid_t * groups = NULL ;
805
803
int child_umask ;
806
804
PyObject * cwd_obj , * cwd_obj2 = NULL ;
807
805
const char * cwd ;
@@ -899,9 +897,6 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
899
897
900
898
if (groups_list != Py_None ) {
901
899
#ifdef HAVE_SETGROUPS
902
- Py_ssize_t i ;
903
- gid_t gid ;
904
-
905
900
if (!PyList_Check (groups_list )) {
906
901
PyErr_SetString (PyExc_TypeError ,
907
902
"setgroups argument must be a list" );
@@ -917,13 +912,17 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
917
912
goto cleanup ;
918
913
}
919
914
920
- if ((groups = PyMem_RawMalloc (num_groups * sizeof (gid_t ))) == NULL ) {
921
- PyErr_SetString (PyExc_MemoryError ,
922
- "failed to allocate memory for group list" );
923
- goto cleanup ;
915
+ /* Deliberately keep groups == NULL for num_groups == 0 */
916
+ if (num_groups > 0 ) {
917
+ groups = PyMem_RawMalloc (num_groups * sizeof (gid_t ));
918
+ if (groups == NULL ) {
919
+ PyErr_SetString (PyExc_MemoryError ,
920
+ "failed to allocate memory for group list" );
921
+ goto cleanup ;
922
+ }
924
923
}
925
924
926
- for (i = 0 ; i < num_groups ; i ++ ) {
925
+ for (Py_ssize_t i = 0 ; i < num_groups ; i ++ ) {
927
926
PyObject * elem ;
928
927
elem = PySequence_GetItem (groups_list , i );
929
928
if (!elem )
@@ -934,6 +933,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
934
933
Py_DECREF (elem );
935
934
goto cleanup ;
936
935
} else {
936
+ gid_t gid ;
937
937
if (!_Py_Gid_Converter (elem , & gid )) {
938
938
Py_DECREF (elem );
939
939
PyErr_SetString (PyExc_ValueError , "invalid group id" );
@@ -943,34 +943,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
943
943
}
944
944
Py_DECREF (elem );
945
945
}
946
- call_setgroups = 1 ;
947
946
948
947
#else /* HAVE_SETGROUPS */
949
948
PyErr_BadInternalCall ();
950
949
goto cleanup ;
951
950
#endif /* HAVE_SETGROUPS */
952
951
}
953
952
953
+ gid_t gid = (gid_t )- 1 ;
954
954
if (gid_object != Py_None ) {
955
955
#ifdef HAVE_SETREGID
956
956
if (!_Py_Gid_Converter (gid_object , & gid ))
957
957
goto cleanup ;
958
958
959
- call_setgid = 1 ;
960
-
961
959
#else /* HAVE_SETREGID */
962
960
PyErr_BadInternalCall ();
963
961
goto cleanup ;
964
962
#endif /* HAVE_SETREUID */
965
963
}
966
964
965
+ uid_t uid = (uid_t )- 1 ;
967
966
if (uid_object != Py_None ) {
968
967
#ifdef HAVE_SETREUID
969
968
if (!_Py_Uid_Converter (uid_object , & uid ))
970
969
goto cleanup ;
971
970
972
- call_setuid = 1 ;
973
-
974
971
#else /* HAVE_SETREUID */
975
972
PyErr_BadInternalCall ();
976
973
goto cleanup ;
@@ -994,7 +991,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
994
991
/* Use vfork() only if it's safe. See the comment above child_exec(). */
995
992
sigset_t old_sigs ;
996
993
if (preexec_fn == Py_None && allow_vfork &&
997
- ! call_setuid && ! call_setgid && ! call_setgroups ) {
994
+ uid == ( uid_t ) - 1 && gid == ( gid_t ) - 1 && num_groups < 0 ) {
998
995
/* Block all signals to ensure that no signal handlers are run in the
999
996
* child process while it shares memory with us. Note that signals
1000
997
* used internally by C libraries won't be blocked by
@@ -1017,8 +1014,8 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
1017
1014
p2cread , p2cwrite , c2pread , c2pwrite ,
1018
1015
errread , errwrite , errpipe_read , errpipe_write ,
1019
1016
close_fds , restore_signals , call_setsid , pgid_to_set ,
1020
- call_setgid , gid , call_setgroups , num_groups , groups ,
1021
- call_setuid , uid , child_umask , old_sigmask ,
1017
+ gid , num_groups , groups ,
1018
+ uid , child_umask , old_sigmask ,
1022
1019
py_fds_to_keep , preexec_fn , preexec_fn_args_tuple );
1023
1020
1024
1021
/* Parent (original) process */
0 commit comments