Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-94518: [_posixsubprocess] Replace variable validity flags with reserved values #94687

Merged
merged 14 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``_posixsubprocess`` now initializes all UID and GID variables using a
reserved ``-1`` value instead of a separate flag. Patch by Oleg Iarygin.
44 changes: 18 additions & 26 deletions Modules/_posixsubprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,9 @@ child_exec(char *const exec_array[],
int errpipe_read, int errpipe_write,
int close_fds, int restore_signals,
int call_setsid, pid_t pgid_to_set,
int call_setgid, gid_t gid,
int call_setgroups, size_t groups_size, const gid_t *groups,
int call_setuid, uid_t uid, int child_umask,
gid_t gid,
size_t groups_size, const gid_t *groups,
arhadthedev marked this conversation as resolved.
Show resolved Hide resolved
uid_t uid, int child_umask,
const void *child_sigmask,
PyObject *py_fds_to_keep,
PyObject *preexec_fn,
Expand Down Expand Up @@ -619,17 +619,17 @@ child_exec(char *const exec_array[],
#endif

#ifdef HAVE_SETGROUPS
if (call_setgroups)
if (groups)
gpshead marked this conversation as resolved.
Show resolved Hide resolved
POSIX_CALL(setgroups(groups_size, groups));
#endif /* HAVE_SETGROUPS */

#ifdef HAVE_SETREGID
if (call_setgid)
if (gid != (gid_t)-1)
POSIX_CALL(setregid(gid, gid));
#endif /* HAVE_SETREGID */

#ifdef HAVE_SETREUID
if (call_setuid)
if (uid != (uid_t)-1)
POSIX_CALL(setreuid(uid, uid));
#endif /* HAVE_SETREUID */

Expand Down Expand Up @@ -724,9 +724,9 @@ do_fork_exec(char *const exec_array[],
int errpipe_read, int errpipe_write,
int close_fds, int restore_signals,
int call_setsid, pid_t pgid_to_set,
int call_setgid, gid_t gid,
int call_setgroups, size_t groups_size, const gid_t *groups,
int call_setuid, uid_t uid, int child_umask,
gid_t gid,
size_t groups_size, const gid_t *groups,
gpshead marked this conversation as resolved.
Show resolved Hide resolved
uid_t uid, int child_umask,
const void *child_sigmask,
PyObject *py_fds_to_keep,
PyObject *preexec_fn,
Expand All @@ -737,10 +737,7 @@ do_fork_exec(char *const exec_array[],

#ifdef VFORK_USABLE
if (child_sigmask) {
/* These are checked by our caller; verify them in debug builds. */
assert(!call_setuid);
assert(!call_setgid);
assert(!call_setgroups);
/* Checked by our caller; verify this in debug builds. */
arhadthedev marked this conversation as resolved.
Show resolved Hide resolved
assert(preexec_fn == Py_None);

pid = vfork();
Expand Down Expand Up @@ -777,8 +774,8 @@ do_fork_exec(char *const exec_array[],
p2cread, p2cwrite, c2pread, c2pwrite,
errread, errwrite, errpipe_read, errpipe_write,
close_fds, restore_signals, call_setsid, pgid_to_set,
call_setgid, gid, call_setgroups, groups_size, groups,
call_setuid, uid, child_umask, child_sigmask,
gid, groups_size, groups,
uid, child_umask, child_sigmask,
py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);
_exit(255);
return 0; /* Dead code to avoid a potential compiler warning. */
Expand All @@ -799,9 +796,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
int errpipe_read, errpipe_write, close_fds, restore_signals;
int call_setsid;
pid_t pgid_to_set = -1;
int call_setgid = 0, call_setgroups = 0, call_setuid = 0;
uid_t uid;
gid_t gid, *groups = NULL;
gid_t *groups = NULL;
int child_umask;
PyObject *cwd_obj, *cwd_obj2 = NULL;
const char *cwd;
Expand Down Expand Up @@ -951,34 +946,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
}
arhadthedev marked this conversation as resolved.
Show resolved Hide resolved
Py_DECREF(elem);
}
call_setgroups = 1;

#else /* HAVE_SETGROUPS */
PyErr_BadInternalCall();
goto cleanup;
#endif /* HAVE_SETGROUPS */
}

gid_t gid = (gid_t)-1;
if (gid_object != Py_None) {
#ifdef HAVE_SETREGID
if (!_Py_Gid_Converter(gid_object, &gid))
goto cleanup;

call_setgid = 1;

#else /* HAVE_SETREGID */
PyErr_BadInternalCall();
goto cleanup;
#endif /* HAVE_SETREUID */
}

uid_t uid = (uid_t)-1;
if (uid_object != Py_None) {
#ifdef HAVE_SETREUID
if (!_Py_Uid_Converter(uid_object, &uid))
goto cleanup;

call_setuid = 1;

#else /* HAVE_SETREUID */
PyErr_BadInternalCall();
goto cleanup;
Expand All @@ -1002,7 +994,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
/* Use vfork() only if it's safe. See the comment above child_exec(). */
sigset_t old_sigs;
if (preexec_fn == Py_None && allow_vfork &&
!call_setuid && !call_setgid && !call_setgroups) {
uid == (uid_t)-1 && gid == (gid_t)-1 && groups_list == Py_None) {
gpshead marked this conversation as resolved.
Show resolved Hide resolved
/* Block all signals to ensure that no signal handlers are run in the
* child process while it shares memory with us. Note that signals
* used internally by C libraries won't be blocked by
Expand All @@ -1025,8 +1017,8 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
p2cread, p2cwrite, c2pread, c2pwrite,
errread, errwrite, errpipe_read, errpipe_write,
close_fds, restore_signals, call_setsid, pgid_to_set,
call_setgid, gid, call_setgroups, num_groups, groups,
call_setuid, uid, child_umask, old_sigmask,
gid, num_groups, groups_list != Py_None ? groups : NULL,
uid, child_umask, old_sigmask,
py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);

/* Parent (original) process */
Expand Down