gh-104522: Fix OSError raised when run a subprocess (#114195)
Only set filename to cwd if it was caused by failed chdir(cwd). _fork_exec() now returns "noexec:chdir" for failed chdir(cwd). Co-authored-by: Robert O'Shea <PurityLake@users.noreply.github.com>
This commit is contained in:
@@ -673,9 +673,10 @@ child_exec(char *const exec_array[],
|
||||
PyObject *preexec_fn,
|
||||
PyObject *preexec_fn_args_tuple)
|
||||
{
|
||||
int i, saved_errno, reached_preexec = 0;
|
||||
int i, saved_errno;
|
||||
PyObject *result;
|
||||
const char* err_msg = "";
|
||||
/* Indicate to the parent that the error happened before exec(). */
|
||||
const char *err_msg = "noexec";
|
||||
/* Buffer large enough to hold a hex integer. We can't malloc. */
|
||||
char hex_errno[sizeof(saved_errno)*2+1];
|
||||
|
||||
@@ -735,8 +736,12 @@ child_exec(char *const exec_array[],
|
||||
/* We no longer manually close p2cread, c2pwrite, and errwrite here as
|
||||
* _close_open_fds takes care when it is not already non-inheritable. */
|
||||
|
||||
if (cwd)
|
||||
POSIX_CALL(chdir(cwd));
|
||||
if (cwd) {
|
||||
if (chdir(cwd) == -1) {
|
||||
err_msg = "noexec:chdir";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (child_umask >= 0)
|
||||
umask(child_umask); /* umask() always succeeds. */
|
||||
@@ -784,7 +789,7 @@ child_exec(char *const exec_array[],
|
||||
#endif /* HAVE_SETREUID */
|
||||
|
||||
|
||||
reached_preexec = 1;
|
||||
err_msg = "";
|
||||
if (preexec_fn != Py_None && preexec_fn_args_tuple) {
|
||||
/* This is where the user has asked us to deadlock their program. */
|
||||
result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
|
||||
@@ -842,16 +847,12 @@ error:
|
||||
}
|
||||
_Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
|
||||
_Py_write_noraise(errpipe_write, ":", 1);
|
||||
if (!reached_preexec) {
|
||||
/* Indicate to the parent that the error happened before exec(). */
|
||||
_Py_write_noraise(errpipe_write, "noexec", 6);
|
||||
}
|
||||
/* We can't call strerror(saved_errno). It is not async signal safe.
|
||||
* The parent process will look the error message up. */
|
||||
} else {
|
||||
_Py_write_noraise(errpipe_write, "SubprocessError:0:", 18);
|
||||
_Py_write_noraise(errpipe_write, err_msg, strlen(err_msg));
|
||||
}
|
||||
_Py_write_noraise(errpipe_write, err_msg, strlen(err_msg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user