blob: 7d5a7fe17c075e72fee3eb601b431d457c4baddf [file] [log] [blame]
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2#include "Python.h"
Victor Stinner5572ba72011-05-26 14:10:08 +02003#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
4# define _GNU_SOURCE
Gregory P. Smith51ee2702010-12-13 07:59:39 +00005#endif
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00006#include <unistd.h>
Gregory P. Smith51ee2702010-12-13 07:59:39 +00007#include <fcntl.h>
Gregory P. Smith8facece2012-01-21 14:01:08 -08008#ifdef HAVE_SYS_TYPES_H
9#include <sys/types.h>
10#endif
Gregory P. Smithf3751ef2019-10-12 13:24:56 -070011#if defined(HAVE_SYS_STAT_H)
Gregory P. Smith4842efc2012-01-21 21:01:24 -080012#include <sys/stat.h>
13#endif
Gregory P. Smith8facece2012-01-21 14:01:08 -080014#ifdef HAVE_SYS_SYSCALL_H
15#include <sys/syscall.h>
16#endif
Gregory P. Smithf9681772015-04-25 23:43:34 -070017#if defined(HAVE_SYS_RESOURCE_H)
18#include <sys/resource.h>
19#endif
Gregory P. Smith8facece2012-01-21 14:01:08 -080020#ifdef HAVE_DIRENT_H
21#include <dirent.h>
22#endif
Patrick McLean2b2ead72019-09-12 10:15:44 -070023#ifdef HAVE_GRP_H
24#include <grp.h>
25#endif /* HAVE_GRP_H */
26
27#include "posixmodule.h"
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000028
Gregory P. Smith3015fb82018-11-12 22:01:22 -080029#ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -080030# include <sanitizer/msan_interface.h>
31#endif
32
Xavier de Gayec716f182016-06-15 11:35:29 +020033#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64)
Gregory P. Smithefeb9da2014-04-14 13:31:21 -070034# include <sys/linux-syscalls.h>
35# define SYS_getdents64 __NR_getdents64
36#endif
37
Jakub Kulík6f9bc722018-12-31 03:16:40 +010038#if defined(__sun) && defined(__SVR4)
Gregory P. Smithe3f78482012-01-21 15:16:17 -080039/* readdir64 is used to work around Solaris 9 bug 6395699. */
40# define readdir readdir64
41# define dirent dirent64
42# if !defined(HAVE_DIRFD)
Gregory P. Smith8facece2012-01-21 14:01:08 -080043/* Some versions of Solaris lack dirfd(). */
Gregory P. Smithe9b7cab2012-01-21 15:19:11 -080044# define dirfd(dirp) ((dirp)->dd_fd)
Gregory P. Smithe3f78482012-01-21 15:16:17 -080045# define HAVE_DIRFD
Gregory P. Smithe3f78482012-01-21 15:16:17 -080046# endif
Gregory P. Smith8facece2012-01-21 14:01:08 -080047#endif
48
Gregory P. Smith4842efc2012-01-21 21:01:24 -080049#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__))
50# define FD_DIR "/dev/fd"
51#else
52# define FD_DIR "/proc/self/fd"
53#endif
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000054
Patrick McLean2b2ead72019-09-12 10:15:44 -070055#ifdef NGROUPS_MAX
56#define MAX_GROUPS NGROUPS_MAX
57#else
58#define MAX_GROUPS 64
59#endif
60
Victor Stinnerdaf45552013-08-28 00:53:59 +020061#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000062
Dino Viehland5a7d2e12019-09-10 12:01:20 +010063typedef struct {
64 PyObject* disable;
65 PyObject* enable;
66 PyObject* isenabled;
67} _posixsubprocessstate;
68
69static struct PyModuleDef _posixsubprocessmodule;
70
Hai Shif707d942020-03-16 21:15:01 +080071static inline _posixsubprocessstate*
72get_posixsubprocess_state(PyObject *module)
73{
74 void *state = PyModule_GetState(module);
75 assert(state != NULL);
76 return (_posixsubprocessstate *)state;
77}
78
79#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000080
Martin Panterafdd5132015-11-30 02:21:41 +000081/* If gc was disabled, call gc.enable(). Return 0 on success. */
Benjamin Peterson91eef982012-01-22 20:04:46 -050082static int
Martin Panterafdd5132015-11-30 02:21:41 +000083_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +000084{
85 PyObject *result;
Martin Panterafdd5132015-11-30 02:21:41 +000086 PyObject *exctype, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020087
Martin Panterafdd5132015-11-30 02:21:41 +000088 if (need_to_reenable_gc) {
89 PyErr_Fetch(&exctype, &val, &tb);
Petr Viktorinffd97532020-02-11 17:46:57 +010090 result = PyObject_CallMethodNoArgs(
Dino Viehland5a7d2e12019-09-10 12:01:20 +010091 gc_module, _posixsubprocessstate_global->enable);
Martin Panterafdd5132015-11-30 02:21:41 +000092 if (exctype != NULL) {
93 PyErr_Restore(exctype, val, tb);
94 }
95 if (result == NULL) {
96 return 1;
97 }
98 Py_DECREF(result);
99 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000100 return 0;
101}
102
103
Gregory P. Smith8facece2012-01-21 14:01:08 -0800104/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500105static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200106_pos_int_from_ascii(const char *name)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800107{
108 int num = 0;
109 while (*name >= '0' && *name <= '9') {
110 num = num * 10 + (*name - '0');
111 ++name;
112 }
113 if (*name)
114 return -1; /* Non digit found, not a number. */
115 return num;
116}
117
118
Gregory P. Smith4842efc2012-01-21 21:01:24 -0800119#if defined(__FreeBSD__)
120/* When /dev/fd isn't mounted it is often a static directory populated
121 * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD and OpenBSD.
122 * NetBSD and OpenBSD have a /proc fs available (though not necessarily
123 * mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs
124 * that properly supports /dev/fd.
125 */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500126static int
Ross Lagerwall7f4fdb22012-03-07 20:06:33 +0200127_is_fdescfs_mounted_on_dev_fd(void)
Gregory P. Smith4842efc2012-01-21 21:01:24 -0800128{
129 struct stat dev_stat;
130 struct stat dev_fd_stat;
131 if (stat("/dev", &dev_stat) != 0)
132 return 0;
133 if (stat(FD_DIR, &dev_fd_stat) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +0200134 return 0;
Gregory P. Smith4842efc2012-01-21 21:01:24 -0800135 if (dev_stat.st_dev == dev_fd_stat.st_dev)
136 return 0; /* / == /dev == /dev/fd means it is static. #fail */
137 return 1;
138}
139#endif
140
141
Gregory P. Smith8facece2012-01-21 14:01:08 -0800142/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500143static int
144_sanity_check_python_fd_sequence(PyObject *fd_sequence)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800145{
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300146 Py_ssize_t seq_idx;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800147 long prev_fd = -1;
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300148 for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) {
149 PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx);
150 long iter_fd;
151 if (!PyLong_Check(py_fd)) {
152 return 1;
153 }
154 iter_fd = PyLong_AsLong(py_fd);
Gregory P. Smithd0a5b1c2015-11-15 21:15:26 -0800155 if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) {
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300156 /* Negative, overflow, unsorted, too big for a fd. */
Gregory P. Smith8facece2012-01-21 14:01:08 -0800157 return 1;
158 }
Gregory P. Smithd0a5b1c2015-11-15 21:15:26 -0800159 prev_fd = iter_fd;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800160 }
161 return 0;
162}
163
164
165/* Is fd found in the sorted Python Sequence? */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500166static int
167_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800168{
169 /* Binary search. */
170 Py_ssize_t search_min = 0;
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300171 Py_ssize_t search_max = PyTuple_GET_SIZE(fd_sequence) - 1;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800172 if (search_max < 0)
173 return 0;
174 do {
175 long middle = (search_min + search_max) / 2;
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300176 long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle));
Gregory P. Smith8facece2012-01-21 14:01:08 -0800177 if (fd == middle_fd)
178 return 1;
179 if (fd > middle_fd)
180 search_min = middle + 1;
181 else
182 search_max = middle - 1;
183 } while (search_min <= search_max);
184 return 0;
185}
186
Victor Stinnerdaf45552013-08-28 00:53:59 +0200187static int
188make_inheritable(PyObject *py_fds_to_keep, int errpipe_write)
189{
190 Py_ssize_t i, len;
191
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300192 len = PyTuple_GET_SIZE(py_fds_to_keep);
Victor Stinnerdaf45552013-08-28 00:53:59 +0200193 for (i = 0; i < len; ++i) {
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300194 PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i);
Victor Stinnerdaf45552013-08-28 00:53:59 +0200195 long fd = PyLong_AsLong(fdobj);
196 assert(!PyErr_Occurred());
197 assert(0 <= fd && fd <= INT_MAX);
198 if (fd == errpipe_write) {
199 /* errpipe_write is part of py_fds_to_keep. It must be closed at
200 exec(), but kept open in the child process until exec() is
201 called. */
202 continue;
203 }
Alexey Izbyshevc1e46e92018-02-06 09:09:34 +0300204 if (_Py_set_inheritable_async_safe((int)fd, 1, NULL) < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +0200205 return -1;
206 }
207 return 0;
208}
209
Gregory P. Smith8facece2012-01-21 14:01:08 -0800210
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700211/* Get the maximum file descriptor that could be opened by this process.
212 * This function is async signal safe for use between fork() and exec().
213 */
214static long
215safe_get_max_fd(void)
216{
217 long local_max_fd;
218#if defined(__NetBSD__)
219 local_max_fd = fcntl(0, F_MAXFD);
220 if (local_max_fd >= 0)
221 return local_max_fd;
222#endif
Gregory P. Smithf9681772015-04-25 23:43:34 -0700223#if defined(HAVE_SYS_RESOURCE_H) && defined(__OpenBSD__)
224 struct rlimit rl;
225 /* Not on the POSIX async signal safe functions list but likely
226 * safe. TODO - Someone should audit OpenBSD to make sure. */
227 if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
228 return (long) rl.rlim_max;
229#endif
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700230#ifdef _SC_OPEN_MAX
231 local_max_fd = sysconf(_SC_OPEN_MAX);
232 if (local_max_fd == -1)
233#endif
234 local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */
235 return local_max_fd;
236}
237
238
239/* Close all file descriptors in the range from start_fd and higher
240 * except for those in py_fds_to_keep. If the range defined by
241 * [start_fd, safe_get_max_fd()) is large this will take a long
242 * time as it calls close() on EVERY possible fd.
243 *
244 * It isn't possible to know for sure what the max fd to go up to
245 * is for processes with the capability of raising their maximum.
Gregory P. Smith8facece2012-01-21 14:01:08 -0800246 */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500247static void
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700248_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800249{
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700250 long end_fd = safe_get_max_fd();
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300251 Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800252 Py_ssize_t keep_seq_idx;
253 int fd_num;
254 /* As py_fds_to_keep is sorted we can loop through the list closing
luzpaza5293b42017-11-05 07:37:50 -0600255 * fds in between any in the keep list falling within our range. */
Gregory P. Smith8facece2012-01-21 14:01:08 -0800256 for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300257 PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800258 int keep_fd = PyLong_AsLong(py_keep_fd);
259 if (keep_fd < start_fd)
260 continue;
261 for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
Victor Stinnere7c74922015-04-02 16:24:46 +0200262 close(fd_num);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800263 }
264 start_fd = keep_fd + 1;
265 }
266 if (start_fd <= end_fd) {
267 for (fd_num = start_fd; fd_num < end_fd; ++fd_num) {
Victor Stinnere7c74922015-04-02 16:24:46 +0200268 close(fd_num);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800269 }
270 }
271}
272
273
274#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
275/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this
276 * only to read a directory of short file descriptor number names. The kernel
277 * will return an error if we didn't give it enough space. Highly Unlikely.
278 * This structure is very old and stable: It will not change unless the kernel
279 * chooses to break compatibility with all existing binaries. Highly Unlikely.
280 */
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800281struct linux_dirent64 {
Gregory P. Smith58f07a92012-06-05 13:26:39 -0700282 unsigned long long d_ino;
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800283 long long d_off;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800284 unsigned short d_reclen; /* Length of this linux_dirent */
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800285 unsigned char d_type;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800286 char d_name[256]; /* Filename (null-terminated) */
287};
288
Gregory P. Smitha26987a2014-06-01 13:46:36 -0700289/* Close all open file descriptors in the range from start_fd and higher
290 * Do not close any in the sorted py_fds_to_keep list.
Gregory P. Smith8facece2012-01-21 14:01:08 -0800291 *
292 * This version is async signal safe as it does not make any unsafe C library
293 * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced
294 * to resort to making a kernel system call directly but this is the ONLY api
295 * available that does no harm. opendir/readdir/closedir perform memory
296 * allocation and locking so while they usually work they are not guaranteed
297 * to (especially if you have replaced your malloc implementation). A version
298 * of this function that uses those can be found in the _maybe_unsafe variant.
299 *
300 * This is Linux specific because that is all I am ready to test it on. It
301 * should be easy to add OS specific dirent or dirent64 structures and modify
302 * it with some cpp #define magic to work on other OSes as well if you want.
303 */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500304static void
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700305_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800306{
307 int fd_dir_fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200308
Victor Stinner160e8192015-03-30 02:18:31 +0200309 fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800310 if (fd_dir_fd == -1) {
311 /* No way to get a list of open fds. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700312 _close_fds_by_brute_force(start_fd, py_fds_to_keep);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800313 return;
314 } else {
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800315 char buffer[sizeof(struct linux_dirent64)];
Gregory P. Smith8facece2012-01-21 14:01:08 -0800316 int bytes;
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800317 while ((bytes = syscall(SYS_getdents64, fd_dir_fd,
318 (struct linux_dirent64 *)buffer,
Gregory P. Smith8facece2012-01-21 14:01:08 -0800319 sizeof(buffer))) > 0) {
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800320 struct linux_dirent64 *entry;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800321 int offset;
Gregory P. Smith3015fb82018-11-12 22:01:22 -0800322#ifdef _Py_MEMORY_SANITIZER
Gregory P. Smith1584a002018-11-12 12:07:14 -0800323 __msan_unpoison(buffer, bytes);
324#endif
Gregory P. Smith8facece2012-01-21 14:01:08 -0800325 for (offset = 0; offset < bytes; offset += entry->d_reclen) {
326 int fd;
Gregory P. Smith255bf5b2013-03-03 10:45:05 -0800327 entry = (struct linux_dirent64 *)(buffer + offset);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800328 if ((fd = _pos_int_from_ascii(entry->d_name)) < 0)
329 continue; /* Not a number. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700330 if (fd != fd_dir_fd && fd >= start_fd &&
Gregory P. Smith8facece2012-01-21 14:01:08 -0800331 !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
Victor Stinnere7c74922015-04-02 16:24:46 +0200332 close(fd);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800333 }
334 }
335 }
Victor Stinnere7c74922015-04-02 16:24:46 +0200336 close(fd_dir_fd);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800337 }
338}
339
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700340#define _close_open_fds _close_open_fds_safe
Gregory P. Smith8facece2012-01-21 14:01:08 -0800341
342#else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
343
344
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700345/* Close all open file descriptors from start_fd and higher.
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300346 * Do not close any in the sorted py_fds_to_keep tuple.
Gregory P. Smith8facece2012-01-21 14:01:08 -0800347 *
348 * This function violates the strict use of async signal safe functions. :(
Gregory P. Smithe3f78482012-01-21 15:16:17 -0800349 * It calls opendir(), readdir() and closedir(). Of these, the one most
Gregory P. Smith8facece2012-01-21 14:01:08 -0800350 * likely to ever cause a problem is opendir() as it performs an internal
351 * malloc(). Practically this should not be a problem. The Java VM makes the
352 * same calls between fork and exec in its own UNIXProcess_md.c implementation.
353 *
354 * readdir_r() is not used because it provides no benefit. It is typically
355 * implemented as readdir() followed by memcpy(). See also:
356 * http://womble.decadent.org.uk/readdir_r-advisory.html
357 */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500358static void
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700359_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep)
Gregory P. Smith8facece2012-01-21 14:01:08 -0800360{
361 DIR *proc_fd_dir;
362#ifndef HAVE_DIRFD
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700363 while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) {
Gregory P. Smith8facece2012-01-21 14:01:08 -0800364 ++start_fd;
365 }
Gregory P. Smith8facece2012-01-21 14:01:08 -0800366 /* Close our lowest fd before we call opendir so that it is likely to
367 * reuse that fd otherwise we might close opendir's file descriptor in
368 * our loop. This trick assumes that fd's are allocated on a lowest
369 * available basis. */
Victor Stinnere7c74922015-04-02 16:24:46 +0200370 close(start_fd);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800371 ++start_fd;
372#endif
Gregory P. Smith8facece2012-01-21 14:01:08 -0800373
Gregory P. Smith4842efc2012-01-21 21:01:24 -0800374#if defined(__FreeBSD__)
375 if (!_is_fdescfs_mounted_on_dev_fd())
376 proc_fd_dir = NULL;
377 else
378#endif
379 proc_fd_dir = opendir(FD_DIR);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800380 if (!proc_fd_dir) {
381 /* No way to get a list of open fds. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700382 _close_fds_by_brute_force(start_fd, py_fds_to_keep);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800383 } else {
Gregory P. Smithe3f78482012-01-21 15:16:17 -0800384 struct dirent *dir_entry;
Gregory P. Smith8facece2012-01-21 14:01:08 -0800385#ifdef HAVE_DIRFD
Gregory P. Smithe9b7cab2012-01-21 15:19:11 -0800386 int fd_used_by_opendir = dirfd(proc_fd_dir);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800387#else
388 int fd_used_by_opendir = start_fd - 1;
389#endif
390 errno = 0;
Gregory P. Smithe3f78482012-01-21 15:16:17 -0800391 while ((dir_entry = readdir(proc_fd_dir))) {
Gregory P. Smith8facece2012-01-21 14:01:08 -0800392 int fd;
393 if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0)
394 continue; /* Not a number. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700395 if (fd != fd_used_by_opendir && fd >= start_fd &&
Gregory P. Smith8facece2012-01-21 14:01:08 -0800396 !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
Victor Stinnere7c74922015-04-02 16:24:46 +0200397 close(fd);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800398 }
399 errno = 0;
400 }
401 if (errno) {
402 /* readdir error, revert behavior. Highly Unlikely. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700403 _close_fds_by_brute_force(start_fd, py_fds_to_keep);
Gregory P. Smith8facece2012-01-21 14:01:08 -0800404 }
405 closedir(proc_fd_dir);
406 }
407}
408
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700409#define _close_open_fds _close_open_fds_maybe_unsafe
Gregory P. Smith8facece2012-01-21 14:01:08 -0800410
411#endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
412
413
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000414/*
415 * This function is code executed in the child process immediately after fork
416 * to set things up and call exec().
417 *
418 * All of the code in this function must only use async-signal-safe functions,
419 * listed at `man 7 signal` or
420 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
421 *
422 * This restriction is documented at
423 * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
424 */
Benjamin Peterson91eef982012-01-22 20:04:46 -0500425static void
426child_exec(char *const exec_array[],
427 char *const argv[],
428 char *const envp[],
429 const char *cwd,
430 int p2cread, int p2cwrite,
431 int c2pread, int c2pwrite,
432 int errread, int errwrite,
433 int errpipe_read, int errpipe_write,
434 int close_fds, int restore_signals,
435 int call_setsid,
Patrick McLean2b2ead72019-09-12 10:15:44 -0700436 int call_setgid, gid_t gid,
437 int call_setgroups, size_t groups_size, const gid_t *groups,
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700438 int call_setuid, uid_t uid, int child_umask,
Benjamin Peterson91eef982012-01-22 20:04:46 -0500439 PyObject *py_fds_to_keep,
440 PyObject *preexec_fn,
441 PyObject *preexec_fn_args_tuple)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000442{
Victor Stinner185fd332015-04-01 18:35:53 +0200443 int i, saved_errno, reached_preexec = 0;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000444 PyObject *result;
Gregory P. Smith14affb82010-12-22 05:22:17 +0000445 const char* err_msg = "";
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000446 /* Buffer large enough to hold a hex integer. We can't malloc. */
447 char hex_errno[sizeof(saved_errno)*2+1];
448
Victor Stinnerdaf45552013-08-28 00:53:59 +0200449 if (make_inheritable(py_fds_to_keep, errpipe_write) < 0)
450 goto error;
451
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000452 /* Close parent's pipe ends. */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200453 if (p2cwrite != -1)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000454 POSIX_CALL(close(p2cwrite));
Victor Stinnerdaf45552013-08-28 00:53:59 +0200455 if (c2pread != -1)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000456 POSIX_CALL(close(c2pread));
Victor Stinnerdaf45552013-08-28 00:53:59 +0200457 if (errread != -1)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000458 POSIX_CALL(close(errread));
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000459 POSIX_CALL(close(errpipe_read));
460
Ross Lagerwalld98646e2011-07-27 07:16:31 +0200461 /* When duping fds, if there arises a situation where one of the fds is
462 either 0, 1 or 2, it is possible that it is overwritten (#12607). */
Gregory P. Smithce344102018-09-10 17:46:22 -0700463 if (c2pwrite == 0) {
Ross Lagerwalld98646e2011-07-27 07:16:31 +0200464 POSIX_CALL(c2pwrite = dup(c2pwrite));
Gregory P. Smithce344102018-09-10 17:46:22 -0700465 /* issue32270 */
466 if (_Py_set_inheritable_async_safe(c2pwrite, 0, NULL) < 0) {
467 goto error;
468 }
469 }
470 while (errwrite == 0 || errwrite == 1) {
Ross Lagerwalld98646e2011-07-27 07:16:31 +0200471 POSIX_CALL(errwrite = dup(errwrite));
Gregory P. Smithce344102018-09-10 17:46:22 -0700472 /* issue32270 */
473 if (_Py_set_inheritable_async_safe(errwrite, 0, NULL) < 0) {
474 goto error;
475 }
476 }
Ross Lagerwalld98646e2011-07-27 07:16:31 +0200477
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +0000478 /* Dup fds for child.
479 dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
480 would be a no-op (issue #10806). */
481 if (p2cread == 0) {
Alexey Izbyshevc1e46e92018-02-06 09:09:34 +0300482 if (_Py_set_inheritable_async_safe(p2cread, 1, NULL) < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +0200483 goto error;
484 }
485 else if (p2cread != -1)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000486 POSIX_CALL(dup2(p2cread, 0)); /* stdin */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200487
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +0000488 if (c2pwrite == 1) {
Alexey Izbyshevc1e46e92018-02-06 09:09:34 +0300489 if (_Py_set_inheritable_async_safe(c2pwrite, 1, NULL) < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +0200490 goto error;
491 }
492 else if (c2pwrite != -1)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000493 POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200494
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +0000495 if (errwrite == 2) {
Alexey Izbyshevc1e46e92018-02-06 09:09:34 +0300496 if (_Py_set_inheritable_async_safe(errwrite, 1, NULL) < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +0200497 goto error;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000498 }
Victor Stinnerdaf45552013-08-28 00:53:59 +0200499 else if (errwrite != -1)
500 POSIX_CALL(dup2(errwrite, 2)); /* stderr */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000501
Gregory P. Smithce344102018-09-10 17:46:22 -0700502 /* We no longer manually close p2cread, c2pwrite, and errwrite here as
503 * _close_open_fds takes care when it is not already non-inheritable. */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000504
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000505 if (cwd)
506 POSIX_CALL(chdir(cwd));
507
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700508 if (child_umask >= 0)
509 umask(child_umask); /* umask() always succeeds. */
510
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000511 if (restore_signals)
512 _Py_RestoreSignals();
513
514#ifdef HAVE_SETSID
515 if (call_setsid)
516 POSIX_CALL(setsid());
517#endif
518
Patrick McLean2b2ead72019-09-12 10:15:44 -0700519#ifdef HAVE_SETGROUPS
520 if (call_setgroups)
521 POSIX_CALL(setgroups(groups_size, groups));
522#endif /* HAVE_SETGROUPS */
523
524#ifdef HAVE_SETREGID
525 if (call_setgid)
526 POSIX_CALL(setregid(gid, gid));
527#endif /* HAVE_SETREGID */
528
529#ifdef HAVE_SETREUID
530 if (call_setuid)
531 POSIX_CALL(setreuid(uid, uid));
532#endif /* HAVE_SETREUID */
533
534
Gregory P. Smith5591b022012-10-10 03:34:47 -0700535 reached_preexec = 1;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000536 if (preexec_fn != Py_None && preexec_fn_args_tuple) {
537 /* This is where the user has asked us to deadlock their program. */
538 result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
539 if (result == NULL) {
540 /* Stringifying the exception or traceback would involve
541 * memory allocation and thus potential for deadlock.
542 * We've already faced potential deadlock by calling back
543 * into Python in the first place, so it probably doesn't
544 * matter but we avoid it to minimize the possibility. */
545 err_msg = "Exception occurred in preexec_fn.";
546 errno = 0; /* We don't want to report an OSError. */
547 goto error;
548 }
549 /* Py_DECREF(result); - We're about to exec so why bother? */
550 }
551
Charles-François Natali249cdc32013-08-25 18:24:45 +0200552 /* close FDs after executing preexec_fn, which might open FDs */
553 if (close_fds) {
Charles-François Natali249cdc32013-08-25 18:24:45 +0200554 /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
Gregory P. Smithd4dcb702014-06-01 13:18:28 -0700555 _close_open_fds(3, py_fds_to_keep);
Charles-François Natali249cdc32013-08-25 18:24:45 +0200556 }
557
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000558 /* This loop matches the Lib/os.py _execvpe()'s PATH search when */
559 /* given the executable_list generated by Lib/subprocess.py. */
560 saved_errno = 0;
561 for (i = 0; exec_array[i] != NULL; ++i) {
562 const char *executable = exec_array[i];
563 if (envp) {
564 execve(executable, argv, envp);
565 } else {
566 execv(executable, argv);
567 }
568 if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) {
569 saved_errno = errno;
570 }
571 }
572 /* Report the first exec error, not the last. */
573 if (saved_errno)
574 errno = saved_errno;
575
576error:
577 saved_errno = errno;
578 /* Report the posix error to our parent process. */
Gregory P. Smith12fdca52012-01-21 12:31:25 -0800579 /* We ignore all write() return values as the total size of our writes is
Victor Stinner185fd332015-04-01 18:35:53 +0200580 less than PIPEBUF and we cannot do anything about an error anyways.
581 Use _Py_write_noraise() to retry write() if it is interrupted by a
582 signal (fails with EINTR). */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000583 if (saved_errno) {
584 char *cur;
Victor Stinner185fd332015-04-01 18:35:53 +0200585 _Py_write_noraise(errpipe_write, "OSError:", 8);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000586 cur = hex_errno + sizeof(hex_errno);
Serhiy Storchaka5ae4f492016-09-27 22:03:51 +0300587 while (saved_errno != 0 && cur != hex_errno) {
Gregory P. Smith4dff6f62015-04-25 23:42:38 +0000588 *--cur = Py_hexdigits[saved_errno % 16];
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000589 saved_errno /= 16;
590 }
Victor Stinner185fd332015-04-01 18:35:53 +0200591 _Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
592 _Py_write_noraise(errpipe_write, ":", 1);
Gregory P. Smith5591b022012-10-10 03:34:47 -0700593 if (!reached_preexec) {
594 /* Indicate to the parent that the error happened before exec(). */
Victor Stinner185fd332015-04-01 18:35:53 +0200595 _Py_write_noraise(errpipe_write, "noexec", 6);
Gregory P. Smith5591b022012-10-10 03:34:47 -0700596 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000597 /* We can't call strerror(saved_errno). It is not async signal safe.
598 * The parent process will look the error message up. */
599 } else {
Victor Stinner185fd332015-04-01 18:35:53 +0200600 _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18);
601 _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg));
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000602 }
603}
604
605
606static PyObject *
607subprocess_fork_exec(PyObject* self, PyObject *args)
608{
609 PyObject *gc_module = NULL;
Antoine Pitrou721738f2012-08-15 23:20:39 +0200610 PyObject *executable_list, *py_fds_to_keep;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000611 PyObject *env_list, *preexec_fn;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000612 PyObject *process_args, *converted_args = NULL, *fast_args = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000613 PyObject *preexec_fn_args_tuple = NULL;
Patrick McLean2b2ead72019-09-12 10:15:44 -0700614 PyObject *groups_list;
615 PyObject *uid_object, *gid_object;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000616 int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite;
617 int errpipe_read, errpipe_write, close_fds, restore_signals;
618 int call_setsid;
Patrick McLean2b2ead72019-09-12 10:15:44 -0700619 int call_setgid = 0, call_setgroups = 0, call_setuid = 0;
620 uid_t uid;
621 gid_t gid, *groups = NULL;
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700622 int child_umask;
Victor Stinner0e59cc32010-04-16 23:49:32 +0000623 PyObject *cwd_obj, *cwd_obj2;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000624 const char *cwd;
625 pid_t pid;
626 int need_to_reenable_gc = 0;
627 char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
Patrick McLean2b2ead72019-09-12 10:15:44 -0700628 Py_ssize_t arg_num, num_groups = 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200629 int need_after_fork = 0;
Gregory P. Smitha20b6ad2018-09-13 04:30:10 -0700630 int saved_errno = 0;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000631
632 if (!PyArg_ParseTuple(
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700633 args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300634 &process_args, &executable_list,
635 &close_fds, &PyTuple_Type, &py_fds_to_keep,
Victor Stinner0e59cc32010-04-16 23:49:32 +0000636 &cwd_obj, &env_list,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000637 &p2cread, &p2cwrite, &c2pread, &c2pwrite,
638 &errread, &errwrite, &errpipe_read, &errpipe_write,
Patrick McLean2b2ead72019-09-12 10:15:44 -0700639 &restore_signals, &call_setsid,
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700640 &gid_object, &groups_list, &uid_object, &child_umask,
Patrick McLean2b2ead72019-09-12 10:15:44 -0700641 &preexec_fn))
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000642 return NULL;
643
Christian Heimes98d90f72019-08-27 23:36:56 +0200644 if ((preexec_fn != Py_None) &&
Victor Stinnerbe793732020-03-13 18:15:33 +0100645 (PyInterpreterState_Get() != PyInterpreterState_Main())) {
Christian Heimes98d90f72019-08-27 23:36:56 +0200646 PyErr_SetString(PyExc_RuntimeError,
647 "preexec_fn not supported within subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -0700648 return NULL;
649 }
650
Gregory P. Smith361e30c2013-12-01 00:12:24 -0800651 if (close_fds && errpipe_write < 3) { /* precondition */
652 PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
653 return NULL;
654 }
Gregory P. Smith8facece2012-01-21 14:01:08 -0800655 if (_sanity_check_python_fd_sequence(py_fds_to_keep)) {
656 PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep");
Gregory P. Smithd4cc7bf2010-12-04 11:22:11 +0000657 return NULL;
658 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000659
660 /* We need to call gc.disable() when we'll be calling preexec_fn */
661 if (preexec_fn != Py_None) {
662 PyObject *result;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200663
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000664 gc_module = PyImport_ImportModule("gc");
665 if (gc_module == NULL)
666 return NULL;
Petr Viktorinffd97532020-02-11 17:46:57 +0100667 result = PyObject_CallMethodNoArgs(
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100668 gc_module, _posixsubprocessstate_global->isenabled);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000669 if (result == NULL) {
670 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000671 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000672 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000673 need_to_reenable_gc = PyObject_IsTrue(result);
674 Py_DECREF(result);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000675 if (need_to_reenable_gc == -1) {
676 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000677 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000678 }
Petr Viktorinffd97532020-02-11 17:46:57 +0100679 result = PyObject_CallMethodNoArgs(
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100680 gc_module, _posixsubprocessstate_global->disable);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000681 if (result == NULL) {
682 Py_DECREF(gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000683 return NULL;
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000684 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000685 Py_DECREF(result);
686 }
687
688 exec_array = _PySequence_BytesToCharpArray(executable_list);
Victor Stinner8f437aa2014-10-05 17:25:19 +0200689 if (!exec_array)
690 goto cleanup;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000691
692 /* Convert args and env into appropriate arguments for exec() */
693 /* These conversions are done in the parent process to avoid allocating
694 or freeing memory in the child process. */
695 if (process_args != Py_None) {
Gregory P. Smith68f52172010-03-15 06:07:42 +0000696 Py_ssize_t num_args;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000697 /* Equivalent to: */
698 /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */
Gregory P. Smith68f52172010-03-15 06:07:42 +0000699 fast_args = PySequence_Fast(process_args, "argv must be a tuple");
Stefan Krahdb579d72012-08-20 14:36:47 +0200700 if (fast_args == NULL)
701 goto cleanup;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000702 num_args = PySequence_Fast_GET_SIZE(fast_args);
703 converted_args = PyTuple_New(num_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000704 if (converted_args == NULL)
705 goto cleanup;
Gregory P. Smith68f52172010-03-15 06:07:42 +0000706 for (arg_num = 0; arg_num < num_args; ++arg_num) {
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000707 PyObject *borrowed_arg, *converted_arg;
Serhiy Storchaka66bffd12017-04-19 21:12:46 +0300708 if (PySequence_Fast_GET_SIZE(fast_args) != num_args) {
709 PyErr_SetString(PyExc_RuntimeError, "args changed during iteration");
710 goto cleanup;
711 }
Gregory P. Smith68f52172010-03-15 06:07:42 +0000712 borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000713 if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0)
714 goto cleanup;
715 PyTuple_SET_ITEM(converted_args, arg_num, converted_arg);
716 }
717
718 argv = _PySequence_BytesToCharpArray(converted_args);
719 Py_CLEAR(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000720 Py_CLEAR(fast_args);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000721 if (!argv)
722 goto cleanup;
723 }
724
725 if (env_list != Py_None) {
726 envp = _PySequence_BytesToCharpArray(env_list);
727 if (!envp)
728 goto cleanup;
729 }
730
Victor Stinner0e59cc32010-04-16 23:49:32 +0000731 if (cwd_obj != Py_None) {
732 if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0)
733 goto cleanup;
Victor Stinnerdcb24032010-04-22 12:08:36 +0000734 cwd = PyBytes_AsString(cwd_obj2);
Victor Stinner0e59cc32010-04-16 23:49:32 +0000735 } else {
736 cwd = NULL;
737 cwd_obj2 = NULL;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000738 }
739
Patrick McLean2b2ead72019-09-12 10:15:44 -0700740 if (groups_list != Py_None) {
741#ifdef HAVE_SETGROUPS
742 Py_ssize_t i;
743 unsigned long gid;
744
745 if (!PyList_Check(groups_list)) {
746 PyErr_SetString(PyExc_TypeError,
747 "setgroups argument must be a list");
748 goto cleanup;
749 }
750 num_groups = PySequence_Size(groups_list);
751
752 if (num_groups < 0)
753 goto cleanup;
754
755 if (num_groups > MAX_GROUPS) {
756 PyErr_SetString(PyExc_ValueError, "too many groups");
757 goto cleanup;
758 }
759
760 if ((groups = PyMem_RawMalloc(num_groups * sizeof(gid_t))) == NULL) {
761 PyErr_SetString(PyExc_MemoryError,
762 "failed to allocate memory for group list");
763 goto cleanup;
764 }
765
766 for (i = 0; i < num_groups; i++) {
767 PyObject *elem;
768 elem = PySequence_GetItem(groups_list, i);
769 if (!elem)
770 goto cleanup;
771 if (!PyLong_Check(elem)) {
772 PyErr_SetString(PyExc_TypeError,
773 "groups must be integers");
774 Py_DECREF(elem);
775 goto cleanup;
776 } else {
777 /* In posixmodule.c UnsignedLong is used as a fallback value
778 * if the value provided does not fit in a Long. Since we are
779 * already doing the bounds checking on the Python side, we
780 * can go directly to an UnsignedLong here. */
781 if (!_Py_Gid_Converter(elem, &gid)) {
782 Py_DECREF(elem);
783 PyErr_SetString(PyExc_ValueError, "invalid group id");
784 goto cleanup;
785 }
786 groups[i] = gid;
787 }
788 Py_DECREF(elem);
789 }
790 call_setgroups = 1;
791
792#else /* HAVE_SETGROUPS */
793 PyErr_BadInternalCall();
794 goto cleanup;
795#endif /* HAVE_SETGROUPS */
796 }
797
798 if (gid_object != Py_None) {
799#ifdef HAVE_SETREGID
800 if (!_Py_Gid_Converter(gid_object, &gid))
801 goto cleanup;
802
803 call_setgid = 1;
804
805#else /* HAVE_SETREGID */
806 PyErr_BadInternalCall();
807 goto cleanup;
808#endif /* HAVE_SETREUID */
809 }
810
811 if (uid_object != Py_None) {
812#ifdef HAVE_SETREUID
813 if (!_Py_Uid_Converter(uid_object, &uid))
814 goto cleanup;
815
816 call_setuid = 1;
817
818#else /* HAVE_SETREUID */
819 PyErr_BadInternalCall();
820 goto cleanup;
821#endif /* HAVE_SETREUID */
822 }
823
Gregory P. Smith163468a2017-05-29 10:03:41 -0700824 /* This must be the last thing done before fork() because we do not
825 * want to call PyOS_BeforeFork() if there is any chance of another
826 * error leading to the cleanup: code without calling fork(). */
827 if (preexec_fn != Py_None) {
828 preexec_fn_args_tuple = PyTuple_New(0);
829 if (!preexec_fn_args_tuple)
830 goto cleanup;
831 PyOS_BeforeFork();
832 need_after_fork = 1;
833 }
834
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000835 pid = fork();
836 if (pid == 0) {
837 /* Child process */
Victor Stinner0e59cc32010-04-16 23:49:32 +0000838 /*
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000839 * Code from here to _exit() must only use async-signal-safe functions,
840 * listed at `man 7 signal` or
841 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
842 */
843
844 if (preexec_fn != Py_None) {
845 /* We'll be calling back into Python later so we need to do this.
846 * This call may not be async-signal-safe but neither is calling
847 * back into Python. The user asked us to use hope as a strategy
848 * to avoid deadlock... */
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200849 PyOS_AfterFork_Child();
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000850 }
851
852 child_exec(exec_array, argv, envp, cwd,
853 p2cread, p2cwrite, c2pread, c2pwrite,
854 errread, errwrite, errpipe_read, errpipe_write,
855 close_fds, restore_signals, call_setsid,
Patrick McLean2b2ead72019-09-12 10:15:44 -0700856 call_setgid, gid, call_setgroups, num_groups, groups,
Gregory P. Smithf3751ef2019-10-12 13:24:56 -0700857 call_setuid, uid, child_umask,
Gregory P. Smith8facece2012-01-21 14:01:08 -0800858 py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000859 _exit(255);
860 return NULL; /* Dead code to avoid a potential compiler warning. */
861 }
Gregory P. Smitha20b6ad2018-09-13 04:30:10 -0700862 /* Parent (original) process */
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000863 if (pid == -1) {
Gregory P. Smitha20b6ad2018-09-13 04:30:10 -0700864 /* Capture errno for the exception. */
865 saved_errno = errno;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000866 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000867
Gregory P. Smitha20b6ad2018-09-13 04:30:10 -0700868 Py_XDECREF(cwd_obj2);
869
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200870 if (need_after_fork)
871 PyOS_AfterFork_Parent();
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000872 if (envp)
873 _Py_FreeCharPArray(envp);
874 if (argv)
875 _Py_FreeCharPArray(argv);
876 _Py_FreeCharPArray(exec_array);
877
878 /* Reenable gc in the parent process (or if fork failed). */
Martin Panterafdd5132015-11-30 02:21:41 +0000879 if (_enable_gc(need_to_reenable_gc, gc_module)) {
880 pid = -1;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000881 }
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000882 Py_XDECREF(preexec_fn_args_tuple);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000883 Py_XDECREF(gc_module);
884
Gregory P. Smitha20b6ad2018-09-13 04:30:10 -0700885 if (pid == -1) {
886 errno = saved_errno;
887 /* We can't call this above as PyOS_AfterFork_Parent() calls back
888 * into Python code which would see the unreturned error. */
889 PyErr_SetFromErrno(PyExc_OSError);
890 return NULL; /* fork() failed. */
891 }
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000892
893 return PyLong_FromPid(pid);
894
895cleanup:
896 if (envp)
897 _Py_FreeCharPArray(envp);
898 if (argv)
899 _Py_FreeCharPArray(argv);
Victor Stinner8f437aa2014-10-05 17:25:19 +0200900 if (exec_array)
901 _Py_FreeCharPArray(exec_array);
Patrick McLean2b2ead72019-09-12 10:15:44 -0700902
903 PyMem_RawFree(groups);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000904 Py_XDECREF(converted_args);
Gregory P. Smith68f52172010-03-15 06:07:42 +0000905 Py_XDECREF(fast_args);
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000906 Py_XDECREF(preexec_fn_args_tuple);
Martin Panterafdd5132015-11-30 02:21:41 +0000907 _enable_gc(need_to_reenable_gc, gc_module);
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000908 Py_XDECREF(gc_module);
909 return NULL;
910}
911
912
913PyDoc_STRVAR(subprocess_fork_exec_doc,
Orivej Desh77abf232019-09-20 17:01:10 +0000914"fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000915 p2cread, p2cwrite, c2pread, c2pwrite,\n\
916 errread, errwrite, errpipe_read, errpipe_write,\n\
Patrick McLean2b2ead72019-09-12 10:15:44 -0700917 restore_signals, call_setsid,\n\
Orivej Desh77abf232019-09-20 17:01:10 +0000918 gid, groups_list, uid,\n\
Patrick McLean2b2ead72019-09-12 10:15:44 -0700919 preexec_fn)\n\
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000920\n\
921Forks a child process, closes parent file descriptors as appropriate in the\n\
922child and dups the few that are needed before calling exec() in the child\n\
923process.\n\
924\n\
Orivej Desh77abf232019-09-20 17:01:10 +0000925If close_fds is true, close file descriptors 3 and higher, except those listed\n\
926in the sorted tuple pass_fds.\n\
927\n\
928The preexec_fn, if supplied, will be called immediately before closing file\n\
929descriptors and exec.\n\
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000930WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\
931 It may trigger infrequent, difficult to debug deadlocks.\n\
932\n\
933If an error occurs in the child process before the exec, it is\n\
934serialized and written to the errpipe_write fd per subprocess.py.\n\
935\n\
936Returns: the child process's PID.\n\
937\n\
938Raises: Only on an error in the parent process.\n\
939");
940
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000941/* module level code ********************************************************/
942
943PyDoc_STRVAR(module_doc,
944"A POSIX helper for the subprocess module.");
945
946
947static PyMethodDef module_methods[] = {
948 {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000949 {NULL, NULL} /* sentinel */
950};
951
952
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100953static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
Hai Shif707d942020-03-16 21:15:01 +0800954 Py_VISIT(get_posixsubprocess_state(m)->disable);
955 Py_VISIT(get_posixsubprocess_state(m)->enable);
956 Py_VISIT(get_posixsubprocess_state(m)->isenabled);
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100957 return 0;
958}
959
960static int _posixsubprocess_clear(PyObject *m) {
Hai Shif707d942020-03-16 21:15:01 +0800961 Py_CLEAR(get_posixsubprocess_state(m)->disable);
962 Py_CLEAR(get_posixsubprocess_state(m)->enable);
963 Py_CLEAR(get_posixsubprocess_state(m)->isenabled);
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100964 return 0;
965}
966
967static void _posixsubprocess_free(void *m) {
968 _posixsubprocess_clear((PyObject *)m);
969}
970
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000971static struct PyModuleDef _posixsubprocessmodule = {
luzpaza5293b42017-11-05 07:37:50 -0600972 PyModuleDef_HEAD_INIT,
973 "_posixsubprocess",
974 module_doc,
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100975 sizeof(_posixsubprocessstate),
luzpaza5293b42017-11-05 07:37:50 -0600976 module_methods,
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100977 NULL,
978 _posixsubprocess_traverse,
979 _posixsubprocess_clear,
980 _posixsubprocess_free,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000981};
982
983PyMODINIT_FUNC
984PyInit__posixsubprocess(void)
985{
Dino Viehland5a7d2e12019-09-10 12:01:20 +0100986 PyObject* m;
987
988 m = PyState_FindModule(&_posixsubprocessmodule);
989 if (m != NULL) {
990 Py_INCREF(m);
991 return m;
992 }
993
994 m = PyModule_Create(&_posixsubprocessmodule);
995 if (m == NULL) {
996 return NULL;
997 }
998
Hai Shif707d942020-03-16 21:15:01 +0800999 get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable");
1000 get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable");
1001 get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled");
Dino Viehland5a7d2e12019-09-10 12:01:20 +01001002
1003 PyState_AddModule(m, &_posixsubprocessmodule);
1004 return m;
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001005}