aboutsummaryrefslogtreecommitdiff
path: root/libc/bionic/pthread_internal.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Add an API for per-process disabling memory initialization.Peter Collingbourne2020-10-081-0/+76
| | | | | | | | | | | | | | | | | | | | | | | Introduce an android_mallopt(M_DISABLE_MEMORY_MITIGATIONS) API call that may be used to disable zero- or pattern-init on non-MTE hardware, or memory tagging on MTE hardware. The intent is that this function may be called at any time, including when there are multiple threads running. Disabling zero- or pattern-init is quite trivial, we just need to set a global variable to 0 via a Scudo API call (although there will be some separate work required on the Scudo side to make this operation thread-safe). It is a bit more tricky to disable MTE across a process, because the kernel does not provide an API for disabling tag checking in all threads in a process, only per-thread. We need to send a signal to each of the process's threads with a handler that issues the required prctl call, and lock thread creation for the duration of the API call to avoid races between thread enumeration and calls to pthread_create(). Bug: 135772972 Change-Id: I81ece86ace916eb6b435ab516cd431ec4b48a3bf
* Stop using the __ANDROID_API_x__ constants.Elliott Hughes2019-12-201-2/+2
| | | | | | | | | | | Historically we've made a few mistakes where they haven't matched the right number. And most non-Googlers are much more familiar with the numbers, so it seems to make sense to rely more on them. Especially in header files, which we actually expect real people to have to read from time to time. Test: treehugger Change-Id: I0d4a97454ee108de1d32f21df285315c5488d886
* Pass caller names to __pthread_internal_find for better errors.Elliott Hughes2019-02-011-3/+8
| | | | | | | | | | | | | | | On http://b/122082295 we had this abort: 12-27 15:29:31.237 10222 10814 10848 F libc : invalid pthread_t 0xb1907960 passed to libc This wasn't super helpful. We can do better. Now you get something like this instead: 03-27 02:34:58.754 25329 25329 W libc : invalid pthread_t (0) passed to pthread_join Test: adb shell crasher Bug: http://b/123255692 Change-Id: I1d545665a233308480cc3747ec3120e2b6de0453
* Factor out ScopedRWLock into its own headerRyan Prichard2019-01-161-18/+1
| | | | | | Bug: http://b/78026329 Test: bionic unit tests Change-Id: I1d1276da835bc8ecac7a7abb714d639a1ee58007
* Reorganize static TLS memory for ELF TLSRyan Prichard2019-01-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For ELF TLS "local-exec" accesses, the static linker assumes that an executable's TLS segment is located at a statically-known offset from the thread pointer (i.e. "variant 1" for ARM and "variant 2" for x86). Because these layouts are incompatible, Bionic generally needs to allocate its TLS slots differently between different architectures. To allow per-architecture TLS slots: - Replace the TLS_SLOT_xxx enumerators with macros. New ARM slots are generally negative, while new x86 slots are generally positive. - Define a bionic_tcb struct that provides two things: - a void* raw_slots_storage[BIONIC_TLS_SLOTS] field - an inline accessor function: void*& tls_slot(size_t tpindex); For ELF TLS, it's necessary to allocate a temporary TCB (i.e. TLS slots), because the runtime linker doesn't know how large the static TLS area is until after it has loaded all of the initial solibs. To accommodate Golang, it's necessary to allocate the pthread keys at a fixed, small, positive offset from the thread pointer. This CL moves the pthread keys into bionic_tls, then allocates a single mapping per thread that looks like so: - stack guard - stack [omitted for main thread and with pthread_attr_setstack] - static TLS: - bionic_tcb [exec TLS will either precede or succeed the TCB] - bionic_tls [prefixed by the pthread keys] - [solib TLS segments will be placed here] - guard page As before, if the new mapping includes a stack, the pthread_internal_t is allocated on it. At startup, Bionic allocates a temporary bionic_tcb object on the stack, then allocates a temporary bionic_tls object using mmap. This mmap is delayed because the linker can't currently call async_safe_fatal() before relocating itself. Later, Bionic allocates a stack-less thread mapping for the main thread, and copies slots from the temporary TCB to the new TCB. (See *::copy_from_bootstrap methods.) Bug: http://b/78026329 Test: bionic unit tests Test: verify that a Golang app still works Test: verify that a Golang app crashes if bionic_{tls,tcb} are swapped Merged-In: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3 Change-Id: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3 (cherry picked from commit 1e660b70da625fcbf1e43dfae09b7b4817fa1660)
* Fix/suppress bionic google-explicit-constructor warningsChih-Hung Hsieh2019-01-021-1/+1
| | | | | | | | * Add explicit to conversion constructors/operators Bug: 28341362 Test: make with WITH_TIDY=1 DEFAULT_GLOBAL_TIDY_CHECKS=-*,google-explicit-constructor Change-Id: Id1ad0327c1b8c6f094bcbb3ae599bc1f716b3f2f
* Make android_get_application_target_sdk_version available to the NDK.Elliott Hughes2018-11-151-2/+1
| | | | | | | | | | | Also move this and android_get_device_api_level into <android/api-level.h> so that they're always available. This involves cleaning up <sys/cdefs.h> slightly. Bug: N/A Test: builds Change-Id: I25435c55f3549cd0d827a7581bee75ea8228028b
* Clean up bionic_macros.h a bit.Elliott Hughes2018-10-251-1/+1
| | | | | | | | | | | Use <android-base/macros.h> instead where possible, and move the bionic macros out of the way of the libbase ones. Yes, there are folks who manage to end up with both included at once (thanks OpenGL!), and cleaning that up doesn't seem nearly as practical as just making this change. Bug: N/A Test: builds Change-Id: I23fc544f39d5addf81dc61471771a5438778895b
* Drop thread list lock before abort.Christopher Ferris2017-09-181-3/+7
| | | | | | | Bug: 65656273 Test: Ran the app and verified it crashes instead of deadlocks. Change-Id: I7dbe653d50a635a23993c99c5f73ca094ee80b28
* Move libc_log code into libasync_safe.Christopher Ferris2017-05-031-3/+4
| | | | | | | | | | | | | | | | | | This library is used by a number of different libraries in the system. Make it easy for platform libraries to use this library and create an actual exported include file. Change the names of the functions to reflect the new name of the library. Run clang_format on the async_safe_log.cpp file since the formatting is all over the place. Bug: 31919199 Test: Compiled for angler/bullhead, and booted. Test: Ran bionic unit tests. Test: Ran the malloc debug tests. Change-Id: I8071bf690c17b0ea3bc8dc5749cdd5b6ad58478a
* Fix leak of bionic TLS when threads are detached.Josh Gao2017-03-071-4/+0
| | | | | | | | | | | | __pthread_internal_free doesn't happen on threads that are detached, causing the bionic TLS allocation (and guard pages) to be leaked. Fix the leak, and name the allocations to make things apparent if this ever happens again. Bug: http://b/36045112 Test: manually ran a program that detached empty threads Change-Id: Id1c7852b7384474244f7bf5a0f7da54ff962e0a1
* Allocate thread local buffers in __init_tls.Josh Gao2017-02-221-0/+4
| | | | | | | | | | | | | | | | | | Thread local buffers were using pthread_setspecific for storage with lazy initialization. pthread_setspecific shares TLS slots between the linker and libc.so, so thread local buffers being initialized in a different order between libc.so and the linker meant that bad things would happen (manifesting as snprintf not working because the locale was mangled) Bug: http://b/20464031 Test: /data/nativetest64/bionic-unit-tests/bionic-unit-tests everything passes Test: /data/nativetest/bionic-unit-tests/bionic-unit-tests thread_local tests are failing both before and after (KUSER_HELPERS?) Test: /data/nativetest64/bionic-unit-tests-static/bionic-unit-tests-static no additional failures Change-Id: I9f445a77c6e86979f3fa49c4a5feecf6ec2b0c3f
* Downgrade the special case of pthread_t(0) to a warning.Elliott Hughes2017-02-211-1/+10
| | | | | | | | | | | | | | So far this is the only issue we've hit in vendor code, and we've hit it several times already. Rather than try to fix bullhead (the current problem), let's just admit that the special case of 0 is a lot less worrying. Also fix the test expectations to correspond to the new abort message. Bug: http://b/35455349 (crashes on 0) Bug: http://b/35622944 (tests) Test: ran tests Change-Id: Iec57011fa699a954ebeaec151db2193e36d1ef35
* Include the pthread_t in the "bad pthread_t" fatal abort.Elliott Hughes2017-02-171-1/+1
| | | | | | | | Also reword the message to be stronger. Bug: http://b/35455349 Test: manual Change-Id: I8f34fd42f3b635c95a7b921645a016fb303ce3ad
* Be more strict about using invalid `pthread_t`s.Elliott Hughes2017-02-131-19/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Another release, another attempt to remove the global thread list. But this time, let's admit that it's not going away. We can switch to using a read/write lock for the global thread list, and to aborting rather than quietly returning ESRCH if we're given an invalid pthread_t. This change affects pthread_detach, pthread_getcpuclockid, pthread_getschedparam/pthread_setschedparam, pthread_join, and pthread_kill: instead of returning ESRCH when passed an invalid pthread_t, if you're targeting O or above, they'll abort with the message "attempt to use invalid pthread_t". Note that this doesn't change behavior as much as you might think: the old lookup only held the global thread list lock for the duration of the lookup, so there was still a race between that and the dereference in the caller, given that callers actually need the tid to pass to some syscall or other, and sometimes update fields in the pthread_internal_t struct too. (This patch replaces such users with calls to pthread_gettid_np, which at least makes the TOCTOU window smaller.) We can't check thread->tid against 0 to see whether a pthread_t is still valid because a dead thread gets its thread struct unmapped along with its stack, so the dereference isn't safe. Taking the affected functions one by one: * pthread_getcpuclockid and pthread_getschedparam/pthread_setschedparam should be fine. Unsafe calls to those seem highly unlikely. * Unsafe pthread_detach callers probably want to switch to pthread_attr_setdetachstate instead, or using pthread_detach(pthread_self()) from the new thread's start routine rather than doing the detach in the parent. * pthread_join calls should be safe anyway, because a joinable thread won't actually exit and unmap until it's joined. If you're joining an unjoinable thread, the fix is to stop marking it detached. If you're joining an already-joined thread, you need to rethink your design. * Unsafe pthread_kill calls aren't portably fixable. (And are obviously inherently non-portable as-is.) The best alternative on Android is to use pthread_gettid_np at some point that you know the thread to be alive, and then call kill/tgkill directly. That's still not completely safe because if you're too late, the tid may have been reused, but then your code is inherently unsafe anyway. Bug: http://b/19636317 Test: ran tests Change-Id: I0372c4428e8a7f1c3af5c9334f5d9c25f2c73f21
* Revert "Remove the global thread list."Elliott Hughes2017-02-021-0/+98
| | | | | | | | This reverts commit b0e8c565a622b5519e03d4416b0b5b1a5f20d7f5. Breaks swiftshader (http:/b/34883464). Change-Id: I7b21193ba8a78f07d7ac65e41d0fe8516940a83b
* Remove the global thread list.Elliott Hughes2017-01-071-98/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Another release, another attempt to fix this bug. This change affects pthread_detach, pthread_getcpuclockid, pthread_getschedparam/pthread_setschedparam, pthread_join, and pthread_kill: instead of returning ESRCH when passed an invalid pthread_t, they'll now SEGV. Note that this doesn't change behavior as much as you might think: the old lookup only held the global thread list lock for the duration of the lookup, so there was still a race between that and the dereference in the caller, given that callers actually need the tid to pass to some syscall or other, and sometimes update fields in the pthread_internal_t struct too. We can't check thread->tid against 0 to see whether a pthread_t is still valid because a dead thread gets its thread struct unmapped along with its stack, so the dereference isn't safe. Taking the affected functions one by one: * pthread_getcpuclockid and pthread_getschedparam/pthread_setschedparam should be fine. Unsafe calls to those seem highly unlikely. * Unsafe pthread_detach callers probably want to switch to pthread_attr_setdetachstate instead, or using pthread_detach(pthread_self()) from the new thread's start routine rather than doing the detach in the parent. * pthread_join calls should be safe anyway, because a joinable thread won't actually exit and unmap until it's joined. If you're joining an unjoinable thread, the fix is to stop marking it detached. If you're joining an already-joined thread, you need to rethink your design. * Unsafe pthread_kill calls aren't portably fixable. (And are obviously inherently non-portable as-is.) The best alternative on Android is to use pthread_gettid_np at some point that you know the thread to be alive, and then call kill/tgkill directly. That's still not completely safe because if you're too late, the tid may have been reused, but then your code is inherently unsafe anyway. If we find too much code is still broken, we can come back and disable the global thread list lookups for anything targeting >= O and then have another go at really removing this in P... Bug: http://b/19636317 Test: N6P boots, bionic tests pass Change-Id: Ia92641212f509344b99ee2a9bfab5383147fcba6
* Add check for pthread_self() when looking up a threadDimitry Ivanov2016-02-041-0/+6
| | | | | | | | | | | | | | Check if thread_id is in fact pthread_self before locking on g_thread_list_lock in __pthread_internal_find. The main reason for doing this is not performance but to allow the linker use raise() which was not working because pthread_kill() couldn't find pthread_self() thread because the global thread list is initialized in libc.so and the linker's version of this list is empty. Bug: http://b/25867917 Change-Id: I18fe620e8cd465b30f0e1ff45fff32958f3c5c00
* Revert "Cause Fatal error when invalid pthread_id is detected."Yabin Cui2015-03-261-8/+4
| | | | | | | | Some code like in https://buganizer.corp.google.com/u/0/issues/19942911 need to change first. This reverts commit 03324780aae9ff28c8acf52debf0ea39120e5ab8. Change-Id: I13ff1e5b3d0672bae9cde234ffba32fbbf33d338
* Cause Fatal error when invalid pthread_id is detected.Yabin Cui2015-03-251-4/+8
| | | | | | | | | This is a patch testing whether we can use abort() instead of returning ESRCH for invalid pthread ids. It is an intermediate step to remove g_thread_list/g_thread_list_lock. Bug: 19636317 Change-Id: Idd8e4a346c7ce91e1be0c2ebcb78ce51c0d0a31d
* Let g_thread_list_lock only protect g_thread_list.Yabin Cui2015-03-231-0/+92
As glibc/netbsd don't protect access to thread struct members by a global lock, we don't want to do it either. This change reduces the responsibility of g_thread_list_lock to only protect g_thread_list. Bug: 19636317 Change-Id: I897890710653dac165d8fa4452c7ecf74abdbf2b