From 8fd150967fc63c08523154ec84e3f5aed3ae5e05 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google]" Date: Wed, 30 Mar 2022 01:20:26 +0000 Subject: [PATCH 1/4] bpo-47151: Fallback to fork when vfork fails in subprocess. --- .../next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst | 3 +++ Modules/_posixsubprocess.c | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst new file mode 100644 index 00000000000000..617e11f68303d0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst @@ -0,0 +1,3 @@ +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed. +Such as the pid 1 init process. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index de599f8c970e38..d42101e9282a5e 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -685,9 +685,16 @@ do_fork_exec(char *const exec_array[], assert(preexec_fn == Py_None); pid = vfork(); + if (pid == -1) { + /* If vfork() fails, fall back to using fork(). When it isn't + * allowed from a process (such as pid==1 init), vfork can return + * -1 with errno EINVAL. https://bugs.python.org/issue47151. */ + goto fallback_to_fork; + } } else #endif { +fallback_to_fork: pid = fork(); } From 5d79179665bf061c592f9d1ce5837bc316c6f0f5 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Wed, 30 Mar 2022 08:36:28 -0700 Subject: [PATCH 2/4] just call fork() rather than goto the fork() --- Modules/_posixsubprocess.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index d42101e9282a5e..ebe757c2e2e4bb 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -689,12 +689,11 @@ do_fork_exec(char *const exec_array[], /* If vfork() fails, fall back to using fork(). When it isn't * allowed from a process (such as pid==1 init), vfork can return * -1 with errno EINVAL. https://bugs.python.org/issue47151. */ - goto fallback_to_fork; + pid = fork(); } } else #endif { -fallback_to_fork: pid = fork(); } From 001a8130ddadc5bba3ce990cad2b9e30c52def14 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Thu, 31 Mar 2022 10:54:12 -0700 Subject: [PATCH 3/4] reword the comment to be more accurate --- Modules/_posixsubprocess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index ebe757c2e2e4bb..440c7c5b335994 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -687,8 +687,8 @@ do_fork_exec(char *const exec_array[], pid = vfork(); if (pid == -1) { /* If vfork() fails, fall back to using fork(). When it isn't - * allowed from a process (such as pid==1 init), vfork can return - * -1 with errno EINVAL. https://bugs.python.org/issue47151. */ + * allowed in a process by the kernel, vfork can return -1 + * with errno EINVAL. https://bugs.python.org/issue47151. */ pid = fork(); } } else From 21ddde70ef6a189aa9ed72b9a37d3bf438d38926 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Thu, 31 Mar 2022 10:55:15 -0700 Subject: [PATCH 4/4] reword news to be more accurate. --- .../next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst index 617e11f68303d0..d4d02459d35de1 100644 --- a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst +++ b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst @@ -1,3 +1,3 @@ When subprocess tries to use vfork, it now falls back to fork if vfork -returns an error. This allows use in situations where vfork isn't allowed. -Such as the pid 1 init process. +returns an error. This allows use in situations where vfork isn't allowed +by the OS kernel.