summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2017-06-01 14:01:43 -0700
committer Alex Light <allight@google.com> 2017-06-02 11:30:01 -0700
commit07f0621463e7b480c86ddba3e72d3fb9f0ae820f (patch)
tree130691a38d30d788306ca546f3e7b4d17c808a53 /runtime/class_linker.cc
parent596c58b3dc73a4017d49af6c5037bbd7109fd31e (diff)
Fix redefinition related use-after-free bug
A redefinition that failed with JVMTI_ERROR_FAILS_VERIFICATION could cause a use-after-free of java DexCache objects if a art::DexFile* that aliases the one created for the failed redefinition is created. Bug: 62237378 Test: ./test.py --host -j40 Change-Id: Ia080dfa6c702b2e3a735c4c3cd80ca3974386934
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc33
1 files changed, 33 insertions, 0 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c169ac0733..c6d60d15d4 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3535,6 +3535,39 @@ ObjPtr<mirror::DexCache> ClassLinker::EnsureSameClassLoader(
return dex_cache;
}
+void ClassLinker::RegisterExistingDexCache(ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader) {
+ Thread* self = Thread::Current();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(dex_cache));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
+ const DexFile* dex_file = dex_cache->GetDexFile();
+ DCHECK(dex_file != nullptr) << "Attempt to register uninitialized dex_cache object!";
+ if (kIsDebugBuild) {
+ DexCacheData old_data;
+ {
+ ReaderMutexLock mu(self, *Locks::dex_lock_);
+ old_data = FindDexCacheDataLocked(*dex_file);
+ }
+ ObjPtr<mirror::DexCache> old_dex_cache = DecodeDexCache(self, old_data);
+ DCHECK(old_dex_cache.IsNull()) << "Attempt to manually register a dex cache thats already "
+ << "been registered on dex file " << dex_file->GetLocation();
+ }
+ ClassTable* table;
+ {
+ WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+ table = InsertClassTableForClassLoader(h_class_loader.Get());
+ }
+ WriterMutexLock mu(self, *Locks::dex_lock_);
+ RegisterDexFileLocked(*dex_file, h_dex_cache.Get(), h_class_loader.Get());
+ table->InsertStrongRoot(h_dex_cache.Get());
+ if (h_class_loader.Get() != nullptr) {
+ // Since we added a strong root to the class table, do the write barrier as required for
+ // remembered sets and generational GCs.
+ Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(h_class_loader.Get());
+ }
+}
+
ObjPtr<mirror::DexCache> ClassLinker::RegisterDexFile(const DexFile& dex_file,
ObjPtr<mirror::ClassLoader> class_loader) {
Thread* self = Thread::Current();