diff options
author | Olaf Titz <olaf@bigred.inka.de> | 2017-11-27 22:15:29 +0100 |
---|---|---|
committer | Olaf Titz <olaf@bigred.inka.de> | 2017-11-27 22:15:29 +0100 |
commit | 4541eceec70adaa58823ad58ed370b5a19777a95 (patch) | |
tree | 2cc94324cebeb1e8041a87212ab5d5af15878f02 | |
parent | 68f04c49c17820aefc5e41ee4fd6aee5e82b6d26 (diff) | |
download | frameworks_base-4541eceec70adaa58823ad58ed370b5a19777a95.tar.gz frameworks_base-4541eceec70adaa58823ad58ed370b5a19777a95.tar.bz2 frameworks_base-4541eceec70adaa58823ad58ed370b5a19777a95.zip |
AssetManager: fix use-after-free of asset
AssetManager::getPkgName(const char *apkgPath) creates a ResXMLTree on
stack, opens an asset and assigns the asset's buffer to the
ResXMLTree, then closes the asset before the ResXMLTree gets
autodestroyed. For apps built with new tooling, this now causes app or
system crashes.
Bug report: https://jira.lineageos.org/browse/BUGBASH-1052
Detailed description of cause: https://issuetracker.google.com/issues/64434571#comment22
The patch ensures that the ResXMLTree object is destroyed prior to the
Asset being closed.
Change-Id: I041b002745ad2dc0deb09ee9cbd00e40c0202ac6
Signed-off-by: Olaf Titz <olaf81825@googlemail.com>
-rw-r--r-- | libs/androidfw/AssetManager.cpp | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index e6e45633dc4..ffe72f3c012 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -417,26 +417,26 @@ String8 AssetManager::getPkgName(const char *apkPath) { ap.type = kFileTypeRegular; ap.path = String8(apkPath); - ResXMLTree tree; - Asset* manifestAsset = openNonAssetInPathLocked(kAndroidManifest, Asset::ACCESS_BUFFER, ap); - tree.setTo(manifestAsset->getBuffer(true), - manifestAsset->getLength()); - tree.restart(); - - size_t len; - ResXMLTree::event_code_t code; - while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { - if (code != ResXMLTree::START_TAG) { - continue; - } - String8 tag(tree.getElementName(&len)); - if (tag != "manifest") break; //Manifest does not start with <manifest> - size_t len; - ssize_t idx = tree.indexOfAttribute(NULL, "package"); - const char16_t* str = tree.getAttributeStringValue(idx, &len); - pkgName = (str ? String8(str, len) : String8()); + { + ResXMLTree tree; + tree.setTo(manifestAsset->getBuffer(true), + manifestAsset->getLength()); + tree.restart(); + size_t len; + ResXMLTree::event_code_t code; + while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { + if (code != ResXMLTree::START_TAG) { + continue; + } + String8 tag(tree.getElementName(&len)); + if (tag != "manifest") break; //Manifest does not start with <manifest> + size_t len; + ssize_t idx = tree.indexOfAttribute(NULL, "package"); + const char16_t* str = tree.getAttributeStringValue(idx, &len); + pkgName = (str ? String8(str, len) : String8()); + } } manifestAsset->close(); |