Loading core/jni/android_content_res_ApkAssets.cpp +73 −48 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #define ATRACE_TAG ATRACE_TAG_RESOURCES #include <mutex> #include "signal.h" #include "android-base/logging.h" Loading @@ -26,6 +28,7 @@ #include "utils/misc.h" #include "utils/Trace.h" #include "android_content_res_ApkAssets.h" #include "android_util_AssetManager_private.h" #include "core_jni_helpers.h" #include "jni.h" Loading Loading @@ -72,6 +75,19 @@ enum : format_type_t { FORMAT_DIRECTORY = 3, }; Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr) { return *reinterpret_cast<Guarded<std::unique_ptr<const ApkAssets>>*>(ptr); } static jlong CreateGuardedApkAssets(std::unique_ptr<const ApkAssets> assets) { auto guarded_assets = new Guarded<std::unique_ptr<const ApkAssets>>(std::move(assets)); return reinterpret_cast<jlong>(guarded_assets); } static void DeleteGuardedApkAssets(Guarded<std::unique_ptr<const ApkAssets>>& apk_assets) { delete &apk_assets; } class LoaderAssetsProvider : public AssetsProvider { public: static std::unique_ptr<AssetsProvider> Create(JNIEnv* env, jobject assets_provider) { Loading Loading @@ -227,7 +243,7 @@ static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t forma jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t format, Loading Loading @@ -279,7 +295,7 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_type_t format, Loading Loading @@ -347,12 +363,12 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_ jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadEmpty(JNIEnv* env, jclass /*clazz*/, jint flags, jobject assets_provider) { auto apk_assets = ApkAssets::Load(LoaderAssetsProvider::Create(env, assets_provider), flags); return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } // STOPSHIP (b/159041693): Revert signal handler when reason for issue is found. Loading Loading @@ -383,7 +399,9 @@ static void DestroyErrorHandler(int sig, siginfo_t* info, void* ucontext) { } static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); { auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); destroy_info << "{ptr=" << apk_assets; if (apk_assets != nullptr) { destroy_info << ", name='" << apk_assets->GetDebugName() << "'" Loading @@ -391,19 +409,19 @@ static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { << ", {arsc=" << apk_assets->GetLoadedArsc(); if (auto arsc = apk_assets->GetLoadedArsc()) { destroy_info << ", strings=" << arsc->GetStringPool() << ", packages=" << &arsc->GetPackages() << " ["; << ", packages=" << &arsc->GetPackages() << " ["; for (auto& package : arsc->GetPackages()) { destroy_info << "{unique_ptr=" << &package << ", package=" << package.get() << "},"; destroy_info << "{unique_ptr=" << &package << ", package=" << package.get() << "},"; } destroy_info << "]"; } destroy_info << "}"; } destroy_info << "}"; } delete apk_assets; DeleteGuardedApkAssets(ApkAssetsFromLong(ptr)); // Deleting the apk assets did not lead to a crash. destroy_info.str(""); Loading @@ -411,7 +429,8 @@ static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { } static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); if (auto path = apk_assets->GetPath()) { return env->NewStringUTF(path->data()); } Loading @@ -419,17 +438,20 @@ static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) { } static jstring NativeGetDebugName(JNIEnv* env, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return env->NewStringUTF(apk_assets->GetDebugName().c_str()); } static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return reinterpret_cast<jlong>(apk_assets->GetLoadedArsc()->GetStringPool()); } static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE; } Loading @@ -439,7 +461,8 @@ static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring fil return 0; } const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); std::unique_ptr<Asset> asset = apk_assets->GetAssetsProvider()->Open( path_utf8.c_str(),Asset::AccessMode::ACCESS_RANDOM); if (asset == nullptr) { Loading Loading @@ -467,7 +490,8 @@ static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring fil static jobject NativeGetOverlayableInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring overlayable_name) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); const auto& packages = apk_assets->GetLoadedArsc()->GetPackages(); if (packages.empty()) { Loading Loading @@ -502,7 +526,8 @@ static jobject NativeGetOverlayableInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr } static jboolean NativeDefinesOverlayable(JNIEnv* env, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); const auto& packages = apk_assets->GetLoadedArsc()->GetPackages(); if (packages.empty()) { Loading core/jni/android_content_res_ApkAssets.h 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_CONTENT_RES_APKASSETS_H #define ANDROID_CONTENT_RES_APKASSETS_H #include "androidfw/ApkAssets.h" #include "androidfw/MutexGuard.h" #include "jni.h" namespace android { Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr); } // namespace android #endif // ANDROID_CONTENT_RES_APKASSETS_H core/jni/android_util_AssetManager.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/ResourceUtils.h" #include "android_content_res_ApkAssets.h" #include "android_util_AssetManager_private.h" #include "core_jni_helpers.h" #include "jni.h" Loading @@ -50,9 +51,9 @@ #include "nativehelper/ScopedStringChars.h" #include "nativehelper/ScopedUtfChars.h" #include "utils/Log.h" #include "utils/misc.h" #include "utils/String8.h" #include "utils/Trace.h" #include "utils/misc.h" extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap); extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap); Loading Loading @@ -307,7 +308,9 @@ static void NativeSetApkAssets(JNIEnv* env, jclass /*clazz*/, jlong ptr, if (env->ExceptionCheck()) { return; } apk_assets.push_back(reinterpret_cast<const ApkAssets*>(apk_assets_native_ptr)); auto scoped_assets = ScopedLock(ApkAssetsFromLong(apk_assets_native_ptr)); apk_assets.push_back(scoped_assets->get()); } ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr)); Loading libs/androidfw/LoadedArsc.cpp +0 −3 Original line number Diff line number Diff line Loading @@ -70,9 +70,6 @@ struct TypeSpecBuilder { } // namespace LoadedPackage::LoadedPackage() = default; LoadedPackage::~LoadedPackage() = default; // Precondition: The header passed in has already been verified, so reading any fields and trusting // the ResChunk_header is safe. static bool VerifyResTableType(incfs::map_ptr<ResTable_type> header) { Loading libs/androidfw/include/androidfw/AssetManager2.h +1 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ class AssetManager2 { }; AssetManager2(); explicit AssetManager2(AssetManager2&& other) = default; // Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets // are not owned by the AssetManager, and must have a longer lifetime. Loading Loading
core/jni/android_content_res_ApkAssets.cpp +73 −48 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #define ATRACE_TAG ATRACE_TAG_RESOURCES #include <mutex> #include "signal.h" #include "android-base/logging.h" Loading @@ -26,6 +28,7 @@ #include "utils/misc.h" #include "utils/Trace.h" #include "android_content_res_ApkAssets.h" #include "android_util_AssetManager_private.h" #include "core_jni_helpers.h" #include "jni.h" Loading Loading @@ -72,6 +75,19 @@ enum : format_type_t { FORMAT_DIRECTORY = 3, }; Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr) { return *reinterpret_cast<Guarded<std::unique_ptr<const ApkAssets>>*>(ptr); } static jlong CreateGuardedApkAssets(std::unique_ptr<const ApkAssets> assets) { auto guarded_assets = new Guarded<std::unique_ptr<const ApkAssets>>(std::move(assets)); return reinterpret_cast<jlong>(guarded_assets); } static void DeleteGuardedApkAssets(Guarded<std::unique_ptr<const ApkAssets>>& apk_assets) { delete &apk_assets; } class LoaderAssetsProvider : public AssetsProvider { public: static std::unique_ptr<AssetsProvider> Create(JNIEnv* env, jobject assets_provider) { Loading Loading @@ -227,7 +243,7 @@ static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t forma jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t format, Loading Loading @@ -279,7 +295,7 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_type_t format, Loading Loading @@ -347,12 +363,12 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_ jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } static jlong NativeLoadEmpty(JNIEnv* env, jclass /*clazz*/, jint flags, jobject assets_provider) { auto apk_assets = ApkAssets::Load(LoaderAssetsProvider::Create(env, assets_provider), flags); return reinterpret_cast<jlong>(apk_assets.release()); return CreateGuardedApkAssets(std::move(apk_assets)); } // STOPSHIP (b/159041693): Revert signal handler when reason for issue is found. Loading Loading @@ -383,7 +399,9 @@ static void DestroyErrorHandler(int sig, siginfo_t* info, void* ucontext) { } static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); { auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); destroy_info << "{ptr=" << apk_assets; if (apk_assets != nullptr) { destroy_info << ", name='" << apk_assets->GetDebugName() << "'" Loading @@ -391,19 +409,19 @@ static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { << ", {arsc=" << apk_assets->GetLoadedArsc(); if (auto arsc = apk_assets->GetLoadedArsc()) { destroy_info << ", strings=" << arsc->GetStringPool() << ", packages=" << &arsc->GetPackages() << " ["; << ", packages=" << &arsc->GetPackages() << " ["; for (auto& package : arsc->GetPackages()) { destroy_info << "{unique_ptr=" << &package << ", package=" << package.get() << "},"; destroy_info << "{unique_ptr=" << &package << ", package=" << package.get() << "},"; } destroy_info << "]"; } destroy_info << "}"; } destroy_info << "}"; } delete apk_assets; DeleteGuardedApkAssets(ApkAssetsFromLong(ptr)); // Deleting the apk assets did not lead to a crash. destroy_info.str(""); Loading @@ -411,7 +429,8 @@ static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { } static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); if (auto path = apk_assets->GetPath()) { return env->NewStringUTF(path->data()); } Loading @@ -419,17 +438,20 @@ static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) { } static jstring NativeGetDebugName(JNIEnv* env, jclass /*clazz*/, jlong ptr) { auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return env->NewStringUTF(apk_assets->GetDebugName().c_str()); } static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return reinterpret_cast<jlong>(apk_assets->GetLoadedArsc()->GetStringPool()); } static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE; } Loading @@ -439,7 +461,8 @@ static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring fil return 0; } const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); std::unique_ptr<Asset> asset = apk_assets->GetAssetsProvider()->Open( path_utf8.c_str(),Asset::AccessMode::ACCESS_RANDOM); if (asset == nullptr) { Loading Loading @@ -467,7 +490,8 @@ static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring fil static jobject NativeGetOverlayableInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring overlayable_name) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); const auto& packages = apk_assets->GetLoadedArsc()->GetPackages(); if (packages.empty()) { Loading Loading @@ -502,7 +526,8 @@ static jobject NativeGetOverlayableInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr } static jboolean NativeDefinesOverlayable(JNIEnv* env, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr)); auto apk_assets = scoped_apk_assets->get(); const auto& packages = apk_assets->GetLoadedArsc()->GetPackages(); if (packages.empty()) { Loading
core/jni/android_content_res_ApkAssets.h 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_CONTENT_RES_APKASSETS_H #define ANDROID_CONTENT_RES_APKASSETS_H #include "androidfw/ApkAssets.h" #include "androidfw/MutexGuard.h" #include "jni.h" namespace android { Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr); } // namespace android #endif // ANDROID_CONTENT_RES_APKASSETS_H
core/jni/android_util_AssetManager.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "androidfw/ResourceTypes.h" #include "androidfw/ResourceUtils.h" #include "android_content_res_ApkAssets.h" #include "android_util_AssetManager_private.h" #include "core_jni_helpers.h" #include "jni.h" Loading @@ -50,9 +51,9 @@ #include "nativehelper/ScopedStringChars.h" #include "nativehelper/ScopedUtfChars.h" #include "utils/Log.h" #include "utils/misc.h" #include "utils/String8.h" #include "utils/Trace.h" #include "utils/misc.h" extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap); extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap); Loading Loading @@ -307,7 +308,9 @@ static void NativeSetApkAssets(JNIEnv* env, jclass /*clazz*/, jlong ptr, if (env->ExceptionCheck()) { return; } apk_assets.push_back(reinterpret_cast<const ApkAssets*>(apk_assets_native_ptr)); auto scoped_assets = ScopedLock(ApkAssetsFromLong(apk_assets_native_ptr)); apk_assets.push_back(scoped_assets->get()); } ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr)); Loading
libs/androidfw/LoadedArsc.cpp +0 −3 Original line number Diff line number Diff line Loading @@ -70,9 +70,6 @@ struct TypeSpecBuilder { } // namespace LoadedPackage::LoadedPackage() = default; LoadedPackage::~LoadedPackage() = default; // Precondition: The header passed in has already been verified, so reading any fields and trusting // the ResChunk_header is safe. static bool VerifyResTableType(incfs::map_ptr<ResTable_type> header) { Loading
libs/androidfw/include/androidfw/AssetManager2.h +1 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ class AssetManager2 { }; AssetManager2(); explicit AssetManager2(AssetManager2&& other) = default; // Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets // are not owned by the AssetManager, and must have a longer lifetime. Loading