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:
songjinshi
2016-09-08 15:24:30 +08:00
committed by Adam Lesinski
parent bf79852ae4
commit 5754b41c20

View File

@ -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;
} }
} }