Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 24 May 2021 17:40:14 +0200
From: Szabolcs Nagy <>
To: Alexey Izbyshev <>
Subject: Re: Potentially infinite loop in posix_spawn'ed child

* Alexey Izbyshev <> [2021-05-24 13:09:21 +0300]:
> As an aside, perhaps it would make sense to call execve() in posix_spawn()
> implementation via a hidden symbol? This would both make it consistent with
> posix_spawnp() and avoid any trouble with user code executing in a vfork'ed
> child if execve() is overridden via e.g. LD_PRELOAD.

libc symbols cannot be interposed by user code, they are
all resolved within the libc, there should be no dynamic
symbolic relocation in except for global data and
malloc symbols (those are explicitly exported).

so musl posix_spawn always calls musl's execve.
except with static linking you cannot hide libc symbols
like that unless musl uses a different name internally
(but that prevents the compiler recognizing builtins in
libc code if we ever want to optimize them).

> #include <errno.h>
> #include <signal.h>
> #include <spawn.h>
> #include <unistd.h>
> static int p[2];
> int execve(const char *path, char *const argv[], char *const envp[]) {

this is only called with static linking, but that is not
supportable usage: libc may provide execve and e.g. signal
in the same object file and then there is a conflict
because signal has to be linked. so this is just a user

>   close(p[1]);
>   kill(getppid(), SIGKILL);
>   read(p[0], &(char){0}, 1);
>   errno = ENOENT;
>   return -1;
> }
> int main(int argc, char *argv[], char *envp[]) {
>     signal(SIGPIPE, SIG_IGN);
>     pipe(p);
>     posix_spawn(0L, "/non-existing", 0L, 0L, argv, envp);
>     return 0;
> }

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.