• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "oat_file_manager.h"
18 
19 #include <memory>
20 #include <queue>
21 #include <vector>
22 #include <sys/stat.h>
23 
24 #include "android-base/file.h"
25 #include "android-base/stringprintf.h"
26 #include "android-base/strings.h"
27 
28 #include "art_field-inl.h"
29 #include "base/bit_vector-inl.h"
30 #include "base/file_utils.h"
31 #include "base/logging.h"  // For VLOG.
32 #include "base/mutex-inl.h"
33 #include "base/sdk_version.h"
34 #include "base/stl_util.h"
35 #include "base/systrace.h"
36 #include "class_linker.h"
37 #include "class_loader_context.h"
38 #include "dex/art_dex_file_loader.h"
39 #include "dex/dex_file-inl.h"
40 #include "dex/dex_file_loader.h"
41 #include "dex/dex_file_tracking_registrar.h"
42 #include "gc/scoped_gc_critical_section.h"
43 #include "gc/space/image_space.h"
44 #include "handle_scope-inl.h"
45 #include "jit/jit.h"
46 #include "jni/java_vm_ext.h"
47 #include "jni/jni_internal.h"
48 #include "mirror/class_loader.h"
49 #include "mirror/object-inl.h"
50 #include "oat_file.h"
51 #include "oat_file_assistant.h"
52 #include "obj_ptr-inl.h"
53 #include "scoped_thread_state_change-inl.h"
54 #include "thread-current-inl.h"
55 #include "thread_list.h"
56 #include "thread_pool.h"
57 #include "vdex_file.h"
58 #include "verifier/verifier_deps.h"
59 #include "well_known_classes.h"
60 
61 namespace art {
62 
63 using android::base::StringPrintf;
64 
65 // If true, we attempt to load the application image if it exists.
66 static constexpr bool kEnableAppImage = true;
67 
RegisterOatFile(std::unique_ptr<const OatFile> oat_file,bool in_memory)68 const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file,
69                                                bool in_memory) {
70   // Use class_linker vlog to match the log for dex file registration.
71   VLOG(class_linker) << "Registered oat file " << oat_file->GetLocation();
72   PaletteNotifyOatFileLoaded(oat_file->GetLocation().c_str());
73 
74   WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
75   CHECK(in_memory ||
76         !only_use_system_oat_files_ ||
77         LocationIsTrusted(oat_file->GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) ||
78         !oat_file->IsExecutable())
79       << "Registering a non /system oat file: " << oat_file->GetLocation() << " android-root="
80       << GetAndroidRoot();
81   DCHECK(oat_file != nullptr);
82   if (kIsDebugBuild) {
83     CHECK(oat_files_.find(oat_file) == oat_files_.end());
84     for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
85       CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
86       // Check that we don't have an oat file with the same address. Copies of the same oat file
87       // should be loaded at different addresses.
88       CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location";
89     }
90   }
91   const OatFile* ret = oat_file.get();
92   oat_files_.insert(std::move(oat_file));
93   return ret;
94 }
95 
UnRegisterAndDeleteOatFile(const OatFile * oat_file)96 void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
97   WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
98   DCHECK(oat_file != nullptr);
99   std::unique_ptr<const OatFile> compare(oat_file);
100   auto it = oat_files_.find(compare);
101   CHECK(it != oat_files_.end());
102   oat_files_.erase(it);
103   compare.release();  // NOLINT b/117926937
104 }
105 
FindOpenedOatFileFromDexLocation(const std::string & dex_base_location) const106 const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation(
107     const std::string& dex_base_location) const {
108   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
109   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
110     const std::vector<const OatDexFile*>& oat_dex_files = oat_file->GetOatDexFiles();
111     for (const OatDexFile* oat_dex_file : oat_dex_files) {
112       if (DexFileLoader::GetBaseLocation(oat_dex_file->GetDexFileLocation()) == dex_base_location) {
113         return oat_file.get();
114       }
115     }
116   }
117   return nullptr;
118 }
119 
FindOpenedOatFileFromOatLocation(const std::string & oat_location) const120 const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
121     const {
122   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
123   return FindOpenedOatFileFromOatLocationLocked(oat_location);
124 }
125 
FindOpenedOatFileFromOatLocationLocked(const std::string & oat_location) const126 const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked(
127     const std::string& oat_location) const {
128   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
129     if (oat_file->GetLocation() == oat_location) {
130       return oat_file.get();
131     }
132   }
133   return nullptr;
134 }
135 
GetBootOatFiles() const136 std::vector<const OatFile*> OatFileManager::GetBootOatFiles() const {
137   std::vector<gc::space::ImageSpace*> image_spaces =
138       Runtime::Current()->GetHeap()->GetBootImageSpaces();
139   std::vector<const OatFile*> oat_files;
140   oat_files.reserve(image_spaces.size());
141   for (gc::space::ImageSpace* image_space : image_spaces) {
142     oat_files.push_back(image_space->GetOatFile());
143   }
144   return oat_files;
145 }
146 
OatFileManager()147 OatFileManager::OatFileManager()
148     : only_use_system_oat_files_(false) {}
149 
~OatFileManager()150 OatFileManager::~OatFileManager() {
151   // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
152   // UnRegisterOatFileLocation.
153   oat_files_.clear();
154 }
155 
RegisterImageOatFiles(const std::vector<gc::space::ImageSpace * > & spaces)156 std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles(
157     const std::vector<gc::space::ImageSpace*>& spaces) {
158   std::vector<const OatFile*> oat_files;
159   oat_files.reserve(spaces.size());
160   for (gc::space::ImageSpace* space : spaces) {
161     // The oat file was generated in memory if the image space has a profile.
162     bool in_memory = !space->GetProfileFiles().empty();
163     oat_files.push_back(RegisterOatFile(space->ReleaseOatFile(), in_memory));
164   }
165   return oat_files;
166 }
167 
ShouldLoadAppImage(const OatFile * source_oat_file) const168 bool OatFileManager::ShouldLoadAppImage(const OatFile* source_oat_file) const {
169   Runtime* const runtime = Runtime::Current();
170   return kEnableAppImage && (!runtime->IsJavaDebuggable() || source_oat_file->IsDebuggable());
171 }
172 
OpenDexFilesFromOat(const char * dex_location,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)173 std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
174     const char* dex_location,
175     jobject class_loader,
176     jobjectArray dex_elements,
177     const OatFile** out_oat_file,
178     std::vector<std::string>* error_msgs) {
179   ScopedTrace trace(StringPrintf("%s(%s)", __FUNCTION__, dex_location));
180   CHECK(dex_location != nullptr);
181   CHECK(error_msgs != nullptr);
182 
183   // Verify we aren't holding the mutator lock, which could starve GC when
184   // hitting the disk.
185   Thread* const self = Thread::Current();
186   Locks::mutator_lock_->AssertNotHeld(self);
187   Runtime* const runtime = Runtime::Current();
188 
189   std::vector<std::unique_ptr<const DexFile>> dex_files;
190   std::unique_ptr<ClassLoaderContext> context(
191       ClassLoaderContext::CreateContextForClassLoader(class_loader, dex_elements));
192 
193   // If the class_loader is null there's not much we can do. This happens if a dex files is loaded
194   // directly with DexFile APIs instead of using class loaders.
195   if (class_loader == nullptr) {
196     LOG(WARNING) << "Opening an oat file without a class loader. "
197                  << "Are you using the deprecated DexFile APIs?";
198   } else if (context != nullptr) {
199     OatFileAssistant oat_file_assistant(dex_location,
200                                         kRuntimeISA,
201                                         context.get(),
202                                         runtime->GetOatFilesExecutable(),
203                                         only_use_system_oat_files_);
204 
205     // Get the current optimization status for trace debugging.
206     // Implementation detail note: GetOptimizationStatus will select the same
207     // oat file as GetBestOatFile used below, and in doing so it already pre-populates
208     // some OatFileAssistant internal fields.
209     std::string odex_location;
210     std::string compilation_filter;
211     std::string compilation_reason;
212     std::string odex_status;
213     oat_file_assistant.GetOptimizationStatus(
214         &odex_location,
215         &compilation_filter,
216         &compilation_reason,
217         &odex_status);
218 
219     Runtime::Current()->GetAppInfo()->RegisterOdexStatus(
220         dex_location,
221         compilation_filter,
222         compilation_reason,
223         odex_status);
224 
225     ScopedTrace odex_loading(StringPrintf(
226         "location=%s status=%s filter=%s reason=%s",
227         odex_location.c_str(),
228         odex_status.c_str(),
229         compilation_filter.c_str(),
230         compilation_reason.c_str()));
231 
232     // Proceed with oat file loading.
233     std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release());
234     VLOG(oat) << "OatFileAssistant(" << dex_location << ").GetBestOatFile()="
235               << (oat_file != nullptr ? oat_file->GetLocation() : "")
236               << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")";
237 
238     CHECK(oat_file == nullptr || odex_location == oat_file->GetLocation())
239         << "OatFileAssistant non-determinism in choosing best oat files. "
240         << "optimization-status-location=" << odex_location
241         << " best_oat_file-location=" << oat_file->GetLocation();
242 
243     if (oat_file != nullptr) {
244       // Load the dex files from the oat file.
245       bool added_image_space = false;
246       if (oat_file->IsExecutable()) {
247         ScopedTrace app_image_timing("AppImage:Loading");
248 
249         // We need to throw away the image space if we are debuggable but the oat-file source of the
250         // image is not otherwise we might get classes with inlined methods or other such things.
251         std::unique_ptr<gc::space::ImageSpace> image_space;
252         if (ShouldLoadAppImage(oat_file.get())) {
253           image_space = oat_file_assistant.OpenImageSpace(oat_file.get());
254         }
255         if (image_space != nullptr) {
256           ScopedObjectAccess soa(self);
257           StackHandleScope<1> hs(self);
258           Handle<mirror::ClassLoader> h_loader(
259               hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
260           // Can not load app image without class loader.
261           if (h_loader != nullptr) {
262             std::string temp_error_msg;
263             // Add image space has a race condition since other threads could be reading from the
264             // spaces array.
265             {
266               ScopedThreadSuspension sts(self, ThreadState::kSuspended);
267               gc::ScopedGCCriticalSection gcs(self,
268                                               gc::kGcCauseAddRemoveAppImageSpace,
269                                               gc::kCollectorTypeAddRemoveAppImageSpace);
270               ScopedSuspendAll ssa("Add image space");
271               runtime->GetHeap()->AddSpace(image_space.get());
272             }
273             {
274               ScopedTrace image_space_timing("Adding image space");
275               added_image_space = runtime->GetClassLinker()->AddImageSpace(image_space.get(),
276                                                                            h_loader,
277                                                                            /*out*/&dex_files,
278                                                                            /*out*/&temp_error_msg);
279             }
280             if (added_image_space) {
281               // Successfully added image space to heap, release the map so that it does not get
282               // freed.
283               image_space.release();  // NOLINT b/117926937
284 
285               // Register for tracking.
286               for (const auto& dex_file : dex_files) {
287                 dex::tracking::RegisterDexFile(dex_file.get());
288               }
289             } else {
290               LOG(INFO) << "Failed to add image file " << temp_error_msg;
291               dex_files.clear();
292               {
293                 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
294                 gc::ScopedGCCriticalSection gcs(self,
295                                                 gc::kGcCauseAddRemoveAppImageSpace,
296                                                 gc::kCollectorTypeAddRemoveAppImageSpace);
297                 ScopedSuspendAll ssa("Remove image space");
298                 runtime->GetHeap()->RemoveSpace(image_space.get());
299               }
300               // Non-fatal, don't update error_msg.
301             }
302           }
303         }
304       }
305       if (!added_image_space) {
306         DCHECK(dex_files.empty());
307 
308         if (oat_file->RequiresImage()) {
309           LOG(WARNING) << "Loading "
310                        << oat_file->GetLocation()
311                        << " non-executable as it requires an image which we failed to load";
312           // file as non-executable.
313           OatFileAssistant nonexecutable_oat_file_assistant(dex_location,
314                                                             kRuntimeISA,
315                                                             context.get(),
316                                                             /*load_executable=*/false,
317                                                             only_use_system_oat_files_);
318           oat_file.reset(nonexecutable_oat_file_assistant.GetBestOatFile().release());
319 
320           // The file could be deleted concurrently (for example background
321           // dexopt, or secondary oat file being deleted by the app).
322           if (oat_file == nullptr) {
323             LOG(WARNING) << "Failed to reload oat file non-executable " << dex_location;
324           }
325         }
326 
327         if (oat_file != nullptr) {
328           dex_files = oat_file_assistant.LoadDexFiles(*oat_file.get(), dex_location);
329 
330           // Register for tracking.
331           for (const auto& dex_file : dex_files) {
332             dex::tracking::RegisterDexFile(dex_file.get());
333           }
334         }
335       }
336       if (dex_files.empty()) {
337         ScopedTrace failed_to_open_dex_files("FailedToOpenDexFilesFromOat");
338         error_msgs->push_back("Failed to open dex files from " + odex_location);
339       } else {
340         // Opened dex files from an oat file, madvise them to their loaded state.
341          for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
342            OatDexFile::MadviseDexFileAtLoad(*dex_file);
343          }
344       }
345 
346       if (oat_file != nullptr) {
347         VdexFile* vdex_file = oat_file->GetVdexFile();
348         if (vdex_file != nullptr) {
349           // Opened vdex file from an oat file, madvise it to its loaded state.
350           // TODO(b/196052575): Unify dex and vdex madvise knobs and behavior.
351           const size_t madvise_size_limit = Runtime::Current()->GetMadviseWillNeedSizeVdex();
352           Runtime::MadviseFileForRange(madvise_size_limit,
353                                        vdex_file->Size(),
354                                        vdex_file->Begin(),
355                                        vdex_file->End(),
356                                        vdex_file->GetName());
357         }
358 
359         VLOG(class_linker) << "Registering " << oat_file->GetLocation();
360         *out_oat_file = RegisterOatFile(std::move(oat_file));
361       }
362     } else {
363       // oat_file == nullptr
364       // Verify if any of the dex files being loaded is already in the class path.
365       // If so, report an error with the current stack trace.
366       // Most likely the developer didn't intend to do this because it will waste
367       // performance and memory.
368       if (oat_file_assistant.GetBestStatus() == OatFileAssistant::kOatContextOutOfDate) {
369         std::set<const DexFile*> already_exists_in_classpath =
370             context->CheckForDuplicateDexFiles(MakeNonOwningPointerVector(dex_files));
371         if (!already_exists_in_classpath.empty()) {
372           ScopedTrace duplicate_dex_files("DuplicateDexFilesInContext");
373           auto duplicate_it = already_exists_in_classpath.begin();
374           std::string duplicates = (*duplicate_it)->GetLocation();
375           for (duplicate_it++ ; duplicate_it != already_exists_in_classpath.end(); duplicate_it++) {
376             duplicates += "," + (*duplicate_it)->GetLocation();
377           }
378 
379           std::ostringstream out;
380           out << "Trying to load dex files which is already loaded in the same ClassLoader "
381               << "hierarchy.\n"
382               << "This is a strong indication of bad ClassLoader construct which leads to poor "
383               << "performance and wastes memory.\n"
384               << "The list of duplicate dex files is: " << duplicates << "\n"
385               << "The current class loader context is: "
386               << context->EncodeContextForOatFile("") << "\n"
387               << "Java stack trace:\n";
388 
389           {
390             ScopedObjectAccess soa(self);
391             self->DumpJavaStack(out);
392           }
393 
394           // We log this as an ERROR to stress the fact that this is most likely unintended.
395           // Note that ART cannot do anything about it. It is up to the app to fix their logic.
396           // Here we are trying to give a heads up on why the app might have performance issues.
397           LOG(ERROR) << out.str();
398         }
399       }
400     }
401   }
402 
403   // If we arrive here with an empty dex files list, it means we fail to load
404   // it/them through an .oat file.
405   if (dex_files.empty()) {
406     std::string error_msg;
407     static constexpr bool kVerifyChecksum = true;
408     const ArtDexFileLoader dex_file_loader;
409     if (!dex_file_loader.Open(dex_location,
410                               dex_location,
411                               Runtime::Current()->IsVerificationEnabled(),
412                               kVerifyChecksum,
413                               /*out*/ &error_msg,
414                               &dex_files)) {
415       ScopedTrace fail_to_open_dex_from_apk("FailedToOpenDexFilesFromApk");
416       LOG(WARNING) << error_msg;
417       error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)
418                             + " because: " + error_msg);
419     }
420   }
421 
422   if (Runtime::Current()->GetJit() != nullptr) {
423     Runtime::Current()->GetJit()->RegisterDexFiles(dex_files, class_loader);
424   }
425 
426   // Now that we loaded the dex/odex files, notify the runtime.
427   // Note that we do this everytime we load dex files.
428   Runtime::Current()->NotifyDexFileLoaded();
429 
430   return dex_files;
431 }
432 
GetDexFileHeaders(const std::vector<MemMap> & maps)433 static std::vector<const DexFile::Header*> GetDexFileHeaders(const std::vector<MemMap>& maps) {
434   std::vector<const DexFile::Header*> headers;
435   headers.reserve(maps.size());
436   for (const MemMap& map : maps) {
437     DCHECK(map.IsValid());
438     headers.push_back(reinterpret_cast<const DexFile::Header*>(map.Begin()));
439   }
440   return headers;
441 }
442 
OpenDexFilesFromOat(std::vector<MemMap> && dex_mem_maps,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)443 std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
444     std::vector<MemMap>&& dex_mem_maps,
445     jobject class_loader,
446     jobjectArray dex_elements,
447     const OatFile** out_oat_file,
448     std::vector<std::string>* error_msgs) {
449   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenDexFilesFromOat_Impl(
450       std::move(dex_mem_maps),
451       class_loader,
452       dex_elements,
453       out_oat_file,
454       error_msgs);
455 
456   if (error_msgs->empty()) {
457     // Remove write permission from DexFile pages. We do this at the end because
458     // OatFile assigns OatDexFile pointer in the DexFile objects.
459     for (std::unique_ptr<const DexFile>& dex_file : dex_files) {
460       if (!dex_file->DisableWrite()) {
461         error_msgs->push_back("Failed to make dex file " + dex_file->GetLocation() + " read-only");
462       }
463     }
464   }
465 
466   if (!error_msgs->empty()) {
467     return std::vector<std::unique_ptr<const DexFile>>();
468   }
469 
470   return dex_files;
471 }
472 
OpenDexFilesFromOat_Impl(std::vector<MemMap> && dex_mem_maps,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)473 std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat_Impl(
474     std::vector<MemMap>&& dex_mem_maps,
475     jobject class_loader,
476     jobjectArray dex_elements,
477     const OatFile** out_oat_file,
478     std::vector<std::string>* error_msgs) {
479   ScopedTrace trace(__FUNCTION__);
480   std::string error_msg;
481   DCHECK(error_msgs != nullptr);
482 
483   // Extract dex file headers from `dex_mem_maps`.
484   const std::vector<const DexFile::Header*> dex_headers = GetDexFileHeaders(dex_mem_maps);
485 
486   // Determine dex/vdex locations and the combined location checksum.
487   std::string dex_location;
488   std::string vdex_path;
489   bool has_vdex = OatFileAssistant::AnonymousDexVdexLocation(dex_headers,
490                                                              kRuntimeISA,
491                                                              &dex_location,
492                                                              &vdex_path);
493 
494   // Attempt to open an existing vdex and check dex file checksums match.
495   std::unique_ptr<VdexFile> vdex_file = nullptr;
496   if (has_vdex && OS::FileExists(vdex_path.c_str())) {
497     vdex_file = VdexFile::Open(vdex_path,
498                                /* writable= */ false,
499                                /* low_4gb= */ false,
500                                &error_msg);
501     if (vdex_file == nullptr) {
502       LOG(WARNING) << "Failed to open vdex " << vdex_path << ": " << error_msg;
503     } else if (!vdex_file->MatchesDexFileChecksums(dex_headers)) {
504       LOG(WARNING) << "Failed to open vdex " << vdex_path << ": dex file checksum mismatch";
505       vdex_file.reset(nullptr);
506     }
507   }
508 
509   // Load dex files. Skip structural dex file verification if vdex was found
510   // and dex checksums matched.
511   std::vector<std::unique_ptr<const DexFile>> dex_files;
512   for (size_t i = 0; i < dex_mem_maps.size(); ++i) {
513     static constexpr bool kVerifyChecksum = true;
514     const ArtDexFileLoader dex_file_loader;
515     std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(
516         DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()),
517         dex_headers[i]->checksum_,
518         std::move(dex_mem_maps[i]),
519         /* verify= */ (vdex_file == nullptr) && Runtime::Current()->IsVerificationEnabled(),
520         kVerifyChecksum,
521         &error_msg));
522     if (dex_file != nullptr) {
523       dex::tracking::RegisterDexFile(dex_file.get());  // Register for tracking.
524       dex_files.push_back(std::move(dex_file));
525     } else {
526       error_msgs->push_back("Failed to open dex files from memory: " + error_msg);
527     }
528   }
529 
530   // Check if we should proceed to creating an OatFile instance backed by the vdex.
531   // We need: (a) an existing vdex, (b) class loader (can be null if invoked via reflection),
532   // and (c) no errors during dex file loading.
533   if (vdex_file == nullptr || class_loader == nullptr || !error_msgs->empty()) {
534     return dex_files;
535   }
536 
537   // Attempt to create a class loader context, check OpenDexFiles succeeds (prerequisite
538   // for using the context later).
539   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::CreateContextForClassLoader(
540       class_loader,
541       dex_elements);
542   if (context == nullptr) {
543     LOG(ERROR) << "Could not create class loader context for " << vdex_path;
544     return dex_files;
545   }
546   DCHECK(context->OpenDexFiles())
547       << "Context created from already opened dex files should not attempt to open again";
548 
549   // Initialize an OatFile instance backed by the loaded vdex.
550   std::unique_ptr<OatFile> oat_file(OatFile::OpenFromVdex(MakeNonOwningPointerVector(dex_files),
551                                                           std::move(vdex_file),
552                                                           dex_location));
553   if (oat_file != nullptr) {
554     VLOG(class_linker) << "Registering " << oat_file->GetLocation();
555     *out_oat_file = RegisterOatFile(std::move(oat_file));
556   }
557   return dex_files;
558 }
559 
560 // Check how many vdex files exist in the same directory as the vdex file we are about
561 // to write. If more than or equal to kAnonymousVdexCacheSize, unlink the least
562 // recently used one(s) (according to stat-reported atime).
UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string & vdex_path_to_add,std::string * error_msg)563 static bool UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string& vdex_path_to_add,
564                                                 std::string* error_msg) {
565   std::string basename = android::base::Basename(vdex_path_to_add);
566   if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
567     // File is not for in memory dex files.
568     return true;
569   }
570 
571   if (OS::FileExists(vdex_path_to_add.c_str())) {
572     // File already exists and will be overwritten.
573     // This will not change the number of entries in the cache.
574     return true;
575   }
576 
577   auto last_slash = vdex_path_to_add.rfind('/');
578   CHECK(last_slash != std::string::npos);
579   std::string vdex_dir = vdex_path_to_add.substr(0, last_slash + 1);
580 
581   if (!OS::DirectoryExists(vdex_dir.c_str())) {
582     // Folder does not exist yet. Cache has zero entries.
583     return true;
584   }
585 
586   std::vector<std::pair<time_t, std::string>> cache;
587 
588   DIR* c_dir = opendir(vdex_dir.c_str());
589   if (c_dir == nullptr) {
590     *error_msg = "Unable to open " + vdex_dir + " to delete unused vdex files";
591     return false;
592   }
593   for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
594     if (de->d_type != DT_REG) {
595       continue;
596     }
597     basename = de->d_name;
598     if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
599       continue;
600     }
601     std::string fullname = vdex_dir + basename;
602 
603     struct stat s;
604     int rc = TEMP_FAILURE_RETRY(stat(fullname.c_str(), &s));
605     if (rc == -1) {
606       *error_msg = "Failed to stat() anonymous vdex file " + fullname;
607       return false;
608     }
609 
610     cache.push_back(std::make_pair(s.st_atime, fullname));
611   }
612   CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
613 
614   if (cache.size() < OatFileManager::kAnonymousVdexCacheSize) {
615     return true;
616   }
617 
618   std::sort(cache.begin(),
619             cache.end(),
620             [](const auto& a, const auto& b) { return a.first < b.first; });
621   for (size_t i = OatFileManager::kAnonymousVdexCacheSize - 1; i < cache.size(); ++i) {
622     if (unlink(cache[i].second.c_str()) != 0) {
623       *error_msg = "Could not unlink anonymous vdex file " + cache[i].second;
624       return false;
625     }
626   }
627 
628   return true;
629 }
630 
631 class BackgroundVerificationTask final : public Task {
632  public:
BackgroundVerificationTask(const std::vector<const DexFile * > & dex_files,jobject class_loader,const std::string & vdex_path)633   BackgroundVerificationTask(const std::vector<const DexFile*>& dex_files,
634                              jobject class_loader,
635                              const std::string& vdex_path)
636       : dex_files_(dex_files),
637         vdex_path_(vdex_path) {
638     Thread* const self = Thread::Current();
639     ScopedObjectAccess soa(self);
640     // Create a global ref for `class_loader` because it will be accessed from a different thread.
641     class_loader_ = soa.Vm()->AddGlobalRef(self, soa.Decode<mirror::ClassLoader>(class_loader));
642     CHECK(class_loader_ != nullptr);
643   }
644 
~BackgroundVerificationTask()645   ~BackgroundVerificationTask() {
646     Thread* const self = Thread::Current();
647     ScopedObjectAccess soa(self);
648     soa.Vm()->DeleteGlobalRef(self, class_loader_);
649   }
650 
Run(Thread * self)651   void Run(Thread* self) override {
652     std::string error_msg;
653     ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
654     verifier::VerifierDeps verifier_deps(dex_files_);
655 
656     // Iterate over all classes and verify them.
657     for (const DexFile* dex_file : dex_files_) {
658       for (uint32_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); cdef_idx++) {
659         const dex::ClassDef& class_def = dex_file->GetClassDef(cdef_idx);
660 
661         // Take handles inside the loop. The background verification is low priority
662         // and we want to minimize the risk of blocking anyone else.
663         ScopedObjectAccess soa(self);
664         StackHandleScope<2> hs(self);
665         Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
666             soa.Decode<mirror::ClassLoader>(class_loader_)));
667         Handle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(class_linker->FindClass(
668             self,
669             dex_file->GetClassDescriptor(class_def),
670             h_loader)));
671 
672         if (h_class == nullptr) {
673           CHECK(self->IsExceptionPending());
674           self->ClearException();
675           continue;
676         }
677 
678         if (&h_class->GetDexFile() != dex_file) {
679           // There is a different class in the class path or a parent class loader
680           // with the same descriptor. This `h_class` is not resolvable, skip it.
681           continue;
682         }
683 
684         CHECK(h_class->IsResolved()) << h_class->PrettyDescriptor();
685         class_linker->VerifyClass(self, &verifier_deps, h_class);
686         if (h_class->IsErroneous()) {
687           // ClassLinker::VerifyClass throws, which isn't useful here.
688           CHECK(soa.Self()->IsExceptionPending());
689           soa.Self()->ClearException();
690         }
691 
692         CHECK(h_class->IsVerified() || h_class->IsErroneous())
693             << h_class->PrettyDescriptor() << ": state=" << h_class->GetStatus();
694 
695         if (h_class->IsVerified()) {
696           verifier_deps.RecordClassVerified(*dex_file, class_def);
697         }
698       }
699     }
700 
701     // Delete old vdex files if there are too many in the folder.
702     if (!UnlinkLeastRecentlyUsedVdexIfNeeded(vdex_path_, &error_msg)) {
703       LOG(ERROR) << "Could not unlink old vdex files " << vdex_path_ << ": " << error_msg;
704       return;
705     }
706 
707     // Construct a vdex file and write `verifier_deps` into it.
708     if (!VdexFile::WriteToDisk(vdex_path_,
709                                dex_files_,
710                                verifier_deps,
711                                &error_msg)) {
712       LOG(ERROR) << "Could not write anonymous vdex " << vdex_path_ << ": " << error_msg;
713       return;
714     }
715   }
716 
Finalize()717   void Finalize() override {
718     delete this;
719   }
720 
721  private:
722   const std::vector<const DexFile*> dex_files_;
723   jobject class_loader_;
724   const std::string vdex_path_;
725 
726   DISALLOW_COPY_AND_ASSIGN(BackgroundVerificationTask);
727 };
728 
RunBackgroundVerification(const std::vector<const DexFile * > & dex_files,jobject class_loader)729 void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
730                                                jobject class_loader) {
731   Runtime* const runtime = Runtime::Current();
732   Thread* const self = Thread::Current();
733 
734   if (runtime->IsJavaDebuggable()) {
735     // Threads created by ThreadPool ("runtime threads") are not allowed to load
736     // classes when debuggable to match class-initialization semantics
737     // expectations. Do not verify in the background.
738     return;
739   }
740 
741   {
742     // Temporarily create a class loader context to see if we recognize the
743     // chain.
744     std::unique_ptr<ClassLoaderContext> context(
745         ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr));
746     if (context == nullptr) {
747       // We only run background verification for class loaders we know the lookup
748       // chain. Because the background verification runs on runtime threads,
749       // which do not call Java, we won't be able to load classes when
750       // verifying, which is something the current verifier relies on.
751       return;
752     }
753   }
754 
755   if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
756     // Do not run for legacy apps as they may depend on the previous class loader behaviour.
757     return;
758   }
759 
760   if (runtime->IsShuttingDown(self)) {
761     // Not allowed to create new threads during runtime shutdown.
762     return;
763   }
764 
765   if (dex_files.size() < 1) {
766     // Nothing to verify.
767     return;
768   }
769 
770   std::string dex_location = dex_files[0]->GetLocation();
771   const std::string& data_dir = Runtime::Current()->GetProcessDataDirectory();
772   if (!android::base::StartsWith(dex_location, data_dir)) {
773     // For now, we only run background verification for secondary dex files.
774     // Running it for primary or split APKs could have some undesirable
775     // side-effects, like overloading the device on app startup.
776     return;
777   }
778 
779   std::string error_msg;
780   std::string odex_filename;
781   if (!OatFileAssistant::DexLocationToOdexFilename(dex_location,
782                                                    kRuntimeISA,
783                                                    &odex_filename,
784                                                    &error_msg)) {
785     LOG(WARNING) << "Could not get odex filename for " << dex_location << ": " << error_msg;
786     return;
787   }
788 
789   if (LocationIsOnArtApexData(odex_filename) && Runtime::Current()->DenyArtApexDataFiles()) {
790     // Ignore vdex file associated with this odex file as the odex file is not trustworthy.
791     return;
792   }
793 
794   {
795     WriterMutexLock mu(self, *Locks::oat_file_manager_lock_);
796     if (verification_thread_pool_ == nullptr) {
797       verification_thread_pool_.reset(
798           new ThreadPool("Verification thread pool", /* num_threads= */ 1));
799       verification_thread_pool_->StartWorkers(self);
800     }
801   }
802   verification_thread_pool_->AddTask(self, new BackgroundVerificationTask(
803       dex_files,
804       class_loader,
805       GetVdexFilename(odex_filename)));
806 }
807 
WaitForWorkersToBeCreated()808 void OatFileManager::WaitForWorkersToBeCreated() {
809   DCHECK(!Runtime::Current()->IsShuttingDown(Thread::Current()))
810       << "Cannot create new threads during runtime shutdown";
811   if (verification_thread_pool_ != nullptr) {
812     verification_thread_pool_->WaitForWorkersToBeCreated();
813   }
814 }
815 
DeleteThreadPool()816 void OatFileManager::DeleteThreadPool() {
817   verification_thread_pool_.reset(nullptr);
818 }
819 
WaitForBackgroundVerificationTasks()820 void OatFileManager::WaitForBackgroundVerificationTasks() {
821   if (verification_thread_pool_ != nullptr) {
822     Thread* const self = Thread::Current();
823     verification_thread_pool_->WaitForWorkersToBeCreated();
824     verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
825   }
826 }
827 
ClearOnlyUseTrustedOatFiles()828 void OatFileManager::ClearOnlyUseTrustedOatFiles() {
829   only_use_system_oat_files_ = false;
830 }
831 
SetOnlyUseTrustedOatFiles()832 void OatFileManager::SetOnlyUseTrustedOatFiles() {
833   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
834   if (!oat_files_.empty()) {
835     LOG(FATAL) << "Unexpected non-empty loaded oat files ";
836   }
837   only_use_system_oat_files_ = true;
838 }
839 
DumpForSigQuit(std::ostream & os)840 void OatFileManager::DumpForSigQuit(std::ostream& os) {
841   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
842   std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
843   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
844     if (ContainsElement(boot_oat_files, oat_file.get())) {
845       continue;
846     }
847     os << oat_file->GetLocation() << ": " << oat_file->GetCompilerFilter() << "\n";
848   }
849 }
850 
ContainsPc(const void * code)851 bool OatFileManager::ContainsPc(const void* code) {
852   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
853   std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
854   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
855     if (oat_file->Contains(code)) {
856       return true;
857     }
858   }
859   return false;
860 }
861 
862 }  // namespace art
863