diff options
| author | 2017-06-01 14:01:43 -0700 | |
|---|---|---|
| committer | 2017-06-02 11:30:01 -0700 | |
| commit | 07f0621463e7b480c86ddba3e72d3fb9f0ae820f (patch) | |
| tree | 130691a38d30d788306ca546f3e7b4d17c808a53 /runtime/class_linker.cc | |
| parent | 596c58b3dc73a4017d49af6c5037bbd7109fd31e (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.cc | 33 |
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(); |