summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2023-12-28 22:46:28 +0000
committer Steven Moreland <smoreland@google.com> 2023-12-28 22:46:28 +0000
commit95ac79e9bbf1b330735a35a8d034230195215fe6 (patch)
tree269050fb134414ddab476801eb1b1f4e4e7216a9
parent22ac12b228bfda8b55aaee05381c36acad7a296b (diff)
libfakeservicemanager: no hold lock in clear
destructors may reference servicemanager, and so if objects are destroyed by libfakeservicemanager clear, this was causing a recursive lock take. Fix this the standard way, by using the lock to copy out references, and then clear them when its okay to talk to servicemanager again. Bug: N/A Test: w/ fuzzers Change-Id: I4795ff6e042324e6ffe76f6c915c1328d3eee94f
-rw-r--r--libs/fakeservicemanager/FakeServiceManager.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/libs/fakeservicemanager/FakeServiceManager.cpp b/libs/fakeservicemanager/FakeServiceManager.cpp
index ae242f32a3..08f30de637 100644
--- a/libs/fakeservicemanager/FakeServiceManager.cpp
+++ b/libs/fakeservicemanager/FakeServiceManager.cpp
@@ -122,9 +122,19 @@ std::vector<IServiceManager::ServiceDebugInfo> FakeServiceManager::getServiceDeb
}
void FakeServiceManager::clear() {
- std::lock_guard<std::mutex> l(mMutex);
+ std::map<String16, sp<IBinder>> backup;
+
+ {
+ std::lock_guard<std::mutex> l(mMutex);
+ backup = mNameToService;
+ mNameToService.clear();
+ }
+
+ // destructors may access FSM, so avoid recursive lock
+ backup.clear(); // explicit
- mNameToService.clear();
+ // TODO: destructors may have added more services here - may want
+ // to check this or abort
}
} // namespace android
@@ -147,4 +157,4 @@ void clearFakeServiceManager() {
LOG_ALWAYS_FATAL_IF(gFakeServiceManager == nullptr, "Fake Service Manager is not available. Forgot to call setupFakeServiceManager?");
gFakeServiceManager->clear();
}
-} //extern "C" \ No newline at end of file
+} //extern "C"