Commit graph

18 commits

Author SHA1 Message Date
Evgeny Eltsin
8a18af52d9 Make more pthread functions weak for native bridge
These are using __pthread_internal_*.

Test: run bionic-unit-tests on cuttlefish
Change-Id: Idbb2503f03bd9f1f2a20fced34b734f573c1c0ad
2019-09-25 16:55:47 +02:00
Elliott Hughes
5bb113cba2 Pass caller names to __pthread_internal_find for better errors.
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
2019-02-01 16:31:10 -08:00
Elliott Hughes
11859d467c Be more strict about using invalid pthread_ts.
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
2017-02-13 17:59:29 -08:00
Elliott Hughes
bcb152903a Revert "Stop checking the global thread list in several trivial cases."
This reverts commit f5a4992b71.

Breaks OMX_ImgEnc in cameraserver (http://b/35088254).

Change-Id: I6dcf12706a184b0b8b72451584567a42dfa1bb4f
2017-02-07 21:05:30 +00:00
Elliott Hughes
f5a4992b71 Stop checking the global thread list in several trivial cases.
Since removing the global thread is hard, let's take the different
groups of functions individually.

The existing code was racy anyway, because the thread might still be
on the list but have exited (leaving tid == 0).

Bug: http://b/19636317
Test: ran tests
Change-Id: Icc0986ff124d5f9b8a653edf718c549d1563973b
2017-02-06 14:09:53 -08:00
Elliott Hughes
7484c21c4c Revert "Remove the global thread list."
This reverts commit b0e8c565a6.

Breaks swiftshader (http:/b/34883464).

Change-Id: I7b21193ba8a78f07d7ac65e41d0fe8516940a83b
2017-02-02 02:41:38 +00:00
Elliott Hughes
b0e8c565a6 Remove the global thread list.
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
2017-01-07 14:16:46 -08:00
Elliott Hughes
725b2a96a7 Add pthread_getname_np.
Also guard both these GNU extensions with _GNU_SOURCE.

Also improve the tests to test each case on both the current thread and
another thread, since the code paths are totally different.

Bug: http://b/27810459
Change-Id: I72b05bca5c5b6ca8ba4585b8edfb716a1c252f92
2016-03-23 17:40:25 -07:00
Yabin Cui
673b15e4ee Let g_thread_list_lock only protect g_thread_list.
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
2015-03-23 19:03:49 -07:00
Elliott Hughes
05fc1d7050 Add missing includes.
Change-Id: Ibf549266a19a67eb9158d341a69dddfb654be669
2015-01-28 19:23:11 -08:00
Elliott Hughes
68d98d832b Assume glibc >= 2.15.
This catches one trivial difference between us and glibc --- the error
returned by pthread_setname_np for an invalid pthread_t.

Change-Id: If4c21e22107c6488333d11184f8005f8669096c2
2014-11-12 21:03:26 -08:00
Elliott Hughes
f73183f1a3 More cases where libc should use O_CLOEXEC.
Change-Id: Idfa111aeebc5deca2399dae919e8b72eb54c23c0
2014-08-26 16:20:59 -07:00
Elliott Hughes
39b644a0e2 Remove dead NULL checks from pthread code.
GCC is removing these checks anyway because it knows the arguments
must be non-null, so leaving this code around is just confusing.

We know from experience that people were shipping code with locking
bugs because they weren't checking for error returns. Failing hard
like glibc does seems the better choice. (And it's what the checked
in code was already doing; this patch doesn't change that. It just
makes it more obvious that that's what's going on.)

Change-Id: I167c6d7c0a296822baf0cb9b43b97821eba7ab35
2014-03-04 10:55:39 -08:00
Elliott Hughes
a41ba2f0bf Fix pthread_setname_np's behavior on invalid pthread_ts.
Change-Id: I0a154beaab4d164ac812f2564d12e4d79b80a8e8
2013-03-21 20:02:35 -07:00
Elliott Hughes
40eabe24e4 Fix the pthread_setname_np test.
Fix the pthread_setname_np test to take into account that emulator kernels are
so old that they don't support setting the name of other threads.

The CLONE_DETACHED thread is obsolete since 2.5 kernels.

Rename kernel_id to tid.

Fix the signature of __pthread_clone.

Clean up the clone and pthread_setname_np implementations slightly.

Change-Id: I16c2ff8845b67530544bbda9aa6618058603066d
2013-02-15 12:08:59 -08:00
Elliott Hughes
3e898476c7 Revert "Revert "More pthreads cleanup.""
This reverts commit 6f94de3ca4

(Doesn't try to increase the number of TLS slots; that leads to
an inability to boot. Adds more tests.)

Change-Id: Ia7d25ba3995219ed6e686463dbba80c95cc831ca
2013-02-12 15:27:18 -08:00
Elliott Hughes
6f94de3ca4 Revert "More pthreads cleanup."
This reverts commit 2a1bb4e646

Change-Id: Ia443d0748015c8e9fc3121e40e68258616767b51
2013-02-12 06:06:22 +00:00
Elliott Hughes
2a1bb4e646 More pthreads cleanup.
POSIX says pthread_create returns EAGAIN, not ENOMEM.

Also pull pthread_attr_t functions into their own file.

Also pull pthread_setname_np into its own file.

Also remove unnecessary #includes from pthread_key.cpp.

Also account for those pthread keys used internally by bionic,
so they don't count against the number of keys available to user
code. (They do with glibc, but glibc's limit is the much more
generous 1024.)

Also factor out the common errno-restoring idiom to reduce gotos.

Bug: 6702535
Change-Id: I555e66efffcf2c1b5a2873569e91489156efca42
2013-02-11 14:56:39 -08:00