Fix potential double destroy of AssetManager

Assume there is a XmlBlock [X] created by a AssetManager [A]
([A] will have mNumRefs = 2). After [A].close is called
(mNumRefs = 1) and then both [X] and [A] are going to be GCed,
if [A].finalize is called first (nativeDestroy), the later
[X].finalize will invoke [A].xmlBlockGone that triggers the
second nativeDestroy of [A] and leads to crash.

By clearing the mObject in AssetManager.finalize, the
decRefsLocked from other paths won't call nativeDestroy again.

Bug: 144028297
Test: atest android.security.cts.AssetManagerTest

Change-Id: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1
Merged-In: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1
This commit is contained in:
Ryan Mitchell
2020-01-15 11:43:47 -08:00
parent 5e0b069876
commit 93320661ca

View File

@@ -588,7 +588,13 @@ public final class AssetManager implements AutoCloseable {
} }
} }
} }
destroy();
synchronized (this) {
if (mObject != 0) {
destroy();
mObject = 0;
}
}
} finally { } finally {
super.finalize(); super.finalize();
} }
@@ -907,8 +913,9 @@ public final class AssetManager implements AutoCloseable {
mNumRefs--; mNumRefs--;
//System.out.println("Dec streams: mNumRefs=" + mNumRefs //System.out.println("Dec streams: mNumRefs=" + mNumRefs
// + " mReleased=" + mReleased); // + " mReleased=" + mReleased);
if (mNumRefs == 0) { if (mNumRefs == 0 && mObject != 0) {
destroy(); destroy();
mObject = 0;
} }
} }
} }