posix_spawn(): errno in older glibc versions
Adhemerval Zanella
adhemerval.zanella@linaro.org
Mon Mar 4 20:46:00 GMT 2019
On 04/03/2019 10:04, Felipe Gasper wrote:
>
>> On Mar 4, 2019, at 2:59 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Felipe Gasper:
>>
>>> The clone()d process (which is a CLONE_VFORK) also, per strace, does a
>>> whole mess of signal-setting prior to the execve(). This also appears
>>> to violate vfork()âs documentation.
>>
>> How so?
>
> vforkâs man page says that only _exit or an exec function should follow the vfork in the child process, but I see a bunch of signal-handling calls in the child before the exec.
>
> I guess this is another case of just knowing that itâs ok with the tested versions of Linuxâs kernel?
I tried add to some information while writing the new posix_spawn regarding
how glibc uses clone (CLONE_VFORK) [1] in a safe way and why vfork is a
quite bad interface. Also, Rich Felker has written a post why vfork
is considered harmful [2].
Basically the way Linux posix_spawn uses clone (CLONE_VFORK) is by:
1. Allocate and providing its own stack for the new process. It avoid
potentially spilled information from the register in the stack
after the vfork call.
2. No signal handlers must run in child context, to avoid corrupt
parent's state. We block all signals (__libc_signal_block_all)
including the internal ones meant for cancellation and setXuid.
3. Child must synchronize with parent to enforce stack deallocation
and to possible return execv issues. This is done by the kernel
that enforces that a new process created with clone (CLONE_VFORK)
suspends the child executions and only resumes it when it exits
by either a _exit or a execve.
Man-pages description of vfork [3] describes why vfork itself should
not be used (on 'Caveats' part):
"The child process should take care not to modify the memory
in unintended ways, since such changes will be seen by the parent
process once the child terminates or executes another program. In
this regard, signal handlers can be especially problematic:"
And since glibc does not allow changing the signal handle for internal
signals, there is not safe way to prevent such issues (a program still
can call sigprocmask directly with syscall, but this comes with other
potential issues).
"When vfork() is called in a multithreaded process, only the calling
thread is suspended until the child terminates or executes a new program.
This means that the child is sharing an address space with other
running code. This can be dangerous if another thread in the parent
process changes credentials (using setuid(2) or similar), since there
are now two processes with different privilege levels running in the
same address space."
Unfortunately this is still and issue with posix_spawn [4] and I will
try to spend some time to see how to fix it.
So I think man-pages vfork description is pretty much accurate and there
is no need to change it. It states what vfork does, describes its history,
and its pitfalls. If I were to change anything it would be to add "do not
use this broken interface".
[1] https://sourceware.org/git/?p=glibc.git;a=commit;h=9ff72da471a509a8c19791efe469f47fa6977410
[2] https://ewontfix.com/7/
[3] https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/vfork.2
[4] https://sourceware.org/bugzilla/show_bug.cgi?id=14749
>
>>
>>> Also, at least on the Ubuntu box, posix_spawn()âs man page appears to
>>> be incorrect:
>>>
>>> -----
>>> The posix_spawn() and posix_spawnp() functions fail only in the case
>>> where the underlying fork(2) or vfork(2) call fails; in these cases,
>>> these functions return an error number, which will be one of the errors
>>> described for fork(2) or vfork(2).
>>> -----
>>>
>>> From what I see, the clone() clearly succeeds, but itâs the execâs
>>> success/failure that posix_spawn() reports. This is much more useful
>>> behavior, IMO--does that just need to make its way into the man page?
>>
>> Well, there is the matter of the emulations, where you do not actually
>> get a report of the execve error. I'm not sure to what extent the
>> man-pages project intends to cover those.
>
> All the same, the man page makes no mention of the (hugely preferable!) behaviour Iâm seeing in the newer glibc.
>
> Iâd be happy to file a bug report against the man page but wasnât successful in finding the repo to verify that the latest version hasnât addressed this. If you know it off-hand, would you be able to share?
Check https://www.kernel.org/doc/man-pages/download.html
>
> Thank you!
>
> -FG
>
More information about the Libc-help
mailing list