about summary refs log tree commit diff
path: root/src/thread/synccall.c
Commit message (Collapse)AuthorAgeFilesLines
* fix mips-specific bug in synccall (too little space for signal mask)Rich Felker2013-09-021-5/+3
| | | | | switch to the new __block_all_sigs/__restore_sigs internal API to clean up the code too.
* in synccall, ignore the signal before any threads' signal handlers returnRich Felker2013-09-021-4/+4
| | | | | | this protects against deadlock from spurious signals (e.g. sent by another process) arriving after the controlling thread releases the other threads from the sync operation.
* fix invalid pointer in synccall (multithread setuid, etc.)Rich Felker2013-09-021-0/+1
| | | | | | | the head pointer was not being reset between calls to synccall, so any use of this interface more than once would build the linked list incorrectly, keeping the (now invalid) list nodes from the previous call.
* synccall signal handler need not handle dead threads anymoreRich Felker2013-04-261-9/+0
| | | | | | they have already blocked signals before decrementing the thread count, so the code being removed is unreachable in the case where the thread is no longer counted.
* remove __SYSCALL_SSLEN arch macro in favor of using public _NSIGRich Felker2013-03-261-2/+2
| | | | | | | | | | | | | | the issue at hand is that many syscalls require as an argument the kernel-ABI size of sigset_t, intended to allow the kernel to switch to a larger sigset_t in the future. previously, each arch was defining this size in syscall_arch.h, which was redundant with the definition of _NSIG in bits/signal.h. as it's used in some not-quite-portable application code as well, _NSIG is much more likely to be recognized and understood immediately by someone reading the code, and it's also shorter and less cluttered. note that _NSIG is actually 65/129, not 64/128, but the division takes care of throwing away the off-by-one part.
* clean up sloppy nested inclusion from pthread_impl.hRich Felker2012-11-081-0/+1
| | | | | | | | | | | | | | this mirrors the stdio_impl.h cleanup. one header which is not strictly needed, errno.h, is left in pthread_impl.h, because since pthread functions return their error codes rather than using errno, nearly every single pthread function needs the errno constants. in a few places, rather than bringing in string.h to use memset, the memset was replaced by direct assignment. this seems to generate much better code anyway, and makes many functions which were previously non-leaf functions into leaf functions (possibly eliminating a great deal of bloat on some platforms where non-leaf functions require ugly prologue and/or epilogue).
* support for TLS in dynamic-loaded (dlopen) modulesRich Felker2012-10-051-13/+2
| | | | | | | | | | | | | | | | | | | | | unlike other implementations, this one reserves memory for new TLS in all pre-existing threads at dlopen-time, and dlopen will fail with no resources consumed and no new libraries loaded if memory is not available. memory is not immediately distributed to running threads; that would be too complex and too costly. instead, assurances are made that threads needing the new TLS can obtain it in an async-signal-safe way from a buffer belonging to the dynamic linker/new module (via atomic fetch-and-add based allocator). I've re-appropriated the lock that was previously used for __synccall (synchronizing set*id() syscalls between threads) as a general pthread_create lock. it's a "backwards" rwlock where the "read" operation is safe atomic modification of the live thread count, which multiple threads can perform at the same time, and the "write" operation is making sure the count does not increase during an operation that depends on it remaining bounded (__synccall or dlopen). in static-linked programs that don't use __synccall, this lock is a no-op and has no cost.
* fix (hopefully) all hard-coded 8's for kernel sigset_t sizeRich Felker2012-08-091-2/+4
| | | | | | | | | | some minor changes to how hard-coded sets for thread-related purposes are handled were also needed, since the old object sizes were not necessarily sufficient. things have gotten a bit ugly in this area, and i think a cleanup is in order at some point, but for now the goal is just to get the code working on all supported archs including mips, which was badly broken by linux rejecting syscalls with the wrong sigset_t size.
* remove everything related to forkallRich Felker2012-05-221-8/+0
| | | | | | | | | | i made a best attempt, but the intended semantics of this function are fundamentally contradictory. there is no consistent way to handle ownership of locks when forking a multi-threaded process. the code could have worked by accident for programs that only used normal mutexes and nothing else (since they don't actually store or care about their owner), but that's about it. broken-by-design interfaces that aren't even in glibc (only solaris) don't belong in musl.
* pthread and synccall cleanup, new __synccall_wait opRich Felker2011-08-121-2/+10
| | | | | | | | | fix up clone signature to match the actual behavior. the new __syncall_wait function allows a __synccall callback to wait for other threads to continue without returning, so that it can resume action after the caller finishes. this interface could be made significantly more general/powerful with minimal effort, but i'll wait to do that until it's actually useful for something.
* fix bug in synccall with no threads: lock was taken but never releasedRich Felker2011-07-301-4/+4
|
* new attempt at making set*id() safe and robustRich Felker2011-07-291-0/+109
changing credentials in a multi-threaded program is extremely difficult on linux because it requires synchronizing the change between all threads, which have their own thread-local credentials on the kernel side. this is further complicated by the fact that changing the real uid can fail due to exceeding RLIMIT_NPROC, making it possible that the syscall will succeed in some threads but fail in others. the old __rsyscall approach being replaced was robust in that it would report failure if any one thread failed, but in this case, the program would be left in an inconsistent state where individual threads might have different uid. (this was not as bad as glibc, which would sometimes even fail to report the failure entirely!) the new approach being committed refuses to change real user id when it cannot temporarily set the rlimit to infinity. this is completely POSIX conformant since POSIX does not require an implementation to allow real-user-id changes for non-privileged processes whatsoever. still, setting the real uid can fail due to memory allocation in the kernel, but this can only happen if there is not already a cached object for the target user. thus, we forcibly serialize the syscalls attempts, and fail the entire operation on the first failure. this *should* lead to an all-or-nothing success/failure result, but it's still fragile and highly dependent on kernel developers not breaking things worse than they're already broken. ideally linux will eventually add a CLONE_USERCRED flag that would give POSIX conformant credential changes without any hacks from userspace, and all of this code would become redundant and could be removed ~10 years down the line when everyone has abandoned the old broken kernels. i'm not holding my breath...