Fix thread race caused double free issue.
The SharedZip's Asset is not thread-safety,the getResourceTableAsset() and setResourceTableAsset(Asset* asset) function of the SharedZip is not sync with a same lock. Consider the following sequence of events: Thread A calls setResourceTableAsset(Asset* asset),it will set mResourceTableAsset = asset; then to calls getBuffer() of the asset. Thread B calls getResourceTableAsset(),which return mResourceTableAsset, then to calls getBuffer() of the mResourceTableAsset,the asset and mResourceTableAsset is same one object. Thread A to delete mZipInflater in getBuffer(). Thread B to delete mZipInflater in getBuffer(). It will cause crash becuase double delete mZipInflater in getBuffer(). https://code.google.com/p/android/issues/detail?id=211941 Bug:31734545 Change-Id: I5a7d67fdf64c4aa03f505b37a2fa840f4443d158 Signed-off-by: songjinshi <songjinshi@xiaomi.com>
This commit is contained in:
committed by
Adam Lesinski
parent
bf79852ae4
commit
5754b41c20
@ -1892,6 +1892,7 @@ ZipFileRO* AssetManager::SharedZip::getZip()
|
|||||||
|
|
||||||
Asset* AssetManager::SharedZip::getResourceTableAsset()
|
Asset* AssetManager::SharedZip::getResourceTableAsset()
|
||||||
{
|
{
|
||||||
|
AutoMutex _l(gLock);
|
||||||
ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
|
ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
|
||||||
return mResourceTableAsset;
|
return mResourceTableAsset;
|
||||||
}
|
}
|
||||||
@ -1901,10 +1902,10 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
|
|||||||
{
|
{
|
||||||
AutoMutex _l(gLock);
|
AutoMutex _l(gLock);
|
||||||
if (mResourceTableAsset == NULL) {
|
if (mResourceTableAsset == NULL) {
|
||||||
mResourceTableAsset = asset;
|
|
||||||
// This is not thread safe the first time it is called, so
|
// This is not thread safe the first time it is called, so
|
||||||
// do it here with the global lock held.
|
// do it here with the global lock held.
|
||||||
asset->getBuffer(true);
|
asset->getBuffer(true);
|
||||||
|
mResourceTableAsset = asset;
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user