| From b3343e687842ad54ca1621f6dcb1d99e6826d65d Mon Sep 17 00:00:00 2001 |
| From: Ethan Chen <intervigil@gmail.com> |
| Date: Tue, 25 Sep 2018 00:11:05 -0700 |
| Subject: [PATCH 1/2] Actually restore pre-P mutex behavior |
| |
| Apps built against versions < P may not actually expect the EBUSY return |
| code, and may crash or otherwise misbehave. Check for target SDK |
| versions earlier than P when performing the IsMutexDestroyed check so |
| any invocation of HandleUsingDestroyedMutex is bypassed and pre-P mutex |
| behavior is restored. |
| |
| See 9e989f12d1186231d97dac6d038db7955acebdf3 for the change that |
| introduced this new behavior. |
| |
| Change-Id: I45f8882c9527c63eed1ef5820a5004b8958d58ea |
| --- |
| libc/bionic/pthread_mutex.cpp | 19 ++++++++++++------- |
| 1 file changed, 12 insertions(+), 7 deletions(-) |
| |
| diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp |
| index bc7bd653f..517e52688 100644 |
| --- a/libc/bionic/pthread_mutex.cpp |
| +++ b/libc/bionic/pthread_mutex.cpp |
| @@ -782,17 +782,22 @@ static int MutexLockWithTimeout(pthread_mutex_internal_t* mutex, bool use_realti |
| |
| } // namespace NonPI |
| |
| -static inline __always_inline bool IsMutexDestroyed(uint16_t mutex_state) { |
| - return mutex_state == 0xffff; |
| -} |
| - |
| // Inlining this function in pthread_mutex_lock() adds the cost of stack frame instructions on |
| // ARM64. So make it noinline. |
| -static int __attribute__((noinline)) HandleUsingDestroyedMutex(pthread_mutex_t* mutex, |
| - const char* function_name) { |
| +static inline __attribute__((noinline)) bool IsMutexDestroyed(uint16_t mutex_state) { |
| + // Checking for mutex destruction is a P-specific behavior. Bypass the |
| + // check if the SDK version precedes P, so that no change in behavior |
| + // that may cause crashes is introduced. |
| if (bionic_get_application_target_sdk_version() >= __ANDROID_API_P__) { |
| - __fortify_fatal("%s called on a destroyed mutex (%p)", function_name, mutex); |
| + return mutex_state == 0xffff; |
| + } else { |
| + return false; |
| } |
| +} |
| + |
| +static int __always_inline HandleUsingDestroyedMutex(pthread_mutex_t* mutex, |
| + const char* function_name) { |
| + __fortify_fatal("%s called on a destroyed mutex (%p)", function_name, mutex); |
| return EBUSY; |
| } |
| |
| -- |
| 2.21.0 |
| |