Skip to content

Commit 473db47

Browse files
author
Alexey Izbyshev
authored
bpo-35823: subprocess: Fix handling of pthread_sigmask() errors (GH-22944)
Using POSIX_CALL() is incorrect since pthread_sigmask() returns the error number instead of setting errno. Also handle failure of the first call to pthread_sigmask() in the parent process, and explain why we don't handle failure of the second call in a comment.
1 parent e01e442 commit 473db47

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

Modules/_posixsubprocess.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,9 @@ child_exec(char *const exec_array[],
581581
#ifdef VFORK_USABLE
582582
if (child_sigmask) {
583583
reset_signal_handlers(child_sigmask);
584-
POSIX_CALL(pthread_sigmask(SIG_SETMASK, child_sigmask, NULL));
584+
if ((errno = pthread_sigmask(SIG_SETMASK, child_sigmask, NULL))) {
585+
goto error;
586+
}
585587
}
586588
#endif
587589

@@ -1007,7 +1009,11 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
10071009
*/
10081010
sigset_t all_sigs;
10091011
sigfillset(&all_sigs);
1010-
pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs);
1012+
if ((saved_errno = pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs))) {
1013+
errno = saved_errno;
1014+
PyErr_SetFromErrno(PyExc_OSError);
1015+
goto cleanup;
1016+
}
10111017
old_sigmask = &old_sigs;
10121018
}
10131019
#endif
@@ -1034,8 +1040,13 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
10341040
* Note that in environments where vfork() is implemented as fork(),
10351041
* such as QEMU user-mode emulation, the parent won't be blocked,
10361042
* but it won't share the address space with the child,
1037-
* so it's still safe to unblock the signals. */
1038-
pthread_sigmask(SIG_SETMASK, old_sigmask, NULL);
1043+
* so it's still safe to unblock the signals.
1044+
*
1045+
* We don't handle errors here because this call can't fail
1046+
* if valid arguments are given, and because there is no good
1047+
* way for the caller to deal with a failure to restore
1048+
* the thread signal mask. */
1049+
(void) pthread_sigmask(SIG_SETMASK, old_sigmask, NULL);
10391050
}
10401051
#endif
10411052

0 commit comments

Comments
 (0)