1 /*
2  * Copyright (C) 2016 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 "vdex_file.h"
18 
19 #include <sys/mman.h>  // For the PROT_* and MAP_* constants.
20 #include <sys/stat.h>  // for mkdir()
21 
22 #include <memory>
23 #include <unordered_set>
24 
25 #include <android-base/logging.h>
26 
27 #include "base/bit_utils.h"
28 #include "base/leb128.h"
29 #include "base/stl_util.h"
30 #include "base/systrace.h"
31 #include "base/unix_file/fd_file.h"
32 #include "class_linker.h"
33 #include "class_loader_context.h"
34 #include "dex/art_dex_file_loader.h"
35 #include "dex/class_accessor-inl.h"
36 #include "dex/dex_file_loader.h"
37 #include "gc/heap.h"
38 #include "gc/space/image_space.h"
39 #include "mirror/class-inl.h"
40 #include "quicken_info.h"
41 #include "handle_scope-inl.h"
42 #include "runtime.h"
43 #include "verifier/verifier_deps.h"
44 
45 namespace art {
46 
47 constexpr uint8_t VdexFile::VdexFileHeader::kVdexInvalidMagic[4];
48 constexpr uint8_t VdexFile::VdexFileHeader::kVdexMagic[4];
49 constexpr uint8_t VdexFile::VdexFileHeader::kVdexVersion[4];
50 
IsMagicValid() const51 bool VdexFile::VdexFileHeader::IsMagicValid() const {
52   return (memcmp(magic_, kVdexMagic, sizeof(kVdexMagic)) == 0);
53 }
54 
IsVdexVersionValid() const55 bool VdexFile::VdexFileHeader::IsVdexVersionValid() const {
56   return (memcmp(vdex_version_, kVdexVersion, sizeof(kVdexVersion)) == 0);
57 }
58 
VdexFileHeader(bool has_dex_section ATTRIBUTE_UNUSED)59 VdexFile::VdexFileHeader::VdexFileHeader(bool has_dex_section ATTRIBUTE_UNUSED)
60     : number_of_sections_(static_cast<uint32_t>(VdexSection::kNumberOfSections)) {
61   memcpy(magic_, kVdexMagic, sizeof(kVdexMagic));
62   memcpy(vdex_version_, kVdexVersion, sizeof(kVdexVersion));
63   DCHECK(IsMagicValid());
64   DCHECK(IsVdexVersionValid());
65 }
66 
OpenAtAddress(uint8_t * mmap_addr,size_t mmap_size,bool mmap_reuse,const std::string & vdex_filename,bool writable,bool low_4gb,bool unquicken,std::string * error_msg)67 std::unique_ptr<VdexFile> VdexFile::OpenAtAddress(uint8_t* mmap_addr,
68                                                   size_t mmap_size,
69                                                   bool mmap_reuse,
70                                                   const std::string& vdex_filename,
71                                                   bool writable,
72                                                   bool low_4gb,
73                                                   bool unquicken,
74                                                   std::string* error_msg) {
75   ScopedTrace trace(("VdexFile::OpenAtAddress " + vdex_filename).c_str());
76   if (!OS::FileExists(vdex_filename.c_str())) {
77     *error_msg = "File " + vdex_filename + " does not exist.";
78     return nullptr;
79   }
80 
81   std::unique_ptr<File> vdex_file;
82   if (writable) {
83     vdex_file.reset(OS::OpenFileReadWrite(vdex_filename.c_str()));
84   } else {
85     vdex_file.reset(OS::OpenFileForReading(vdex_filename.c_str()));
86   }
87   if (vdex_file == nullptr) {
88     *error_msg = "Could not open file " + vdex_filename +
89                  (writable ? " for read/write" : "for reading");
90     return nullptr;
91   }
92 
93   int64_t vdex_length = vdex_file->GetLength();
94   if (vdex_length == -1) {
95     *error_msg = "Could not read the length of file " + vdex_filename;
96     return nullptr;
97   }
98 
99   return OpenAtAddress(mmap_addr,
100                        mmap_size,
101                        mmap_reuse,
102                        vdex_file->Fd(),
103                        vdex_length,
104                        vdex_filename,
105                        writable,
106                        low_4gb,
107                        unquicken,
108                        error_msg);
109 }
110 
OpenAtAddress(uint8_t * mmap_addr,size_t mmap_size,bool mmap_reuse,int file_fd,size_t vdex_length,const std::string & vdex_filename,bool writable,bool low_4gb,bool unquicken,std::string * error_msg)111 std::unique_ptr<VdexFile> VdexFile::OpenAtAddress(uint8_t* mmap_addr,
112                                                   size_t mmap_size,
113                                                   bool mmap_reuse,
114                                                   int file_fd,
115                                                   size_t vdex_length,
116                                                   const std::string& vdex_filename,
117                                                   bool writable,
118                                                   bool low_4gb,
119                                                   bool unquicken,
120                                                   std::string* error_msg) {
121   if (mmap_addr != nullptr && mmap_size < vdex_length) {
122     LOG(WARNING) << "Insufficient pre-allocated space to mmap vdex.";
123     mmap_addr = nullptr;
124     mmap_reuse = false;
125   }
126   CHECK(!mmap_reuse || mmap_addr != nullptr);
127   CHECK(!(writable && unquicken)) << "We don't want to be writing unquickened files out to disk!";
128   // Start as PROT_WRITE so we can mprotect back to it if we want to.
129   MemMap mmap = MemMap::MapFileAtAddress(
130       mmap_addr,
131       vdex_length,
132       PROT_READ | PROT_WRITE,
133       writable ? MAP_SHARED : MAP_PRIVATE,
134       file_fd,
135       /* start= */ 0u,
136       low_4gb,
137       vdex_filename.c_str(),
138       mmap_reuse,
139       /* reservation= */ nullptr,
140       error_msg);
141   if (!mmap.IsValid()) {
142     *error_msg = "Failed to mmap file " + vdex_filename + " : " + *error_msg;
143     return nullptr;
144   }
145 
146   std::unique_ptr<VdexFile> vdex(new VdexFile(std::move(mmap)));
147   if (!vdex->IsValid()) {
148     *error_msg = "Vdex file is not valid";
149     return nullptr;
150   }
151 
152   if (!writable) {
153     Runtime* runtime = Runtime::Current();
154     // The runtime might not be available at this point if we're running
155     // dex2oat or oatdump.
156     if (runtime != nullptr) {
157       size_t madvise_size_limit = runtime->GetMadviseWillNeedSizeVdex();
158       Runtime::MadviseFileForRange(madvise_size_limit,
159                                    vdex->Size(),
160                                    vdex->Begin(),
161                                    vdex->End(),
162                                    vdex_filename);
163     }
164   }
165 
166   return vdex;
167 }
168 
GetNextDexFileData(const uint8_t * cursor,uint32_t dex_file_index) const169 const uint8_t* VdexFile::GetNextDexFileData(const uint8_t* cursor, uint32_t dex_file_index) const {
170   DCHECK(cursor == nullptr || (cursor > Begin() && cursor <= End()));
171   if (cursor == nullptr) {
172     // Beginning of the iteration, return the first dex file if there is one.
173     return HasDexSection() ? DexBegin() : nullptr;
174   } else if (dex_file_index >= GetNumberOfDexFiles()) {
175     return nullptr;
176   } else {
177     // Fetch the next dex file. Return null if there is none.
178     const uint8_t* data = cursor + reinterpret_cast<const DexFile::Header*>(cursor)->file_size_;
179     // Dex files are required to be 4 byte aligned. the OatWriter makes sure they are, see
180     // OatWriter::SeekToDexFiles.
181     return AlignUp(data, 4);
182   }
183 }
184 
GetNextTypeLookupTableData(const uint8_t * cursor,uint32_t dex_file_index) const185 const uint8_t* VdexFile::GetNextTypeLookupTableData(const uint8_t* cursor,
186                                                     uint32_t dex_file_index) const {
187   if (cursor == nullptr) {
188     // Beginning of the iteration, return the first dex file if there is one.
189     return HasTypeLookupTableSection() ? TypeLookupTableDataBegin() : nullptr;
190   } else if (dex_file_index >= GetNumberOfDexFiles()) {
191     return nullptr;
192   } else {
193     const uint8_t* data = cursor + sizeof(uint32_t) + reinterpret_cast<const uint32_t*>(cursor)[0];
194     // TypeLookupTables are required to be 4 byte aligned. the OatWriter makes sure they are.
195     // We don't check this here to be defensive against corrupted vdex files.
196     // Callers should check the returned value matches their expectations.
197     return data;
198   }
199 }
200 
OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>> * dex_files,std::string * error_msg) const201 bool VdexFile::OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>>* dex_files,
202                                std::string* error_msg) const {
203   const ArtDexFileLoader dex_file_loader;
204   size_t i = 0;
205   for (const uint8_t* dex_file_start = GetNextDexFileData(nullptr, i);
206        dex_file_start != nullptr;
207        dex_file_start = GetNextDexFileData(dex_file_start, ++i)) {
208     size_t size = reinterpret_cast<const DexFile::Header*>(dex_file_start)->file_size_;
209     // TODO: Supply the location information for a vdex file.
210     static constexpr char kVdexLocation[] = "";
211     std::string location = DexFileLoader::GetMultiDexLocation(i, kVdexLocation);
212     std::unique_ptr<const DexFile> dex(dex_file_loader.OpenWithDataSection(
213         dex_file_start,
214         size,
215         /*data_base=*/ nullptr,
216         /*data_size=*/ 0u,
217         location,
218         GetLocationChecksum(i),
219         /*oat_dex_file=*/ nullptr,
220         /*verify=*/ false,
221         /*verify_checksum=*/ false,
222         error_msg));
223     if (dex == nullptr) {
224       return false;
225     }
226     dex_files->push_back(std::move(dex));
227   }
228   return true;
229 }
230 
CreateDirectories(const std::string & child_path,std::string * error_msg)231 static bool CreateDirectories(const std::string& child_path, /* out */ std::string* error_msg) {
232   size_t last_slash_pos = child_path.find_last_of('/');
233   CHECK_NE(last_slash_pos, std::string::npos) << "Invalid path: " << child_path;
234   std::string parent_path = child_path.substr(0, last_slash_pos);
235   if (OS::DirectoryExists(parent_path.c_str())) {
236     return true;
237   } else if (CreateDirectories(parent_path, error_msg)) {
238     if (mkdir(parent_path.c_str(), 0700) == 0) {
239       return true;
240     }
241     *error_msg = "Could not create directory " + parent_path;
242     return false;
243   } else {
244     return false;
245   }
246 }
247 
WriteToDisk(const std::string & path,const std::vector<const DexFile * > & dex_files,const verifier::VerifierDeps & verifier_deps,std::string * error_msg)248 bool VdexFile::WriteToDisk(const std::string& path,
249                            const std::vector<const DexFile*>& dex_files,
250                            const verifier::VerifierDeps& verifier_deps,
251                            std::string* error_msg) {
252   std::vector<uint8_t> verifier_deps_data;
253   verifier_deps.Encode(dex_files, &verifier_deps_data);
254   uint32_t verifier_deps_size = verifier_deps_data.size();
255   // Add padding so the type lookup tables are 4 byte aligned.
256   uint32_t verifier_deps_with_padding_size = RoundUp(verifier_deps_data.size(), 4);
257   DCHECK_GE(verifier_deps_with_padding_size, verifier_deps_data.size());
258   verifier_deps_data.resize(verifier_deps_with_padding_size, 0);
259 
260   size_t type_lookup_table_size = 0u;
261   for (const DexFile* dex_file : dex_files) {
262     type_lookup_table_size +=
263         sizeof(uint32_t) + TypeLookupTable::RawDataLength(dex_file->NumClassDefs());
264   }
265 
266   VdexFile::VdexFileHeader vdex_header(/* has_dex_section= */ false);
267   VdexFile::VdexSectionHeader sections[static_cast<uint32_t>(VdexSection::kNumberOfSections)];
268 
269   // Set checksum section.
270   sections[VdexSection::kChecksumSection].section_kind = VdexSection::kChecksumSection;
271   sections[VdexSection::kChecksumSection].section_offset = GetChecksumsOffset();
272   sections[VdexSection::kChecksumSection].section_size =
273       sizeof(VdexFile::VdexChecksum) * dex_files.size();
274 
275   // Set dex section.
276   sections[VdexSection::kDexFileSection].section_kind = VdexSection::kDexFileSection;
277   sections[VdexSection::kDexFileSection].section_offset = 0u;
278   sections[VdexSection::kDexFileSection].section_size = 0u;
279 
280   // Set VerifierDeps section.
281   sections[VdexSection::kVerifierDepsSection].section_kind = VdexSection::kVerifierDepsSection;
282   sections[VdexSection::kVerifierDepsSection].section_offset =
283       GetChecksumsOffset() + sections[kChecksumSection].section_size;
284   sections[VdexSection::kVerifierDepsSection].section_size = verifier_deps_size;
285 
286   // Set TypeLookupTable section.
287   sections[VdexSection::kTypeLookupTableSection].section_kind =
288       VdexSection::kTypeLookupTableSection;
289   sections[VdexSection::kTypeLookupTableSection].section_offset =
290       sections[VdexSection::kVerifierDepsSection].section_offset + verifier_deps_with_padding_size;
291   sections[VdexSection::kTypeLookupTableSection].section_size = type_lookup_table_size;
292 
293   if (!CreateDirectories(path, error_msg)) {
294     return false;
295   }
296 
297   std::unique_ptr<File> out(OS::CreateEmptyFileWriteOnly(path.c_str()));
298   if (out == nullptr) {
299     *error_msg = "Could not open " + path + " for writing";
300     return false;
301   }
302 
303   // Write header.
304   if (!out->WriteFully(reinterpret_cast<const char*>(&vdex_header), sizeof(vdex_header))) {
305     *error_msg = "Could not write vdex header to " + path;
306     out->Unlink();
307     return false;
308   }
309 
310   // Write section infos.
311   if (!out->WriteFully(reinterpret_cast<const char*>(&sections), sizeof(sections))) {
312     *error_msg = "Could not write vdex sections to " + path;
313     out->Unlink();
314     return false;
315   }
316 
317   // Write checksum section.
318   for (const DexFile* dex_file : dex_files) {
319     uint32_t checksum = dex_file->GetLocationChecksum();
320     const uint32_t* checksum_ptr = &checksum;
321     static_assert(sizeof(*checksum_ptr) == sizeof(VdexFile::VdexChecksum));
322     if (!out->WriteFully(reinterpret_cast<const char*>(checksum_ptr),
323                          sizeof(VdexFile::VdexChecksum))) {
324       *error_msg = "Could not write dex checksums to " + path;
325       out->Unlink();
326       return false;
327     }
328   }
329 
330   if (!out->WriteFully(reinterpret_cast<const char*>(verifier_deps_data.data()),
331                        verifier_deps_with_padding_size)) {
332     *error_msg = "Could not write verifier deps to " + path;
333     out->Unlink();
334     return false;
335   }
336 
337   size_t written_type_lookup_table_size = 0;
338   for (const DexFile* dex_file : dex_files) {
339     TypeLookupTable type_lookup_table = TypeLookupTable::Create(*dex_file);
340     uint32_t size = type_lookup_table.RawDataLength();
341     DCHECK_ALIGNED(size, 4);
342     if (!out->WriteFully(reinterpret_cast<const char*>(&size), sizeof(uint32_t)) ||
343         !out->WriteFully(reinterpret_cast<const char*>(type_lookup_table.RawData()), size)) {
344       *error_msg = "Could not write type lookup table " + path;
345       out->Unlink();
346       return false;
347     }
348     written_type_lookup_table_size += sizeof(uint32_t) + size;
349   }
350   DCHECK_EQ(written_type_lookup_table_size, type_lookup_table_size);
351 
352   if (out->FlushClose() != 0) {
353     *error_msg = "Could not flush and close " + path;
354     out->Unlink();
355     return false;
356   }
357 
358   return true;
359 }
360 
MatchesDexFileChecksums(const std::vector<const DexFile::Header * > & dex_headers) const361 bool VdexFile::MatchesDexFileChecksums(const std::vector<const DexFile::Header*>& dex_headers)
362     const {
363   if (dex_headers.size() != GetNumberOfDexFiles()) {
364     LOG(WARNING) << "Mismatch of number of dex files in vdex (expected="
365         << GetNumberOfDexFiles() << ", actual=" << dex_headers.size() << ")";
366     return false;
367   }
368   const VdexChecksum* checksums = GetDexChecksumsArray();
369   for (size_t i = 0; i < dex_headers.size(); ++i) {
370     if (checksums[i] != dex_headers[i]->checksum_) {
371       LOG(WARNING) << "Mismatch of dex file checksum in vdex (index=" << i << ")";
372       return false;
373     }
374   }
375   return true;
376 }
377 
FindClassAndClearException(ClassLinker * class_linker,Thread * self,const char * name,Handle<mirror::ClassLoader> class_loader)378 static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker,
379                                                         Thread* self,
380                                                         const char* name,
381                                                         Handle<mirror::ClassLoader> class_loader)
382     REQUIRES_SHARED(Locks::mutator_lock_) {
383   ObjPtr<mirror::Class> result = class_linker->FindClass(self, name, class_loader);
384   if (result == nullptr) {
385     DCHECK(self->IsExceptionPending());
386     self->ClearException();
387   }
388   return result;
389 }
390 
GetStringFromId(const DexFile & dex_file,dex::StringIndex string_id,uint32_t number_of_extra_strings,const uint32_t * extra_strings_offsets,const uint8_t * verifier_deps)391 static const char* GetStringFromId(const DexFile& dex_file,
392                                    dex::StringIndex string_id,
393                                    uint32_t number_of_extra_strings,
394                                    const uint32_t* extra_strings_offsets,
395                                    const uint8_t* verifier_deps) {
396   uint32_t num_ids_in_dex = dex_file.NumStringIds();
397   if (string_id.index_ < num_ids_in_dex) {
398     return dex_file.StringDataByIdx(string_id);
399   } else {
400     CHECK_LT(string_id.index_ - num_ids_in_dex, number_of_extra_strings);
401     uint32_t offset = extra_strings_offsets[string_id.index_ - num_ids_in_dex];
402     return reinterpret_cast<const char*>(verifier_deps) + offset;
403   }
404 }
405 
406 // Returns an array of offsets where the assignability checks for each class
407 // definition are stored.
GetDexFileClassDefs(const uint8_t * verifier_deps,uint32_t index)408 static const uint32_t* GetDexFileClassDefs(const uint8_t* verifier_deps, uint32_t index) {
409   uint32_t dex_file_offset = reinterpret_cast<const uint32_t*>(verifier_deps)[index];
410   return reinterpret_cast<const uint32_t*>(verifier_deps + dex_file_offset);
411 }
412 
413 // Returns an array of offsets where extra strings are stored.
GetExtraStringsOffsets(const DexFile & dex_file,const uint8_t * verifier_deps,const uint32_t * dex_file_class_defs,uint32_t * number_of_extra_strings)414 static const uint32_t* GetExtraStringsOffsets(const DexFile& dex_file,
415                                               const uint8_t* verifier_deps,
416                                               const uint32_t* dex_file_class_defs,
417                                               /*out*/ uint32_t* number_of_extra_strings) {
418   // The information for strings is right after dex_file_class_defs, 4-byte
419   // aligned
420   uint32_t end_of_assignability_types = dex_file_class_defs[dex_file.NumClassDefs()];
421   const uint8_t* strings_data_start =
422       AlignUp(verifier_deps + end_of_assignability_types, sizeof(uint32_t));
423   // First entry is the number of extra strings for this dex file.
424   *number_of_extra_strings = *reinterpret_cast<const uint32_t*>(strings_data_start);
425   // Then an array of offsets in `verifier_deps` for the extra strings.
426   return reinterpret_cast<const uint32_t*>(strings_data_start + sizeof(uint32_t));
427 }
428 
ComputeClassStatus(Thread * self,Handle<mirror::Class> cls) const429 ClassStatus VdexFile::ComputeClassStatus(Thread* self, Handle<mirror::Class> cls) const {
430   const DexFile& dex_file = cls->GetDexFile();
431   uint16_t class_def_index = cls->GetDexClassDefIndex();
432 
433   // Find which dex file index from within the vdex file.
434   uint32_t index = 0;
435   for (; index < GetNumberOfDexFiles(); ++index) {
436     if (dex_file.GetLocationChecksum() == GetLocationChecksum(index)) {
437       break;
438     }
439   }
440 
441   DCHECK_NE(index, GetNumberOfDexFiles());
442 
443   const uint8_t* verifier_deps = GetVerifierDepsData().data();
444   const uint32_t* dex_file_class_defs = GetDexFileClassDefs(verifier_deps, index);
445 
446   // Fetch type checks offsets.
447   uint32_t class_def_offset = dex_file_class_defs[class_def_index];
448   if (class_def_offset == verifier::VerifierDeps::kNotVerifiedMarker) {
449     // Return a status that needs re-verification.
450     return ClassStatus::kResolved;
451   }
452   // End offset for this class's type checks. We know there is one and the loop
453   // will terminate.
454   uint32_t end_offset = verifier::VerifierDeps::kNotVerifiedMarker;
455   for (uint32_t i = class_def_index + 1; i < dex_file.NumClassDefs() + 1; ++i) {
456     end_offset = dex_file_class_defs[i];
457     if (end_offset != verifier::VerifierDeps::kNotVerifiedMarker) {
458       break;
459     }
460   }
461   DCHECK_NE(end_offset, verifier::VerifierDeps::kNotVerifiedMarker);
462 
463   uint32_t number_of_extra_strings = 0;
464   // Offset where extra strings are stored.
465   const uint32_t* extra_strings_offsets = GetExtraStringsOffsets(dex_file,
466                                                                  verifier_deps,
467                                                                  dex_file_class_defs,
468                                                                  &number_of_extra_strings);
469 
470   // Loop over and perform each assignability check.
471   StackHandleScope<3> hs(self);
472   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
473   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(cls->GetClassLoader()));
474   MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
475   MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
476 
477   const uint8_t* cursor = verifier_deps + class_def_offset;
478   const uint8_t* end = verifier_deps + end_offset;
479   while (cursor < end) {
480     uint32_t destination_index;
481     uint32_t source_index;
482     if (UNLIKELY(!DecodeUnsignedLeb128Checked(&cursor, end, &destination_index) ||
483                  !DecodeUnsignedLeb128Checked(&cursor, end, &source_index))) {
484       // Error parsing the data, just return that we are not verified.
485       return ClassStatus::kResolved;
486     }
487     const char* destination_desc = GetStringFromId(dex_file,
488                                                    dex::StringIndex(destination_index),
489                                                    number_of_extra_strings,
490                                                    extra_strings_offsets,
491                                                    verifier_deps);
492     destination.Assign(
493         FindClassAndClearException(class_linker, self, destination_desc, class_loader));
494 
495     const char* source_desc = GetStringFromId(dex_file,
496                                               dex::StringIndex(source_index),
497                                               number_of_extra_strings,
498                                               extra_strings_offsets,
499                                               verifier_deps);
500     source.Assign(FindClassAndClearException(class_linker, self, source_desc, class_loader));
501 
502     if (destination == nullptr || source == nullptr) {
503       // The interpreter / compiler can handle a missing class.
504       continue;
505     }
506 
507     DCHECK(destination->IsResolved() && source->IsResolved());
508     if (!destination->IsAssignableFrom(source.Get())) {
509       // An implicit assignability check is failing in the code, return that the
510       // class is not verified.
511       return ClassStatus::kResolved;
512     }
513   }
514 
515   return ClassStatus::kVerifiedNeedsAccessChecks;
516 }
517 
518 }  // namespace art
519