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
diff --git a/libs/fakeservicemanager/FakeServiceManager.cpp b/libs/fakeservicemanager/FakeServiceManager.cpp
index ae242f3..08f30de 100644
--- a/libs/fakeservicemanager/FakeServiceManager.cpp
+++ b/libs/fakeservicemanager/FakeServiceManager.cpp
@@ -122,9 +122,19 @@
}
void FakeServiceManager::clear() {
- std::lock_guard<std::mutex> l(mMutex);
+ std::map<String16, sp<IBinder>> backup;
- mNameToService.clear();
+ {
+ std::lock_guard<std::mutex> l(mMutex);
+ backup = mNameToService;
+ mNameToService.clear();
+ }
+
+ // destructors may access FSM, so avoid recursive lock
+ backup.clear(); // explicit
+
+ // TODO: destructors may have added more services here - may want
+ // to check this or abort
}
} // namespace android
@@ -147,4 +157,4 @@
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"