resourcemanagerservice: make a copy of client config
The cases when the codec is release without stopping, the
resource manager calls notifyClientStopped from notifyClientReleased.
But while doing so, it passes a reference from mClientConfigMap map’s
entry.
This could potentially cause use-after-free situation as
notifyClientStopped removes the entry from the map and uses it
later.
To fix this, make a copy of ClientConfigParcel from the mClientConfigMap
map’s entry. Also, update the timestamp of codec::stop
Bug: 274883119
Test: atest cts/tests/media/misc/src/android/media/misc/cts/ResourceManagerTest.java
/data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
/data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Merged-In: I00cb69a276b80e8ef7a196f62d9816541878b222
Change-Id: I00cb69a276b80e8ef7a196f62d9816541878b222
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index b60e734..8d591df 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -146,18 +146,21 @@
void ResourceManagerMetrics::notifyClientReleased(const ClientInfoParcel& clientInfo) {
bool stopCalled = true;
- ClientConfigMap::iterator found;
+ ClientConfigParcel clientConfig;
{
std::scoped_lock lock(mLock);
- found = mClientConfigMap.find(clientInfo.id);
+ ClientConfigMap::iterator found = mClientConfigMap.find(clientInfo.id);
if (found != mClientConfigMap.end()) {
// Release is called without Stop!
stopCalled = false;
+ clientConfig = found->second;
+ // Update the timestamp for stopping the codec.
+ clientConfig.timeStamp = systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL;
}
}
if (!stopCalled) {
// call Stop to update the metrics.
- notifyClientStopped(found->second);
+ notifyClientStopped(clientConfig);
}
{
std::scoped_lock lock(mLock);