8000 gh-94518: [_posixsubprocess] Replace variable validity flags with reserved values by arhadthedev · Pull Request #94687 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

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

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

Merged
merged 14 commits into from
Jan 14, 2023
Merged
Changes from 1 commit
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
Next Next commit
Replace call_setgid/call_setuid in _posixsubprocess with gid/uid==-1
  • Loading branch information
arhadthedev committed Jul 8, 2022
commit 1b3250e96bd3398f6a79ed85258250fa375f916c
48 changes: 22 additions & 26 deletions Modules/_posixsubprocess.c
10000
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,10 @@ reset_signal_handlers(const sigset_t *child_sigmask)
#endif /* VFORK_USABLE */


/* To avoid signeness churn on platforms where gid and uid are unsigned. */
#define RESERVED_GID (gid_t)-1
#define RESERVED_UID (uid_t)-1

/*
* This function is code executed in the child process immediately after
* (v)fork to set things up and call exec().
Expand Down Expand Up @@ -518,9 +522,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,
uid_t uid, int child_umask,
const void *child_sigmask,
PyObject *py_fds_to_keep,
PyObject *preexec_fn,
Expand Down Expand Up @@ -619,17 +623,17 @@ child_exec(char *const exec_array[],
#endif

#ifdef HAVE_SETGROUPS
if (call_setgroups)
if (groups)
POSIX_CALL(setgroups(groups_size, groups));
#endif /* HAVE_SETGROUPS */

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

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

Expand Down Expand Up @@ -724,9 +728,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,
uid_t uid, int child_umask,
const void *child_sigmask,
PyObject *py_fds_to_keep,
PyObject *preexec_fn,
Expand All @@ -737,10 +741,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. */
assert(preexec_fn == Py_None);

pid = vfork();
Expand Down Expand Up @@ -777,8 +778,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 +800,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 +950,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args)
}
Py_DECREF(elem);
}
call_setgroups = 1;

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

gid_t gid = RESERVED_GID;
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 = RESERVED_UID;
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 +998,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 == RESERVED_UID && gid == RESERVED_GID && groups_list == Py_None) {
/* 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 +1021,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
0