History log of /seL4-test-master/projects/musllibc/src/process/posix_spawn.c
Revision Date Author Comments
# 8f7bc690 05-Dec-2014 Rich Felker <dalias@aerifal.cx>

use direct syscall rather than write function in posix_spawn child

the write function is a cancellation point and accesses thread-local
state belonging to the calling thread in the parent process. since
cancellation is blocked for the duration of posix_spawn, this is
probably safe, but it's fragile and unnecessary. making the syscall
directly is just as easy and clearly safe.


# 1c12c243 05-Dec-2014 Rich Felker <dalias@aerifal.cx>

don't fail posix_spawn on failed close

the resolution of austin group issue #370 removes the requirement that
posix_spawn fail when the close file action is performed on an
already-closed fd. since there are no other meaningful errors for
close, just ignoring the return value completely is the simplest fix.


# 0b3d33d4 01-Jul-2014 Rich Felker <dalias@aerifal.cx>

fix ungrammatical comment in posix_spawn code


# dd5f50da 29-May-2014 Rich Felker <dalias@aerifal.cx>

support linux kernel apis (new archs) with old syscalls removed

such archs are expected to omit definitions of the SYS_* macros for
syscalls their kernels lack from arch/$ARCH/bits/syscall.h. the
preprocessor is then able to select the an appropriate implementation
for affected functions. two basic strategies are used on a
case-by-case basis:

where the old syscalls correspond to deprecated library-level
functions, the deprecated functions have been converted to wrappers
for the modern function, and the modern function has fallback code
(omitted at the preprocessor level on new archs) to make use of the
old syscalls if the new syscall fails with ENOSYS. this also improves
functionality on older kernels and eliminates the incentive to program
with deprecated library-level functions for the sake of compatibility
with older kernels.

in other situations where the old syscalls correspond to library-level
functions which are not deprecated but merely lack some new features,
such as the *at functions, the old syscalls are still used on archs
which support them. this may change at some point in the future if or
when fallback code is added to the new functions to make them usable
(possibly with reduced functionality) on old kernels.


# 594c827a 24-May-2014 Rich Felker <dalias@aerifal.cx>

support kernels with no SYS_open syscall, only SYS_openat

open is handled specially because it is used from so many places, in
so many variants (2 or 3 arguments, setting errno or not, and
cancellable or not). trying to do it as a function would not only
increase bloat, but would also risk subtle breakage.

this is the first step towards supporting "new" archs where linux
lacks "old" syscalls.


# 8011614d 11-Feb-2014 Rich Felker <dalias@aerifal.cx>

make posix_spawn accept null pid pointer arguments

this is a requirement in the specification that was overlooked.


# 3c5c5e6f 09-Aug-2013 Rich Felker <dalias@aerifal.cx>

optimize posix_spawn to avoid spurious sigaction syscalls

the trick here is that sigaction can track for us which signals have
ever had a signal handler set for them, and only those signals need to
be considered for reset. this tracking mask may have false positives,
since it is impossible to remove bits from it without race conditions.
false negatives are not possible since the mask is updated with atomic
operations prior to making the sigaction syscall.

implementation-internal signals are set to SIG_IGN rather than SIG_DFL
so that a signal raised in the parent (e.g. calling pthread_cancel on
the thread executing pthread_spawn) does not have any chance make it
to the child, where it would cause spurious termination by signal.

this change reduces the minimum/typical number of syscalls in the
child from around 70 to 4 (including execve). this should greatly
improve the performance of posix_spawn and other interfaces which use
it (popen and system).

to facilitate these changes, sigismember is also changed to return 0
rather than -1 for invalid signals, and to return the actual status of
implementation-internal signals. POSIX allows but does not require an
error on invalid signal numbers, and in fact returning an error tends
to confuse applications which wrongly assume the return value of
sigismember is boolean.


# 65d7aa4d 09-Aug-2013 Rich Felker <dalias@aerifal.cx>

fix missing errno from exec failure in posix_spawn

failures prior to the exec attempt were reported correctly, but on
exec failure, the return value contained junk.


# b06dc666 17-Jul-2013 Rich Felker <dalias@aerifal.cx>

make posix_spawn (and functions that use it) use CLONE_VFORK flag

this is both a minor scheduling optimization and a workaround for a
difficult-to-fix bug in qemu app-level emulation.

from the scheduling standpoint, it makes no sense to schedule the
parent thread again until the child has exec'd or exited, since the
parent will immediately block again waiting for it.

on the qemu side, as regular application code running on an underlying
libc, qemu cannot make arbitrary clone syscalls itself without
confusing the underlying implementation. instead, it breaks them down
into either fork-like or pthread_create-like cases. it was treating
the code in posix_spawn as pthread_create-like, due to CLONE_VM, which
caused horribly wrong behavior: CLONE_FILES broke the synchronization
mechanism, CLONE_SIGHAND broke the parent's signals, and CLONE_THREAD
caused the child's exec to end the parent -- if it hadn't already
crashed. however, qemu special-cases CLONE_VFORK and emulates that
with fork, even when CLONE_VM is also specified. this also gives
incorrect semantics for code that really needs the memory sharing, but
posix_spawn does not make use of the vm sharing except to avoid
momentary double commit charge.

