From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 8270 invoked from network); 2 May 2022 19:26:53 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 2 May 2022 19:26:53 -0000 Received: (qmail 26023 invoked by uid 550); 2 May 2022 19:26:50 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 25990 invoked from network); 2 May 2022 19:26:50 -0000 MIME-Version: 1.0 Date: Mon, 02 May 2022 22:26:36 +0300 From: Alexey Izbyshev To: musl@lists.openwall.com User-Agent: Roundcube Webmail/1.4.4 Message-ID: X-Sender: izbyshev@ispras.ru Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Subject: [musl] vfork()-based posix_spawn() has more failure modes than fork()-based one Hi, I was recently made aware via [1] that vfork() can have more failure modes than fork() on Linux. The only case I know about is due to Linux not allowing processes in different time namespaces to share address space, but probably there are or will be more. An example is below (requires Linux >= 5.6). $ cat test.c #include #include #include #include #include #include int main(int argc, char *argv[], char *envp[]) { if (getenv("TEST_FORK")) { pid_t pid = fork(); if (pid < 0) { perror("fork"); return 127; } if (pid == 0) { execve(argv[1], argv + 1, envp); _exit(127); } } else { int err = posix_spawn(0, argv[1], 0, 0, argv + 1, envp); if (err) { printf("posix_spawn: %s\n", strerror(err)); return 127; } } wait(NULL); return 0; } $ musl-gcc test.c $ unshare -UrT ./a.out /bin/echo OK posix_spawn: Invalid argument $ TEST_FORK=1 unshare -UrT ./a.out /bin/echo OK OK A common expectation from applications is that they can use posix_spawn() as a drop-in replacement for fork()/exec() (when its child-tweaking features are sufficient), but this case breaks the expectation. Do you think it would make sense for musl to fallback to fork() in case vfork() fails in posix_spawn()? I've also opened a bug about this in glibc[2]. Maybe libcs could coordinate in how they handle this case. Alexey [1] https://github.com/python/cpython/issues/91307 [2] https://sourceware.org/bugzilla/show_bug.cgi?id=29115