about summary refs log tree commit diff
path: root/src/process/_Fork.c
Commit message (Collapse)AuthorAgeFilesLines
* fix public clone function to be safe and usable by applicationsRich Felker2023-06-011-10/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | the clone() function has been effectively unusable since it was added, due to producing a child process with inconsistent state. in particular, the child process's thread structure still contains the tid, thread list pointers, thread count, and robust list for the parent. this will cause malfunction in interfaces that attempt to use the tid or thread list, some of which are specified to be async-signal-safe. this patch attempts to make clone() consistent in a _Fork-like sense. as in _Fork, when the parent process is multi-threaded, the child process inherits an async-signal context where it cannot call AS-unsafe functions, but its context is now intended to be safe for calling AS-safe functions. making clone fork-like would also be a future option, if it turns out that this is what makes sense to applications, but it's not done at this time because the changes would be more invasive. in the case where the CLONE_VM flag is used, clone is only vfork-like, not _Fork-like. in particular, the child will see itself as having the parent's tid, and cannot safely call any libc functions but one of the exec family or _exit. handling of flags and variadic arguments is also changed so that arguments are only consumed with flags that indicate their presence, and so that flags which produce an inconsistent state are disallowed (reported as EINVAL). in particular, all libc functions carry a contract that they are only callable with ABI requirements met, which includes having a valid thread pointer to a thread structure that's unique within the process, and whose contents are opaque and only able to be setup internally by the implementation. the only way for an application to use flags that violate these requirements without executing any libc code is to perform the syscall from application-provided asm.
* fix broken thread list unlocking after forkRich Felker2023-06-011-1/+1
| | | | | | | | | | | apparently Linux clears the registered exit futex address on fork. this means that, if after forking the child process becomes multithreaded and the original thread exits, the thread list will never be unlocked, and future attempts to use the thread list will deadlock. re-register the exit futex address after _Fork in the child to ensure that it's preserved.
* fix potential deadlock between multithreaded fork and aioRich Felker2022-10-191-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | as reported by Alexey Izbyshev, there is a lock order inversion deadlock between the malloc lock and aio maplock at MT-fork time: _Fork attempts to take the aio maplock while fork already has the malloc lock, but a concurrent aio operation holding the maplock may attempt to allocate memory. move the __aio_atfork calls in the parent from _Fork to fork, and reorder the lock before most other locks, since nothing else depends on aio(*). this leaves us with the possibility that the child will not be able to obtain the read lock, if _Fork is used directly and happens concurrent with an aio operation. however, in that case, the child context is an async signal context that cannot call any further aio functions, so all we need is to ensure that close does not attempt to perform any aio cancellation. this can be achieved just by nulling out the map pointer. (*) even if other functions call close, they will only need a read lock, not a write lock, and read locks being recursive ensures they can obtain it. moreover, the number of read references held is bounded by something like twice the number of live threads, meaning that the read lock count cannot saturate.
* move aio implementation details to a proper internal headerRich Felker2020-10-141-0/+1
| | | | | also fix the lack of declaration (and thus hidden visibility) in __stdio_close's use of __aio_close.
* implement _Fork and refactor fork using itRich Felker2020-10-141-9/+2
| | | | | | | the _Fork interface is defined for future issue of POSIX as the outcome of Austin Group issue 62, which drops the AS-safety requirement for fork, and provides an AS-safe replacement that does not run the registered atfork handlers.
* rename fork source fileRich Felker2020-10-141-0/+44
this is in preparation for implementing _Fork from POSIX-future, factored as a separate commit to improve readability of history.