programs using posix_spawn (including via popen) should now work
correctly under qemu app-level emulation.


# a0473a0c 26-Apr-2013 Rich Felker <dalias@aerifal.cx>

remove explicit locking to prevent __synccall setuid during posix_spawn

for the duration of the vm-sharing clone used by posix_spawn, all
signals are blocked in the parent process, including
implementation-internal signals. since __synccall cannot do anything
until successfully signaling all threads, the fact that signals are
blocked automatically yields the necessary safety.

aside from debloating and general simplification, part of the
motivation for removing the explicit lock is to simplify the
synchronization logic of __synccall in hopes that it can be made
async-signal-safe, which is needed to make setuid and setgid, which
depend on __synccall, conform to the standard. whether this will be
possible remains to be seen.


# 4862864f 03-Feb-2013 Rich Felker <dalias@aerifal.cx>

fix unsigned comparison bug in posix_spawn

read should never return anything but 0 or sizeof ec here, but if it
does, we want to treat any other return as "success". then the caller
will get back the pid and is responsible for waiting on it when it
immediately exits.


# fb6b159d 03-Feb-2013 Rich Felker <dalias@aerifal.cx>

overhaul posix_spawn to use CLONE_VM instead of vfork

the proposed change was described in detail in detail previously on
the mailing list. in short, vfork is unsafe because:

1. the compiler could make optimizations that cause the child to
clobber the parent's local vars.

2. strace is buggy and allows the vforking parent to run before the
child execs when run under strace.

the new design uses a close-on-exec pipe instead of vfork semantics to
synchronize the parent and child so that the parent does not return
before the child has finished using its arguments (and now, also its
stack). this also allows reporting exec failures to the caller instead
of giving the caller a child that mysteriously exits with status 127
on exec error.

basic testing has been performed on both the success and failure code
paths. further testing should be done.


# 599f9736 19-Oct-2012 Rich Felker <dalias@aerifal.cx>

fix usage of locks with vfork

__release_ptc() is only valid in the parent; if it's performed in the
child, the lock will be unlocked early then double-unlocked later,
corrupting the lock state.


# 97c8bdd8 18-Oct-2012 Rich Felker <dalias@aerifal.cx>

fix parent-memory-clobber in posix_spawn (environ)


# 44eb4d8b 18-Oct-2012 Rich Felker <dalias@aerifal.cx>

overhaul system() and popen() to use vfork; fix various related bugs

since we target systems without overcommit, special care should be
taken that system() and popen(), like posix_spawn(), do not fail in
processes whose commit charges are too high to allow ordinary forking.

this in turn requires special precautions to ensure that the parent
process's signal handlers do not end up running in the shared-memory
child, where they could corrupt the state of the parent process.

popen has also been updated to use pipe2, so it does not have a
fd-leak race in multi-threaded programs. since pipe2 is missing on
older kernels, (non-atomic) emulation has been added.

some silly bugs in the old code should be gone too.


# d5304147 15-Oct-2012 Rich Felker <dalias@aerifal.cx>

block uid/gid changes during posix_spawn

usage of vfork creates a situation where a process of lower privilege
may momentarily have write access to the memory of a process of higher
privilege.

consider the case of a multi-threaded suid program which is calling
posix_spawn in one thread while another thread drops the elevated
privileges then runs untrusted (relative to the elevated privilege)
code as the original invoking user. this untrusted code can then
potentially modify the data the child process will use before calling
exec, for example changing the pathname or arguments that will be
passed to exec.

note that if vfork is implemented as fork, the lock will not be held
until the child execs, but since memory is not shared it does not
matter.


# d62f4e98 14-Sep-2012 Rich Felker <dalias@aerifal.cx>

use vfork if possible in posix_spawn

vfork is implemented as the fork syscall (with no atfork handlers run)
on archs where it is not available, so this change does not introduce
any change in behavior or regression for such archs.


# 400c5e5c 06-Sep-2012 Rich Felker <dalias@aerifal.cx>

use restrict everywhere it's required by c99 and/or posix 2008

to deal with the fact that the public headers may be used with pre-c99
compilers, __restrict is used in place of restrict, and defined
appropriately for any supported compiler. we also avoid the form
[restrict] since older versions of gcc rejected it due to a bug in the
original c99 standard, and instead use the form *restrict.


# 13cd9695 13-Sep-2011 Rich Felker <dalias@aerifal.cx>

fix various errors in function signatures/prototypes found by nsz


# f48832ee 28-May-2011 Rich Felker <dalias@aerifal.cx>

fix backwards posix_spawn file action order


# a0ae0b09 28-May-2011 Rich Felker <dalias@aerifal.cx>

add file actions support to posix_spawn


# d6c0c978 28-May-2011 Rich Felker <dalias@aerifal.cx>

posix_spawn: honor POSIX_SPAWN_SETSIGDEF flag


# c97f0d99 28-May-2011 Rich Felker <dalias@aerifal.cx>

initial implementation of posix_spawn

file actions are not yet implemented, but everything else should be
mostly complete and roughly correct.