• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "dex_file_verifier.h"
18 
19 #include <algorithm>
20 #include <bitset>
21 #include <limits>
22 #include <memory>
23 
24 #include "android-base/logging.h"
25 #include "android-base/macros.h"
26 #include "android-base/stringprintf.h"
27 
28 #include "base/hash_map.h"
29 #include "base/leb128.h"
30 #include "base/safe_map.h"
31 #include "class_accessor-inl.h"
32 #include "code_item_accessors-inl.h"
33 #include "descriptors_names.h"
34 #include "dex_file-inl.h"
35 #include "dex_file_types.h"
36 #include "modifiers.h"
37 #include "utf-inl.h"
38 
39 namespace art {
40 namespace dex {
41 
42 using android::base::StringAppendV;
43 using android::base::StringPrintf;
44 
45 namespace {
46 
47 constexpr uint32_t kTypeIdLimit = std::numeric_limits<uint16_t>::max();
48 
IsValidOrNoTypeId(uint16_t low,uint16_t high)49 constexpr bool IsValidOrNoTypeId(uint16_t low, uint16_t high) {
50   return (high == 0) || ((high == 0xffffU) && (low == 0xffffU));
51 }
52 
IsValidTypeId(uint16_t low ATTRIBUTE_UNUSED,uint16_t high)53 constexpr bool IsValidTypeId(uint16_t low ATTRIBUTE_UNUSED, uint16_t high) {
54   return (high == 0);
55 }
56 
MapTypeToBitMask(DexFile::MapItemType map_item_type)57 constexpr uint32_t MapTypeToBitMask(DexFile::MapItemType map_item_type) {
58   switch (map_item_type) {
59     case DexFile::kDexTypeHeaderItem:               return 1 << 0;
60     case DexFile::kDexTypeStringIdItem:             return 1 << 1;
61     case DexFile::kDexTypeTypeIdItem:               return 1 << 2;
62     case DexFile::kDexTypeProtoIdItem:              return 1 << 3;
63     case DexFile::kDexTypeFieldIdItem:              return 1 << 4;
64     case DexFile::kDexTypeMethodIdItem:             return 1 << 5;
65     case DexFile::kDexTypeClassDefItem:             return 1 << 6;
66     case DexFile::kDexTypeCallSiteIdItem:           return 1 << 7;
67     case DexFile::kDexTypeMethodHandleItem:         return 1 << 8;
68     case DexFile::kDexTypeMapList:                  return 1 << 9;
69     case DexFile::kDexTypeTypeList:                 return 1 << 10;
70     case DexFile::kDexTypeAnnotationSetRefList:     return 1 << 11;
71     case DexFile::kDexTypeAnnotationSetItem:        return 1 << 12;
72     case DexFile::kDexTypeClassDataItem:            return 1 << 13;
73     case DexFile::kDexTypeCodeItem:                 return 1 << 14;
74     case DexFile::kDexTypeStringDataItem:           return 1 << 15;
75     case DexFile::kDexTypeDebugInfoItem:            return 1 << 16;
76     case DexFile::kDexTypeAnnotationItem:           return 1 << 17;
77     case DexFile::kDexTypeEncodedArrayItem:         return 1 << 18;
78     case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 19;
79     case DexFile::kDexTypeHiddenapiClassData:       return 1 << 20;
80   }
81   return 0;
82 }
83 
IsDataSectionType(DexFile::MapItemType map_item_type)84 constexpr bool IsDataSectionType(DexFile::MapItemType map_item_type) {
85   switch (map_item_type) {
86     case DexFile::kDexTypeHeaderItem:
87     case DexFile::kDexTypeStringIdItem:
88     case DexFile::kDexTypeTypeIdItem:
89     case DexFile::kDexTypeProtoIdItem:
90     case DexFile::kDexTypeFieldIdItem:
91     case DexFile::kDexTypeMethodIdItem:
92     case DexFile::kDexTypeClassDefItem:
93       return false;
94     case DexFile::kDexTypeCallSiteIdItem:
95     case DexFile::kDexTypeMethodHandleItem:
96     case DexFile::kDexTypeMapList:
97     case DexFile::kDexTypeTypeList:
98     case DexFile::kDexTypeAnnotationSetRefList:
99     case DexFile::kDexTypeAnnotationSetItem:
100     case DexFile::kDexTypeClassDataItem:
101     case DexFile::kDexTypeCodeItem:
102     case DexFile::kDexTypeStringDataItem:
103     case DexFile::kDexTypeDebugInfoItem:
104     case DexFile::kDexTypeAnnotationItem:
105     case DexFile::kDexTypeEncodedArrayItem:
106     case DexFile::kDexTypeAnnotationsDirectoryItem:
107     case DexFile::kDexTypeHiddenapiClassData:
108       return true;
109   }
110   return true;
111 }
112 
113 // Fields and methods may have only one of public/protected/private.
114 ALWAYS_INLINE
CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags)115 constexpr bool CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags) {
116   // Semantically we want 'return POPCOUNT(flags & kAcc) <= 1;'.
117   static_assert(IsPowerOfTwo(0), "0 not marked as power of two");
118   static_assert(IsPowerOfTwo(kAccPublic), "kAccPublic not marked as power of two");
119   static_assert(IsPowerOfTwo(kAccProtected), "kAccProtected not marked as power of two");
120   static_assert(IsPowerOfTwo(kAccPrivate), "kAccPrivate not marked as power of two");
121   return IsPowerOfTwo(flags & (kAccPublic | kAccProtected | kAccPrivate));
122 }
123 
124 // Helper functions to retrieve names from the dex file. We do not want to rely on DexFile
125 // functionality, as we're still verifying the dex file. begin and header correspond to the
126 // underscored variants in the DexFileVerifier.
127 
GetString(const uint8_t * const begin,const DexFile::Header * const header,dex::StringIndex string_idx)128 std::string GetString(const uint8_t* const begin,
129                       const DexFile::Header* const header,
130                       dex::StringIndex string_idx) {
131   // All sources of the `string_idx` have already been checked in CheckIntraSection().
132   DCHECK_LT(string_idx.index_, header->string_ids_size_);
133   const dex::StringId* string_id =
134       reinterpret_cast<const dex::StringId*>(begin + header->string_ids_off_) + string_idx.index_;
135 
136   // The string offset has been checked at the start of `CheckInterSection()`
137   // to point to a string data item checked by `CheckIntraSection()`.
138   const uint8_t* ptr = begin + string_id->string_data_off_;
139   DecodeUnsignedLeb128(&ptr);  // Ignore the result.
140   return reinterpret_cast<const char*>(ptr);
141 }
142 
GetClass(const uint8_t * const begin,const DexFile::Header * const header,dex::TypeIndex class_idx)143 std::string GetClass(const uint8_t* const begin,
144                      const DexFile::Header* const header,
145                      dex::TypeIndex class_idx) {
146   // All sources of `class_idx` have already been checked in CheckIntraSection().
147   CHECK_LT(class_idx.index_, header->type_ids_size_);
148 
149   const dex::TypeId* type_id =
150       reinterpret_cast<const dex::TypeId*>(begin + header->type_ids_off_) + class_idx.index_;
151 
152   // The `type_id->descriptor_idx_` has already been checked in CheckIntraTypeIdItem().
153   // However, it may not have been checked to be a valid descriptor, so return the raw
154   // string without converting with `PrettyDescriptor()`.
155   return GetString(begin, header, type_id->descriptor_idx_);
156 }
157 
GetFieldDescription(const uint8_t * const begin,const DexFile::Header * const header,uint32_t idx)158 std::string GetFieldDescription(const uint8_t* const begin,
159                                 const DexFile::Header* const header,
160                                 uint32_t idx) {
161   // The `idx` has already been checked in `DexFileVerifier::CheckIntraClassDataItemFields()`.
162   CHECK_LT(idx, header->field_ids_size_);
163 
164   const dex::FieldId* field_id =
165       reinterpret_cast<const dex::FieldId*>(begin + header->field_ids_off_) + idx;
166 
167   // Indexes in `*field_id` have already been checked in CheckIntraFieldIdItem().
168   std::string class_name = GetClass(begin, header, field_id->class_idx_);
169   std::string field_name = GetString(begin, header, field_id->name_idx_);
170   return class_name + "." + field_name;
171 }
172 
GetMethodDescription(const uint8_t * const begin,const DexFile::Header * const header,uint32_t idx)173 std::string GetMethodDescription(const uint8_t* const begin,
174                                  const DexFile::Header* const header,
175                                  uint32_t idx) {
176   // The `idx` has already been checked in `DexFileVerifier::CheckIntraClassDataItemMethods()`.
177   CHECK_LT(idx, header->method_ids_size_);
178 
179   const dex::MethodId* method_id =
180       reinterpret_cast<const dex::MethodId*>(begin + header->method_ids_off_) + idx;
181 
182   // Indexes in `*method_id` have already been checked in CheckIntraMethodIdItem().
183   std::string class_name = GetClass(begin, header, method_id->class_idx_);
184   std::string method_name = GetString(begin, header, method_id->name_idx_);
185   return class_name + "." + method_name;
186 }
187 
188 }  // namespace
189 
190 // Note: the anonymous namespace would be nice, but we need friend access into accessors.
191 
192 class DexFileVerifier {
193  public:
DexFileVerifier(const DexFile * dex_file,const char * location,bool verify_checksum)194   DexFileVerifier(const DexFile* dex_file, const char* location, bool verify_checksum)
195       : dex_file_(dex_file),
196         begin_(dex_file->Begin()),
197         size_(dex_file->Size()),
198         location_(location),
199         verify_checksum_(verify_checksum),
200         header_(&dex_file->GetHeader()),
201         ptr_(nullptr),
202         previous_item_(nullptr),
203         init_indices_{std::numeric_limits<size_t>::max(),
204                       std::numeric_limits<size_t>::max(),
205                       std::numeric_limits<size_t>::max(),
206                       std::numeric_limits<size_t>::max()} {}
207 
208   bool Verify();
209 
FailureReason() const210   const std::string& FailureReason() const {
211     return failure_reason_;
212   }
213 
214  private:
215   bool CheckShortyDescriptorMatch(char shorty_char, const char* descriptor, bool is_return_type);
216   bool CheckListSize(const void* start, size_t count, size_t element_size, const char* label);
217   // Check a list. The head is assumed to be at *ptr, and elements to be of size element_size. If
218   // successful, the ptr will be moved forward the amount covered by the list.
219   bool CheckList(size_t element_size, const char* label, const uint8_t* *ptr);
220   // Checks whether the offset is zero (when size is zero) or that the offset falls within the area
221   // claimed by the file.
222   bool CheckValidOffsetAndSize(uint32_t offset, uint32_t size, size_t alignment, const char* label);
223   // Checks whether the size is less than the limit.
CheckSizeLimit(uint32_t size,uint32_t limit,const char * label)224   ALWAYS_INLINE bool CheckSizeLimit(uint32_t size, uint32_t limit, const char* label) {
225     if (size > limit) {
226       ErrorStringPrintf("Size(%u) should not exceed limit(%u) for %s.", size, limit, label);
227       return false;
228     }
229     return true;
230   }
CheckIndex(uint32_t field,uint32_t limit,const char * label)231   ALWAYS_INLINE bool CheckIndex(uint32_t field, uint32_t limit, const char* label) {
232     if (UNLIKELY(field >= limit)) {
233       ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
234       return false;
235     }
236     return true;
237   }
238 
239   bool CheckHeader();
240   bool CheckMap();
241 
ReadUnsignedLittleEndian(uint32_t size)242   uint32_t ReadUnsignedLittleEndian(uint32_t size) {
243     uint32_t result = 0;
244     if (LIKELY(CheckListSize(ptr_, size, sizeof(uint8_t), "encoded_value"))) {
245       for (uint32_t i = 0; i < size; i++) {
246         result |= ((uint32_t) *(ptr_++)) << (i * 8);
247       }
248     }
249     return result;
250   }
251   bool CheckAndGetHandlerOffsets(const dex::CodeItem* code_item,
252                                  uint32_t* handler_offsets, uint32_t handlers_size);
253   bool CheckClassDataItemField(uint32_t idx,
254                                uint32_t access_flags,
255                                uint32_t class_access_flags,
256                                dex::TypeIndex class_type_index);
257   bool CheckClassDataItemMethod(uint32_t idx,
258                                 uint32_t access_flags,
259                                 uint32_t class_access_flags,
260                                 dex::TypeIndex class_type_index,
261                                 uint32_t code_offset,
262                                 bool expect_direct);
263   ALWAYS_INLINE
CheckOrder(const char * type_descr,uint32_t curr_index,uint32_t prev_index)264   bool CheckOrder(const char* type_descr, uint32_t curr_index, uint32_t prev_index) {
265     if (UNLIKELY(curr_index < prev_index)) {
266       ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32,
267                         type_descr,
268                         prev_index,
269                         curr_index);
270       return false;
271     }
272     return true;
273   }
274   bool CheckStaticFieldTypes(const dex::ClassDef& class_def);
275 
276   bool CheckPadding(size_t offset, uint32_t aligned_offset, DexFile::MapItemType type);
277   bool CheckEncodedValue();
278   bool CheckEncodedArray();
279   bool CheckEncodedAnnotation();
280 
281   bool CheckIntraTypeIdItem();
282   bool CheckIntraProtoIdItem();
283   bool CheckIntraFieldIdItem();
284   bool CheckIntraMethodIdItem();
285   bool CheckIntraClassDefItem(uint32_t class_def_index);
286   bool CheckIntraMethodHandleItem();
287   bool CheckIntraTypeList();
288   // Check all fields of the given type, reading `encoded_field` entries from `ptr_`.
289   template <bool kStatic>
290   bool CheckIntraClassDataItemFields(size_t count);
291   // Check direct or virtual methods, reading `encoded_method` entries from `ptr_`.
292   // Check virtual methods against duplicates with direct methods.
293   bool CheckIntraClassDataItemMethods(size_t num_methods,
294                                       ClassAccessor::Method* direct_methods,
295                                       size_t num_direct_methods);
296   bool CheckIntraClassDataItem();
297 
298   bool CheckIntraCodeItem();
299   bool CheckIntraStringDataItem();
300   bool CheckIntraDebugInfoItem();
301   bool CheckIntraAnnotationItem();
302   bool CheckIntraAnnotationsDirectoryItem();
303   bool CheckIntraHiddenapiClassData();
304 
305   template <DexFile::MapItemType kType>
306   bool CheckIntraSectionIterate(size_t offset, uint32_t count);
307   template <DexFile::MapItemType kType>
308   bool CheckIntraIdSection(size_t offset, uint32_t count);
309   template <DexFile::MapItemType kType>
310   bool CheckIntraDataSection(size_t offset, uint32_t count);
311   bool CheckIntraSection();
312 
313   bool CheckOffsetToTypeMap(size_t offset, uint16_t type);
314 
315   // Returns kDexNoIndex if there are no fields/methods, otherwise a 16-bit type index.
316   uint32_t FindFirstClassDataDefiner(const ClassAccessor& accessor);
317   uint32_t FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr);
318 
319   bool CheckInterStringIdItem();
320   bool CheckInterTypeIdItem();
321   bool CheckInterProtoIdItem();
322   bool CheckInterFieldIdItem();
323   bool CheckInterMethodIdItem();
324   bool CheckInterClassDefItem();
325   bool CheckInterCallSiteIdItem();
326   bool CheckInterAnnotationSetRefList();
327   bool CheckInterAnnotationSetItem();
328   bool CheckInterClassDataItem();
329   bool CheckInterAnnotationsDirectoryItem();
330 
331   bool CheckInterSectionIterate(size_t offset, uint32_t count, DexFile::MapItemType type);
332   bool CheckInterSection();
333 
ErrorStringPrintf(const char * fmt,...)334   void ErrorStringPrintf(const char* fmt, ...)
335       __attribute__((__format__(__printf__, 2, 3))) COLD_ATTR {
336     va_list ap;
337     va_start(ap, fmt);
338     DCHECK(failure_reason_.empty()) << failure_reason_;
339     failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
340     StringAppendV(&failure_reason_, fmt, ap);
341     va_end(ap);
342   }
FailureReasonIsSet() const343   bool FailureReasonIsSet() const { return failure_reason_.size() != 0; }
344 
345   // Check validity of the given access flags, interpreted for a field in the context of a class
346   // with the given second access flags.
347   bool CheckFieldAccessFlags(uint32_t idx,
348                              uint32_t field_access_flags,
349                              uint32_t class_access_flags,
350                              std::string* error_message);
351 
352   // Check validity of the given method and access flags, in the context of a class with the given
353   // second access flags.
354   bool CheckMethodAccessFlags(uint32_t method_index,
355                               uint32_t method_access_flags,
356                               uint32_t class_access_flags,
357                               uint32_t constructor_flags_by_name,
358                               bool has_code,
359                               bool expect_direct,
360                               std::string* error_message);
361 
362   // Check validity of given method if it's a constructor or class initializer.
363   bool CheckConstructorProperties(uint32_t method_index, uint32_t constructor_flags);
364 
365   void FindStringRangesForMethodNames();
366 
367   template <typename ExtraCheckFn>
368   bool VerifyTypeDescriptor(dex::TypeIndex idx, const char* error_msg, ExtraCheckFn extra_check);
369 
370   const DexFile* const dex_file_;
371   const uint8_t* const begin_;
372   const size_t size_;
373   const char* const location_;
374   const bool verify_checksum_;
375   const DexFile::Header* const header_;
376 
377   struct OffsetTypeMapEmptyFn {
378     // Make a hash map slot empty by making the offset 0. Offset 0 is a valid dex file offset that
379     // is in the offset of the dex file header. However, we only store data section items in the
380     // map, and these are after the header.
MakeEmptyart::dex::DexFileVerifier::OffsetTypeMapEmptyFn381     void MakeEmpty(std::pair<uint32_t, uint16_t>& pair) const {
382       pair.first = 0u;
383     }
384     // Check if a hash map slot is empty.
IsEmptyart::dex::DexFileVerifier::OffsetTypeMapEmptyFn385     bool IsEmpty(const std::pair<uint32_t, uint16_t>& pair) const {
386       return pair.first == 0;
387     }
388   };
389   struct OffsetTypeMapHashCompareFn {
390     // Hash function for offset.
operator ()art::dex::DexFileVerifier::OffsetTypeMapHashCompareFn391     size_t operator()(const uint32_t key) const {
392       return key;
393     }
394     // std::equal function for offset.
operator ()art::dex::DexFileVerifier::OffsetTypeMapHashCompareFn395     bool operator()(const uint32_t a, const uint32_t b) const {
396       return a == b;
397     }
398   };
399   // Map from offset to dex file type, HashMap for performance reasons.
400   HashMap<uint32_t,
401           uint16_t,
402           OffsetTypeMapEmptyFn,
403           OffsetTypeMapHashCompareFn,
404           OffsetTypeMapHashCompareFn> offset_to_type_map_;
405   const uint8_t* ptr_;
406   const void* previous_item_;
407 
408   std::string failure_reason_;
409 
410   // Cached string indices for "interesting" entries wrt/ method names. Will be populated by
411   // FindStringRangesForMethodNames (which is automatically called before verifying the
412   // classdataitem section).
413   //
414   // Strings starting with '<' are in the range
415   //    [angle_bracket_start_index_,angle_bracket_end_index_).
416   // angle_init_angle_index_ and angle_clinit_angle_index_ denote the indices of "<init>" and
417   // "<clinit>", respectively. If any value is not found, the corresponding index will be larger
418   // than any valid string index for this dex file.
419   struct {
420     size_t angle_bracket_start_index;
421     size_t angle_bracket_end_index;
422     size_t angle_init_angle_index;
423     size_t angle_clinit_angle_index;
424   } init_indices_;
425 
426   // A bitvector for verified type descriptors. Each bit corresponds to a type index. A set
427   // bit denotes that the descriptor has been verified wrt/ IsValidDescriptor.
428   std::vector<char> verified_type_descriptors_;
429 
430   // Set of type ids for which there are ClassDef elements in the dex file. Using a bitset
431   // avoids all allocations. The bitset should be implemented as 8K of storage, which is
432   // tight enough for all callers.
433   std::bitset<kTypeIdLimit + 1> defined_classes_;
434 
435   // Class definition indexes, valid only if corresponding `defined_classes_[.]` is true.
436   std::vector<uint16_t> defined_class_indexes_;
437 };
438 
439 template <typename ExtraCheckFn>
VerifyTypeDescriptor(dex::TypeIndex idx,const char * error_msg,ExtraCheckFn extra_check)440 bool DexFileVerifier::VerifyTypeDescriptor(dex::TypeIndex idx,
441                                            const char* error_msg,
442                                            ExtraCheckFn extra_check) {
443   // All sources of the `idx` have already been checked in CheckIntraSection().
444   DCHECK_LT(idx.index_, header_->type_ids_size_);
445 
446   char cached_char = verified_type_descriptors_[idx.index_];
447   if (cached_char != 0) {
448     if (!extra_check(cached_char)) {
449       const char* descriptor = dex_file_->StringByTypeIdx(idx);
450       ErrorStringPrintf("%s: '%s'", error_msg, descriptor);
451       return false;
452     }
453     return true;
454   }
455 
456   const char* descriptor = dex_file_->StringByTypeIdx(idx);
457   if (UNLIKELY(!IsValidDescriptor(descriptor))) {
458     ErrorStringPrintf("%s: '%s'", error_msg, descriptor);
459     return false;
460   }
461   verified_type_descriptors_[idx.index_] = descriptor[0];
462 
463   if (!extra_check(descriptor[0])) {
464     ErrorStringPrintf("%s: '%s'", error_msg, descriptor);
465     return false;
466   }
467   return true;
468 }
469 
CheckShortyDescriptorMatch(char shorty_char,const char * descriptor,bool is_return_type)470 bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
471                                                 bool is_return_type) {
472   switch (shorty_char) {
473     case 'V':
474       if (UNLIKELY(!is_return_type)) {
475         ErrorStringPrintf("Invalid use of void");
476         return false;
477       }
478       FALLTHROUGH_INTENDED;
479     case 'B':
480     case 'C':
481     case 'D':
482     case 'F':
483     case 'I':
484     case 'J':
485     case 'S':
486     case 'Z':
487       if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
488         ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
489                           shorty_char, descriptor);
490         return false;
491       }
492       break;
493     case 'L':
494       if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
495         ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
496         return false;
497       }
498       break;
499     default:
500       ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
501       return false;
502   }
503   return true;
504 }
505 
CheckListSize(const void * start,size_t count,size_t elem_size,const char * label)506 bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
507                                     const char* label) {
508   // Check that element size is not 0.
509   DCHECK_NE(elem_size, 0U);
510 
511   size_t offset = reinterpret_cast<const uint8_t*>(start) - begin_;
512   if (UNLIKELY(offset > size_)) {
513     ErrorStringPrintf("Offset beyond end of file for %s: %zx to %zx", label, offset, size_);
514     return false;
515   }
516 
517   // Calculate the number of elements that fit until the end of file,
518   // rather than calculating the end of the range as that could overflow.
519   size_t max_elements = (size_ - offset) / elem_size;
520   if (UNLIKELY(max_elements < count)) {
521     ErrorStringPrintf(
522         "List too large for %s: %zx+%zu*%zu > %zx", label, offset, count, elem_size, size_);
523     return false;
524   }
525 
526   return true;
527 }
528 
CheckList(size_t element_size,const char * label,const uint8_t ** ptr)529 bool DexFileVerifier::CheckList(size_t element_size, const char* label, const uint8_t* *ptr) {
530   // Check that the list is available. The first 4B are the count.
531   if (!CheckListSize(*ptr, 1, 4U, label)) {
532     return false;
533   }
534 
535   uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
536   if (count > 0) {
537     if (!CheckListSize(*ptr + 4, count, element_size, label)) {
538       return false;
539     }
540   }
541 
542   *ptr += 4 + count * element_size;
543   return true;
544 }
545 
CheckValidOffsetAndSize(uint32_t offset,uint32_t size,size_t alignment,const char * label)546 bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset,
547                                               uint32_t size,
548                                               size_t alignment,
549                                               const char* label) {
550   if (size == 0) {
551     if (offset != 0) {
552       ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
553       return false;
554     }
555   }
556   if (size_ <= offset) {
557     ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
558     return false;
559   }
560   if (alignment != 0 && !IsAlignedParam(offset, alignment)) {
561     ErrorStringPrintf("Offset(%d) should be aligned by %zu for %s.", offset, alignment, label);
562     return false;
563   }
564   return true;
565 }
566 
CheckHeader()567 bool DexFileVerifier::CheckHeader() {
568   // Check file size from the header.
569   uint32_t expected_size = header_->file_size_;
570   if (size_ != expected_size) {
571     ErrorStringPrintf("Bad file size (%zd, expected %u)", size_, expected_size);
572     return false;
573   }
574 
575   uint32_t adler_checksum = dex_file_->CalculateChecksum();
576   // Compute and verify the checksum in the header.
577   if (adler_checksum != header_->checksum_) {
578     if (verify_checksum_) {
579       ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
580       return false;
581     } else {
582       LOG(WARNING) << StringPrintf(
583           "Ignoring bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
584     }
585   }
586 
587   // Check the contents of the header.
588   if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
589     ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
590     return false;
591   }
592 
593   const uint32_t expected_header_size = dex_file_->IsCompactDexFile()
594       ? sizeof(CompactDexFile::Header)
595       : sizeof(StandardDexFile::Header);
596 
597   if (header_->header_size_ != expected_header_size) {
598     ErrorStringPrintf("Bad header size: %ud expected %ud",
599                       header_->header_size_,
600                       expected_header_size);
601     return false;
602   }
603 
604   // Check that all offsets are inside the file.
605   bool result =
606       CheckValidOffsetAndSize(header_->link_off_,
607                               header_->link_size_,
608                               /* alignment= */ 0,
609                               "link") &&
610       CheckValidOffsetAndSize(header_->map_off_,
611                               header_->map_off_,
612                               /* alignment= */ 4,
613                               "map") &&
614       CheckValidOffsetAndSize(header_->string_ids_off_,
615                               header_->string_ids_size_,
616                               /* alignment= */ 4,
617                               "string-ids") &&
618       CheckValidOffsetAndSize(header_->type_ids_off_,
619                               header_->type_ids_size_,
620                               /* alignment= */ 4,
621                               "type-ids") &&
622       CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") &&
623       CheckValidOffsetAndSize(header_->proto_ids_off_,
624                               header_->proto_ids_size_,
625                               /* alignment= */ 4,
626                               "proto-ids") &&
627       CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") &&
628       CheckValidOffsetAndSize(header_->field_ids_off_,
629                               header_->field_ids_size_,
630                               /* alignment= */ 4,
631                               "field-ids") &&
632       CheckValidOffsetAndSize(header_->method_ids_off_,
633                               header_->method_ids_size_,
634                               /* alignment= */ 4,
635                               "method-ids") &&
636       CheckValidOffsetAndSize(header_->class_defs_off_,
637                               header_->class_defs_size_,
638                               /* alignment= */ 4,
639                               "class-defs") &&
640       CheckValidOffsetAndSize(header_->data_off_,
641                               header_->data_size_,
642                               // Unaligned, spec doesn't talk about it, even though size
643                               // is supposed to be a multiple of 4.
644                               /* alignment= */ 0,
645                               "data");
646   return result;
647 }
648 
CheckMap()649 bool DexFileVerifier::CheckMap() {
650   const dex::MapList* map = reinterpret_cast<const dex::MapList*>(begin_ + header_->map_off_);
651   // Check that map list content is available.
652   if (!CheckListSize(map, 1, sizeof(dex::MapList), "maplist content")) {
653     return false;
654   }
655 
656   const dex::MapItem* item = map->list_;
657 
658   uint32_t count = map->size_;
659   uint32_t last_offset = 0;
660   uint32_t last_type = 0;
661   uint32_t data_item_count = 0;
662   uint32_t data_items_left = header_->data_size_;
663   uint32_t used_bits = 0;
664 
665   // Check the validity of the size of the map list.
666   if (!CheckListSize(item, count, sizeof(dex::MapItem), "map size")) {
667     return false;
668   }
669 
670   // Check the items listed in the map.
671   for (uint32_t i = 0; i < count; i++) {
672     if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
673       ErrorStringPrintf("Out of order map item: %x then %x for type %x last type was %x",
674                         last_offset,
675                         item->offset_,
676                         static_cast<uint32_t>(item->type_),
677                         last_type);
678       return false;
679     }
680     if (UNLIKELY(item->offset_ >= header_->file_size_)) {
681       ErrorStringPrintf("Map item after end of file: %x, size %x",
682                         item->offset_, header_->file_size_);
683       return false;
684     }
685 
686     DexFile::MapItemType item_type = static_cast<DexFile::MapItemType>(item->type_);
687     if (IsDataSectionType(item_type)) {
688       uint32_t icount = item->size_;
689       if (UNLIKELY(icount > data_items_left)) {
690         ErrorStringPrintf("Too many items in data section: %ud item_type %zx",
691                           data_item_count + icount,
692                           static_cast<size_t>(item_type));
693         return false;
694       }
695       data_items_left -= icount;
696       data_item_count += icount;
697     }
698 
699     uint32_t bit = MapTypeToBitMask(item_type);
700 
701     if (UNLIKELY(bit == 0)) {
702       ErrorStringPrintf("Unknown map section type %x", item->type_);
703       return false;
704     }
705 
706     if (UNLIKELY((used_bits & bit) != 0)) {
707       ErrorStringPrintf("Duplicate map section of type %x", item->type_);
708       return false;
709     }
710 
711     used_bits |= bit;
712     last_offset = item->offset_;
713     last_type = item->type_;
714     item++;
715   }
716 
717   // Check for missing sections in the map.
718   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
719     ErrorStringPrintf("Map is missing header entry");
720     return false;
721   }
722   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
723     ErrorStringPrintf("Map is missing map_list entry");
724     return false;
725   }
726   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
727                ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
728     ErrorStringPrintf("Map is missing string_ids entry");
729     return false;
730   }
731   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
732                ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
733     ErrorStringPrintf("Map is missing type_ids entry");
734     return false;
735   }
736   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
737                ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
738     ErrorStringPrintf("Map is missing proto_ids entry");
739     return false;
740   }
741   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
742                ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
743     ErrorStringPrintf("Map is missing field_ids entry");
744     return false;
745   }
746   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
747                ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
748     ErrorStringPrintf("Map is missing method_ids entry");
749     return false;
750   }
751   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
752                ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
753     ErrorStringPrintf("Map is missing class_defs entry");
754     return false;
755   }
756   return true;
757 }
758 
759 #define DECODE_UNSIGNED_CHECKED_FROM_WITH_ERROR_VALUE(ptr, var, error_value)  \
760   uint32_t var;                                                               \
761   if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) {         \
762     return error_value;                                                       \
763   }
764 
765 #define DECODE_UNSIGNED_CHECKED_FROM(ptr, var)                        \
766   uint32_t var;                                                       \
767   if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
768     ErrorStringPrintf("Read out of bounds");                          \
769     return false;                                                     \
770   }
771 
772 #define DECODE_SIGNED_CHECKED_FROM(ptr, var)                        \
773   int32_t var;                                                      \
774   if (!DecodeSignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
775     ErrorStringPrintf("Read out of bounds");                        \
776     return false;                                                   \
777   }
778 
CheckAndGetHandlerOffsets(const dex::CodeItem * code_item,uint32_t * handler_offsets,uint32_t handlers_size)779 bool DexFileVerifier::CheckAndGetHandlerOffsets(const dex::CodeItem* code_item,
780                                                 uint32_t* handler_offsets,
781                                                 uint32_t handlers_size) {
782   CodeItemDataAccessor accessor(*dex_file_, code_item);
783   const uint8_t* handlers_base = accessor.GetCatchHandlerData();
784 
785   for (uint32_t i = 0; i < handlers_size; i++) {
786     bool catch_all;
787     size_t offset = ptr_ - handlers_base;
788     DECODE_SIGNED_CHECKED_FROM(ptr_, size);
789 
790     if (UNLIKELY((size < -65536) || (size > 65536))) {
791       ErrorStringPrintf("Invalid exception handler size: %d", size);
792       return false;
793     }
794 
795     if (size <= 0) {
796       catch_all = true;
797       size = -size;
798     } else {
799       catch_all = false;
800     }
801 
802     handler_offsets[i] = static_cast<uint32_t>(offset);
803 
804     while (size-- > 0) {
805       DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
806       if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
807         return false;
808       }
809 
810       DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
811       if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
812         ErrorStringPrintf("Invalid handler addr: %x", addr);
813         return false;
814       }
815     }
816 
817     if (catch_all) {
818       DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
819       if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
820         ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
821         return false;
822       }
823     }
824   }
825 
826   return true;
827 }
828 
CheckClassDataItemField(uint32_t idx,uint32_t access_flags,uint32_t class_access_flags,dex::TypeIndex class_type_index)829 bool DexFileVerifier::CheckClassDataItemField(uint32_t idx,
830                                               uint32_t access_flags,
831                                               uint32_t class_access_flags,
832                                               dex::TypeIndex class_type_index) {
833   // The `idx` has already been checked in `CheckIntraClassDataItemFields()`.
834   DCHECK_LE(idx, header_->field_ids_size_);
835 
836   // Check that it's the right class.
837   dex::TypeIndex my_class_index =
838       (reinterpret_cast<const dex::FieldId*>(begin_ + header_->field_ids_off_) + idx)->class_idx_;
839   if (class_type_index != my_class_index) {
840     ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16,
841                       my_class_index.index_,
842                       class_type_index.index_);
843     return false;
844   }
845 
846   // Check field access flags.
847   std::string error_msg;
848   if (!CheckFieldAccessFlags(idx, access_flags, class_access_flags, &error_msg)) {
849     ErrorStringPrintf("%s", error_msg.c_str());
850     return false;
851   }
852 
853   return true;
854 }
855 
CheckClassDataItemMethod(uint32_t idx,uint32_t access_flags,uint32_t class_access_flags,dex::TypeIndex class_type_index,uint32_t code_offset,bool expect_direct)856 bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx,
857                                                uint32_t access_flags,
858                                                uint32_t class_access_flags,
859                                                dex::TypeIndex class_type_index,
860                                                uint32_t code_offset,
861                                                bool expect_direct) {
862   // The `idx` has already been checked in `CheckIntraClassDataItemMethods()`.
863   DCHECK_LT(idx, header_->method_ids_size_);
864 
865   const dex::MethodId& method_id =
866       *(reinterpret_cast<const dex::MethodId*>(begin_ + header_->method_ids_off_) + idx);
867 
868   // Check that it's the right class.
869   dex::TypeIndex my_class_index = method_id.class_idx_;
870   if (class_type_index != my_class_index) {
871     ErrorStringPrintf("Method's class index unexpected, %" PRIu16 " vs %" PRIu16,
872                       my_class_index.index_,
873                       class_type_index.index_);
874     return false;
875   }
876 
877   std::string error_msg;
878   uint32_t constructor_flags_by_name = 0;
879   {
880     uint32_t string_idx = method_id.name_idx_.index_;
881     if (!CheckIndex(string_idx, header_->string_ids_size_, "method flags verification")) {
882       return false;
883     }
884     if (UNLIKELY(string_idx < init_indices_.angle_bracket_end_index) &&
885             string_idx >= init_indices_.angle_bracket_start_index) {
886       if (string_idx == init_indices_.angle_clinit_angle_index) {
887         constructor_flags_by_name = kAccStatic | kAccConstructor;
888       } else if (string_idx == init_indices_.angle_init_angle_index) {
889         constructor_flags_by_name = kAccConstructor;
890       } else {
891         ErrorStringPrintf("Bad method name for method index %u", idx);
892         return false;
893       }
894     }
895   }
896 
897   bool has_code = (code_offset != 0);
898   if (!CheckMethodAccessFlags(idx,
899                               access_flags,
900                               class_access_flags,
901                               constructor_flags_by_name,
902                               has_code,
903                               expect_direct,
904                               &error_msg)) {
905     ErrorStringPrintf("%s", error_msg.c_str());
906     return false;
907   }
908 
909   if (constructor_flags_by_name != 0) {
910     if (!CheckConstructorProperties(idx, constructor_flags_by_name)) {
911       DCHECK(FailureReasonIsSet());
912       return false;
913     }
914   }
915 
916   return true;
917 }
918 
CheckPadding(size_t offset,uint32_t aligned_offset,DexFile::MapItemType type)919 bool DexFileVerifier::CheckPadding(size_t offset,
920                                    uint32_t aligned_offset,
921                                    DexFile::MapItemType type) {
922   if (offset < aligned_offset) {
923     if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(uint8_t), "section")) {
924       return false;
925     }
926     while (offset < aligned_offset) {
927       if (UNLIKELY(*ptr_ != '\0')) {
928         ErrorStringPrintf("Non-zero padding %x before section of type %zu at offset 0x%zx",
929                           *ptr_,
930                           static_cast<size_t>(type),
931                           offset);
932         return false;
933       }
934       ptr_++;
935       offset++;
936     }
937   }
938   return true;
939 }
940 
CheckEncodedValue()941 bool DexFileVerifier::CheckEncodedValue() {
942   if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "encoded_value header")) {
943     return false;
944   }
945 
946   uint8_t header_byte = *(ptr_++);
947   uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
948   uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
949 
950   switch (value_type) {
951     case DexFile::kDexAnnotationByte:
952       if (UNLIKELY(value_arg != 0)) {
953         ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
954         return false;
955       }
956       ptr_++;
957       break;
958     case DexFile::kDexAnnotationShort:
959     case DexFile::kDexAnnotationChar:
960       if (UNLIKELY(value_arg > 1)) {
961         ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
962         return false;
963       }
964       ptr_ += value_arg + 1;
965       break;
966     case DexFile::kDexAnnotationInt:
967     case DexFile::kDexAnnotationFloat:
968       if (UNLIKELY(value_arg > 3)) {
969         ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
970         return false;
971       }
972       ptr_ += value_arg + 1;
973       break;
974     case DexFile::kDexAnnotationLong:
975     case DexFile::kDexAnnotationDouble:
976       ptr_ += value_arg + 1;
977       break;
978     case DexFile::kDexAnnotationString: {
979       if (UNLIKELY(value_arg > 3)) {
980         ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
981         return false;
982       }
983       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
984       if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
985         return false;
986       }
987       break;
988     }
989     case DexFile::kDexAnnotationType: {
990       if (UNLIKELY(value_arg > 3)) {
991         ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
992         return false;
993       }
994       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
995       if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
996         return false;
997       }
998       break;
999     }
1000     case DexFile::kDexAnnotationField:
1001     case DexFile::kDexAnnotationEnum: {
1002       if (UNLIKELY(value_arg > 3)) {
1003         ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
1004         return false;
1005       }
1006       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
1007       if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
1008         return false;
1009       }
1010       break;
1011     }
1012     case DexFile::kDexAnnotationMethod: {
1013       if (UNLIKELY(value_arg > 3)) {
1014         ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
1015         return false;
1016       }
1017       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
1018       if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
1019         return false;
1020       }
1021       break;
1022     }
1023     case DexFile::kDexAnnotationArray:
1024       if (UNLIKELY(value_arg != 0)) {
1025         ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
1026         return false;
1027       }
1028       if (!CheckEncodedArray()) {
1029         return false;
1030       }
1031       break;
1032     case DexFile::kDexAnnotationAnnotation:
1033       if (UNLIKELY(value_arg != 0)) {
1034         ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
1035         return false;
1036       }
1037       if (!CheckEncodedAnnotation()) {
1038         return false;
1039       }
1040       break;
1041     case DexFile::kDexAnnotationNull:
1042       if (UNLIKELY(value_arg != 0)) {
1043         ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
1044         return false;
1045       }
1046       break;
1047     case DexFile::kDexAnnotationBoolean:
1048       if (UNLIKELY(value_arg > 1)) {
1049         ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
1050         return false;
1051       }
1052       break;
1053     case DexFile::kDexAnnotationMethodType: {
1054       if (UNLIKELY(value_arg > 3)) {
1055         ErrorStringPrintf("Bad encoded_value method type size %x", value_arg);
1056         return false;
1057       }
1058       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
1059       if (!CheckIndex(idx, header_->proto_ids_size_, "method_type value")) {
1060         return false;
1061       }
1062       break;
1063     }
1064     case DexFile::kDexAnnotationMethodHandle: {
1065       if (UNLIKELY(value_arg > 3)) {
1066         ErrorStringPrintf("Bad encoded_value method handle size %x", value_arg);
1067         return false;
1068       }
1069       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
1070       if (!CheckIndex(idx, dex_file_->NumMethodHandles(), "method_handle value")) {
1071         return false;
1072       }
1073       break;
1074     }
1075     default:
1076       ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
1077       return false;
1078   }
1079 
1080   return true;
1081 }
1082 
CheckEncodedArray()1083 bool DexFileVerifier::CheckEncodedArray() {
1084   DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
1085 
1086   for (; size != 0u; --size) {
1087     if (!CheckEncodedValue()) {
1088       failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
1089       return false;
1090     }
1091   }
1092   return true;
1093 }
1094 
CheckEncodedAnnotation()1095 bool DexFileVerifier::CheckEncodedAnnotation() {
1096   DECODE_UNSIGNED_CHECKED_FROM(ptr_, anno_idx);
1097   if (!CheckIndex(anno_idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
1098     return false;
1099   }
1100 
1101   DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
1102   uint32_t last_idx = 0;
1103 
1104   for (uint32_t i = 0; i < size; i++) {
1105     DECODE_UNSIGNED_CHECKED_FROM(ptr_, idx);
1106     if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
1107       return false;
1108     }
1109 
1110     if (UNLIKELY(last_idx >= idx && i != 0)) {
1111       ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
1112                         last_idx, idx);
1113       return false;
1114     }
1115 
1116     if (!CheckEncodedValue()) {
1117       return false;
1118     }
1119 
1120     last_idx = idx;
1121   }
1122   return true;
1123 }
1124 
CheckStaticFieldTypes(const dex::ClassDef & class_def)1125 bool DexFileVerifier::CheckStaticFieldTypes(const dex::ClassDef& class_def) {
1126   ClassAccessor accessor(*dex_file_, ptr_);
1127   EncodedStaticFieldValueIterator array_it(*dex_file_, class_def);
1128 
1129   for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
1130     if (!array_it.HasNext()) {
1131       break;
1132     }
1133     uint32_t index = field.GetIndex();
1134     // The `index` has already been checked in `CheckIntraClassDataItemFields()`.
1135     DCHECK_LT(index, header_->field_ids_size_);
1136     const dex::TypeId& type_id = dex_file_->GetTypeId(dex_file_->GetFieldId(index).type_idx_);
1137     const char* field_type_name =
1138         dex_file_->GetStringData(dex_file_->GetStringId(type_id.descriptor_idx_));
1139     Primitive::Type field_type = Primitive::GetType(field_type_name[0]);
1140     EncodedArrayValueIterator::ValueType array_type = array_it.GetValueType();
1141     // Ensure this matches RuntimeEncodedStaticFieldValueIterator.
1142     switch (array_type) {
1143       case EncodedArrayValueIterator::ValueType::kBoolean:
1144         if (field_type != Primitive::kPrimBoolean) {
1145           ErrorStringPrintf("unexpected static field initial value type: 'Z' vs '%c'",
1146                             field_type_name[0]);
1147           return false;
1148         }
1149         break;
1150       case EncodedArrayValueIterator::ValueType::kByte:
1151         if (field_type != Primitive::kPrimByte) {
1152           ErrorStringPrintf("unexpected static field initial value type: 'B' vs '%c'",
1153                             field_type_name[0]);
1154           return false;
1155         }
1156         break;
1157       case EncodedArrayValueIterator::ValueType::kShort:
1158         if (field_type != Primitive::kPrimShort) {
1159           ErrorStringPrintf("unexpected static field initial value type: 'S' vs '%c'",
1160                             field_type_name[0]);
1161           return false;
1162         }
1163         break;
1164       case EncodedArrayValueIterator::ValueType::kChar:
1165         if (field_type != Primitive::kPrimChar) {
1166           ErrorStringPrintf("unexpected static field initial value type: 'C' vs '%c'",
1167                             field_type_name[0]);
1168           return false;
1169         }
1170         break;
1171       case EncodedArrayValueIterator::ValueType::kInt:
1172         if (field_type != Primitive::kPrimInt) {
1173           ErrorStringPrintf("unexpected static field initial value type: 'I' vs '%c'",
1174                             field_type_name[0]);
1175           return false;
1176         }
1177         break;
1178       case EncodedArrayValueIterator::ValueType::kLong:
1179         if (field_type != Primitive::kPrimLong) {
1180           ErrorStringPrintf("unexpected static field initial value type: 'J' vs '%c'",
1181                             field_type_name[0]);
1182           return false;
1183         }
1184         break;
1185       case EncodedArrayValueIterator::ValueType::kFloat:
1186         if (field_type != Primitive::kPrimFloat) {
1187           ErrorStringPrintf("unexpected static field initial value type: 'F' vs '%c'",
1188                             field_type_name[0]);
1189           return false;
1190         }
1191         break;
1192       case EncodedArrayValueIterator::ValueType::kDouble:
1193         if (field_type != Primitive::kPrimDouble) {
1194           ErrorStringPrintf("unexpected static field initial value type: 'D' vs '%c'",
1195                             field_type_name[0]);
1196           return false;
1197         }
1198         break;
1199       case EncodedArrayValueIterator::ValueType::kNull:
1200       case EncodedArrayValueIterator::ValueType::kString:
1201       case EncodedArrayValueIterator::ValueType::kType:
1202         if (field_type != Primitive::kPrimNot) {
1203           ErrorStringPrintf("unexpected static field initial value type: 'L' vs '%c'",
1204                             field_type_name[0]);
1205           return false;
1206         }
1207         break;
1208       default:
1209         ErrorStringPrintf("unexpected static field initial value type: %x", array_type);
1210         return false;
1211     }
1212     array_it.Next();
1213   }
1214 
1215   if (array_it.HasNext()) {
1216     ErrorStringPrintf("too many static field initial values");
1217     return false;
1218   }
1219   return true;
1220 }
1221 
CheckIntraTypeIdItem()1222 bool DexFileVerifier::CheckIntraTypeIdItem() {
1223   if (!CheckListSize(ptr_, 1, sizeof(dex::TypeId), "type_ids")) {
1224     return false;
1225   }
1226 
1227   const dex::TypeId* type_id = reinterpret_cast<const dex::TypeId*>(ptr_);
1228   if (!CheckIndex(type_id->descriptor_idx_.index_,
1229                   header_->string_ids_size_,
1230                   "type_id.descriptor")) {
1231     return false;
1232   }
1233 
1234   ptr_ += sizeof(dex::TypeId);
1235   return true;
1236 }
1237 
CheckIntraProtoIdItem()1238 bool DexFileVerifier::CheckIntraProtoIdItem() {
1239   if (!CheckListSize(ptr_, 1, sizeof(dex::ProtoId), "proto_ids")) {
1240     return false;
1241   }
1242 
1243   const dex::ProtoId* proto_id = reinterpret_cast<const dex::ProtoId*>(ptr_);
1244   if (!CheckIndex(proto_id->shorty_idx_.index_, header_->string_ids_size_, "proto_id.shorty") ||
1245       !CheckIndex(proto_id->return_type_idx_.index_,
1246                   header_->type_ids_size_,
1247                   "proto_id.return_type")) {
1248     return false;
1249   }
1250 
1251   ptr_ += sizeof(dex::ProtoId);
1252   return true;
1253 }
1254 
CheckIntraFieldIdItem()1255 bool DexFileVerifier::CheckIntraFieldIdItem() {
1256   if (!CheckListSize(ptr_, 1, sizeof(dex::FieldId), "field_ids")) {
1257     return false;
1258   }
1259 
1260   const dex::FieldId* field_id = reinterpret_cast<const dex::FieldId*>(ptr_);
1261   if (!CheckIndex(field_id->class_idx_.index_, header_->type_ids_size_, "field_id.class") ||
1262       !CheckIndex(field_id->type_idx_.index_, header_->type_ids_size_, "field_id.type") ||
1263       !CheckIndex(field_id->name_idx_.index_, header_->string_ids_size_, "field_id.name")) {
1264     return false;
1265   }
1266 
1267   ptr_ += sizeof(dex::FieldId);
1268   return true;
1269 }
1270 
CheckIntraMethodIdItem()1271 bool DexFileVerifier::CheckIntraMethodIdItem() {
1272   if (!CheckListSize(ptr_, 1, sizeof(dex::MethodId), "method_ids")) {
1273     return false;
1274   }
1275 
1276   const dex::MethodId* method_id = reinterpret_cast<const dex::MethodId*>(ptr_);
1277   if (!CheckIndex(method_id->class_idx_.index_, header_->type_ids_size_, "method_id.class") ||
1278       !CheckIndex(method_id->proto_idx_.index_, header_->proto_ids_size_, "method_id.proto") ||
1279       !CheckIndex(method_id->name_idx_.index_, header_->string_ids_size_, "method_id.name")) {
1280     return false;
1281   }
1282 
1283   ptr_ += sizeof(dex::MethodId);
1284   return true;
1285 }
1286 
CheckIntraClassDefItem(uint32_t class_def_index)1287 bool DexFileVerifier::CheckIntraClassDefItem(uint32_t class_def_index) {
1288   if (!CheckListSize(ptr_, 1, sizeof(dex::ClassDef), "class_defs")) {
1289     return false;
1290   }
1291 
1292   const dex::ClassDef* class_def = reinterpret_cast<const dex::ClassDef*>(ptr_);
1293   if (!CheckIndex(class_def->class_idx_.index_, header_->type_ids_size_, "class_def.class")) {
1294     return false;
1295   }
1296 
1297   // Check superclass, if any.
1298   if (UNLIKELY(class_def->pad2_ != 0u)) {
1299     uint32_t combined =
1300         (static_cast<uint32_t>(class_def->pad2_) << 16) + class_def->superclass_idx_.index_;
1301     if (combined != 0xffffffffu) {
1302       ErrorStringPrintf("Invalid superclass type padding/index: %x", combined);
1303       return false;
1304     }
1305   } else if (!CheckIndex(class_def->superclass_idx_.index_,
1306                          header_->type_ids_size_,
1307                          "class_def.superclass")) {
1308     return false;
1309   }
1310 
1311   DCHECK_LE(class_def->class_idx_.index_, kTypeIdLimit);
1312   DCHECK_LT(kTypeIdLimit, defined_classes_.size());
1313   if (defined_classes_[class_def->class_idx_.index_]) {
1314     ErrorStringPrintf("Redefinition of class with type idx: '%u'", class_def->class_idx_.index_);
1315     return false;
1316   }
1317   defined_classes_[class_def->class_idx_.index_] = true;
1318   DCHECK_LE(class_def->class_idx_.index_, defined_class_indexes_.size());
1319   defined_class_indexes_[class_def->class_idx_.index_] = class_def_index;
1320 
1321   ptr_ += sizeof(dex::ClassDef);
1322   return true;
1323 }
1324 
CheckIntraMethodHandleItem()1325 bool DexFileVerifier::CheckIntraMethodHandleItem() {
1326   if (!CheckListSize(ptr_, 1, sizeof(dex::MethodHandleItem), "method_handles")) {
1327     return false;
1328   }
1329 
1330   const dex::MethodHandleItem* item = reinterpret_cast<const dex::MethodHandleItem*>(ptr_);
1331 
1332   DexFile::MethodHandleType method_handle_type =
1333       static_cast<DexFile::MethodHandleType>(item->method_handle_type_);
1334   if (method_handle_type > DexFile::MethodHandleType::kLast) {
1335     ErrorStringPrintf("Bad method handle type %x", item->method_handle_type_);
1336     return false;
1337   }
1338 
1339   uint32_t index = item->field_or_method_idx_;
1340   switch (method_handle_type) {
1341     case DexFile::MethodHandleType::kStaticPut:
1342     case DexFile::MethodHandleType::kStaticGet:
1343     case DexFile::MethodHandleType::kInstancePut:
1344     case DexFile::MethodHandleType::kInstanceGet:
1345       if (!CheckIndex(index, header_->field_ids_size_, "method_handle_item field_idx")) {
1346         return false;
1347       }
1348       break;
1349     case DexFile::MethodHandleType::kInvokeStatic:
1350     case DexFile::MethodHandleType::kInvokeInstance:
1351     case DexFile::MethodHandleType::kInvokeConstructor:
1352     case DexFile::MethodHandleType::kInvokeDirect:
1353     case DexFile::MethodHandleType::kInvokeInterface: {
1354       if (!CheckIndex(index, header_->method_ids_size_, "method_handle_item method_idx")) {
1355         return false;
1356       }
1357       break;
1358     }
1359   }
1360 
1361   ptr_ += sizeof(dex::MethodHandleItem);
1362   return true;
1363 }
1364 
CheckIntraTypeList()1365 bool DexFileVerifier::CheckIntraTypeList() {
1366   const dex::TypeList* type_list = reinterpret_cast<const dex::TypeList*>(ptr_);
1367   if (!CheckList(sizeof(dex::TypeItem), "type_list", &ptr_)) {
1368     return false;
1369   }
1370 
1371   for (uint32_t i = 0, size = type_list->Size(); i != size; ++i) {
1372     if (!CheckIndex(type_list->GetTypeItem(i).type_idx_.index_,
1373                     header_->type_ids_size_,
1374                     "type_list.type")) {
1375       return false;
1376     }
1377   }
1378 
1379   return true;
1380 }
1381 
1382 template <bool kStatic>
CheckIntraClassDataItemFields(size_t count)1383 bool DexFileVerifier::CheckIntraClassDataItemFields(size_t count) {
1384   constexpr const char* kTypeDescr = kStatic ? "static field" : "instance field";
1385 
1386   // We cannot use ClassAccessor::Field yet as it could read beyond the end of the data section.
1387   const uint8_t* ptr = ptr_;
1388   const uint8_t* data_end = begin_ + header_->data_off_ + header_->data_size_;
1389 
1390   uint32_t prev_index = 0;
1391   for (size_t i = 0; i != count; ++i) {
1392     uint32_t field_idx_diff, access_flags;
1393     if (UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &field_idx_diff)) ||
1394         UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &access_flags))) {
1395       ErrorStringPrintf("encoded_field read out of bounds");
1396       return false;
1397     }
1398     uint32_t curr_index = prev_index + field_idx_diff;
1399     // Check for overflow.
1400     if (!CheckIndex(curr_index, header_->field_ids_size_, "class_data_item field_idx")) {
1401       return false;
1402     }
1403     if (!CheckOrder(kTypeDescr, curr_index, prev_index)) {
1404       return false;
1405     }
1406     // Check that it falls into the right class-data list.
1407     bool is_static = (access_flags & kAccStatic) != 0;
1408     if (UNLIKELY(is_static != kStatic)) {
1409       ErrorStringPrintf("Static/instance field not in expected list");
1410       return false;
1411     }
1412 
1413     prev_index = curr_index;
1414   }
1415 
1416   ptr_ = ptr;
1417   return true;
1418 }
1419 
CheckIntraClassDataItemMethods(size_t num_methods,ClassAccessor::Method * direct_methods,size_t num_direct_methods)1420 bool DexFileVerifier::CheckIntraClassDataItemMethods(size_t num_methods,
1421                                                      ClassAccessor::Method* direct_methods,
1422                                                      size_t num_direct_methods) {
1423   DCHECK(num_direct_methods == 0u || direct_methods != nullptr);
1424   const char* kTypeDescr = (direct_methods == nullptr) ? "direct method" : "virtual method";
1425 
1426   // We cannot use ClassAccessor::Method yet as it could read beyond the end of the data section.
1427   const uint8_t* ptr = ptr_;
1428   const uint8_t* data_end = begin_ + header_->data_off_ + header_->data_size_;
1429 
1430   // Load the first direct method for the check below.
1431   size_t remaining_direct_methods = num_direct_methods;
1432   if (remaining_direct_methods != 0u) {
1433     DCHECK(direct_methods != nullptr);
1434     direct_methods->Read();
1435   }
1436 
1437   uint32_t prev_index = 0;
1438   for (size_t i = 0; i != num_methods; ++i) {
1439     uint32_t method_idx_diff, access_flags, code_off;
1440     if (UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &method_idx_diff)) ||
1441         UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &access_flags)) ||
1442         UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &code_off))) {
1443       ErrorStringPrintf("encoded_method read out of bounds");
1444       return false;
1445     }
1446     uint32_t curr_index = prev_index + method_idx_diff;
1447     // Check for overflow.
1448     if (!CheckIndex(curr_index, header_->method_ids_size_, "class_data_item method_idx")) {
1449       return false;
1450     }
1451     if (!CheckOrder(kTypeDescr, curr_index, prev_index)) {
1452       return false;
1453     }
1454 
1455     // For virtual methods, we cross reference the method index to make sure
1456     // it doesn't match any direct methods.
1457     if (remaining_direct_methods != 0) {
1458       // The direct methods are already known to be in ascending index order.
1459       // So just keep up with the current index.
1460       while (true) {
1461         const uint32_t direct_idx = direct_methods->GetIndex();
1462         if (direct_idx > curr_index) {
1463           break;
1464         }
1465         if (direct_idx == curr_index) {
1466           ErrorStringPrintf("Found virtual method with same index as direct method: %u",
1467                             curr_index);
1468           return false;
1469         }
1470         --remaining_direct_methods;
1471         if (remaining_direct_methods == 0u) {
1472           break;
1473         }
1474         direct_methods->Read();
1475       }
1476     }
1477 
1478     prev_index = curr_index;
1479   }
1480 
1481   ptr_ = ptr;
1482   return true;
1483 }
1484 
CheckIntraClassDataItem()1485 bool DexFileVerifier::CheckIntraClassDataItem() {
1486   // We cannot use ClassAccessor yet as it could read beyond the end of the data section.
1487   const uint8_t* ptr = ptr_;
1488   const uint8_t* data_end = begin_ + header_->data_off_ + header_->data_size_;
1489 
1490   uint32_t static_fields_size, instance_fields_size, direct_methods_size, virtual_methods_size;
1491   if (UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &static_fields_size)) ||
1492       UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &instance_fields_size)) ||
1493       UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &direct_methods_size)) ||
1494       UNLIKELY(!DecodeUnsignedLeb128Checked(&ptr, data_end, &virtual_methods_size))) {
1495     ErrorStringPrintf("class_data_item read out of bounds");
1496     return false;
1497   }
1498   ptr_ = ptr;
1499 
1500   // Check fields.
1501   if (!CheckIntraClassDataItemFields</*kStatic=*/ true>(static_fields_size)) {
1502     return false;
1503   }
1504   if (!CheckIntraClassDataItemFields</*kStatic=*/ false>(instance_fields_size)) {
1505     return false;
1506   }
1507 
1508   // Check methods.
1509   const uint8_t* direct_methods_ptr = ptr_;
1510   if (!CheckIntraClassDataItemMethods(direct_methods_size,
1511                                       /*direct_methods=*/ nullptr,
1512                                       /*num_direct_methods=*/ 0u)) {
1513     return false;
1514   }
1515   // Direct methods have been checked, so we can now use ClassAccessor::Method to read them again.
1516   ClassAccessor::Method direct_methods(*dex_file_, direct_methods_ptr);
1517   if (!CheckIntraClassDataItemMethods(virtual_methods_size, &direct_methods, direct_methods_size)) {
1518     return false;
1519   }
1520 
1521   return true;
1522 }
1523 
CheckIntraCodeItem()1524 bool DexFileVerifier::CheckIntraCodeItem() {
1525   const dex::CodeItem* code_item = reinterpret_cast<const dex::CodeItem*>(ptr_);
1526   if (!CheckListSize(code_item, 1, sizeof(dex::CodeItem), "code")) {
1527     return false;
1528   }
1529 
1530   CodeItemDataAccessor accessor(*dex_file_, code_item);
1531   if (UNLIKELY(accessor.InsSize() > accessor.RegistersSize())) {
1532     ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
1533                       accessor.InsSize(), accessor.RegistersSize());
1534     return false;
1535   }
1536 
1537   if (UNLIKELY(accessor.OutsSize() > 5 && accessor.OutsSize() > accessor.RegistersSize())) {
1538     /*
1539      * outs_size can be up to 5, even if registers_size is smaller, since the
1540      * short forms of method invocation allow repetitions of a register multiple
1541      * times within a single parameter list. However, longer parameter lists
1542      * need to be represented in-order in the register file.
1543      */
1544     ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
1545                       accessor.OutsSize(), accessor.RegistersSize());
1546     return false;
1547   }
1548 
1549   const uint16_t* insns = accessor.Insns();
1550   uint32_t insns_size = accessor.InsnsSizeInCodeUnits();
1551   if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
1552     return false;
1553   }
1554 
1555   // Grab the end of the insns if there are no try_items.
1556   uint32_t try_items_size = accessor.TriesSize();
1557   if (try_items_size == 0) {
1558     ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
1559     return true;
1560   }
1561 
1562   // try_items are 4-byte aligned. Verify the spacer is 0.
1563   if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
1564     ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
1565     return false;
1566   }
1567 
1568   const dex::TryItem* try_items = accessor.TryItems().begin();
1569   if (!CheckListSize(try_items, try_items_size, sizeof(dex::TryItem), "try_items size")) {
1570     return false;
1571   }
1572 
1573   ptr_ = accessor.GetCatchHandlerData();
1574   DECODE_UNSIGNED_CHECKED_FROM(ptr_, handlers_size);
1575 
1576   if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
1577     ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
1578     return false;
1579   }
1580 
1581   // Avoid an expensive allocation, if possible.
1582   std::unique_ptr<uint32_t[]> handler_offsets_uptr;
1583   uint32_t* handler_offsets;
1584   constexpr size_t kAllocaMaxSize = 1024;
1585   if (handlers_size < kAllocaMaxSize/sizeof(uint32_t)) {
1586     // Note: Clang does not specify alignment guarantees for alloca. So align by hand.
1587     handler_offsets =
1588         AlignUp(reinterpret_cast<uint32_t*>(alloca((handlers_size + 1) * sizeof(uint32_t))),
1589                 alignof(uint32_t[]));
1590   } else {
1591     handler_offsets_uptr.reset(new uint32_t[handlers_size]);
1592     handler_offsets = handler_offsets_uptr.get();
1593   }
1594 
1595   if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
1596     return false;
1597   }
1598 
1599   uint32_t last_addr = 0;
1600   for (; try_items_size != 0u; --try_items_size) {
1601     if (UNLIKELY(try_items->start_addr_ < last_addr)) {
1602       ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
1603       return false;
1604     }
1605 
1606     if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
1607       ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
1608       return false;
1609     }
1610 
1611     uint32_t i;
1612     for (i = 0; i < handlers_size; i++) {
1613       if (try_items->handler_off_ == handler_offsets[i]) {
1614         break;
1615       }
1616     }
1617 
1618     if (UNLIKELY(i == handlers_size)) {
1619       ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
1620       return false;
1621     }
1622 
1623     last_addr = try_items->start_addr_ + try_items->insn_count_;
1624     if (UNLIKELY(last_addr > insns_size)) {
1625       ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
1626       return false;
1627     }
1628 
1629     try_items++;
1630   }
1631 
1632   return true;
1633 }
1634 
CheckIntraStringDataItem()1635 bool DexFileVerifier::CheckIntraStringDataItem() {
1636   DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
1637   const uint8_t* file_end = begin_ + size_;
1638 
1639   for (uint32_t i = 0; i < size; i++) {
1640     CHECK_LT(i, size);  // b/15014252 Prevents hitting the impossible case below
1641     if (UNLIKELY(ptr_ >= file_end)) {
1642       ErrorStringPrintf("String data would go beyond end-of-file");
1643       return false;
1644     }
1645 
1646     uint8_t byte = *(ptr_++);
1647 
1648     // Switch on the high 4 bits.
1649     switch (byte >> 4) {
1650       case 0x00:
1651         // Special case of bit pattern 0xxx.
1652         if (UNLIKELY(byte == 0)) {
1653           CHECK_LT(i, size);  // b/15014252 Actually hit this impossible case with clang
1654           ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
1655           return false;
1656         }
1657         break;
1658       case 0x01:
1659       case 0x02:
1660       case 0x03:
1661       case 0x04:
1662       case 0x05:
1663       case 0x06:
1664       case 0x07:
1665         // No extra checks necessary for bit pattern 0xxx.
1666         break;
1667       case 0x08:
1668       case 0x09:
1669       case 0x0a:
1670       case 0x0b:
1671       case 0x0f:
1672         // Illegal bit patterns 10xx or 1111.
1673         // Note: 1111 is valid for normal UTF-8, but not here.
1674         ErrorStringPrintf("Illegal start byte %x in string data", byte);
1675         return false;
1676       case 0x0c:
1677       case 0x0d: {
1678         // Bit pattern 110x has an additional byte.
1679         uint8_t byte2 = *(ptr_++);
1680         if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1681           ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
1682           return false;
1683         }
1684         uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
1685         if (UNLIKELY((value != 0) && (value < 0x80))) {
1686           ErrorStringPrintf("Illegal representation for value %x in string data", value);
1687           return false;
1688         }
1689         break;
1690       }
1691       case 0x0e: {
1692         // Bit pattern 1110 has 2 additional bytes.
1693         uint8_t byte2 = *(ptr_++);
1694         if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1695           ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
1696           return false;
1697         }
1698         uint8_t byte3 = *(ptr_++);
1699         if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
1700           ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
1701           return false;
1702         }
1703         uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
1704         if (UNLIKELY(value < 0x800)) {
1705           ErrorStringPrintf("Illegal representation for value %x in string data", value);
1706           return false;
1707         }
1708         break;
1709       }
1710     }
1711   }
1712 
1713   if (UNLIKELY(*(ptr_++) != '\0')) {
1714     ErrorStringPrintf("String longer than indicated size %x", size);
1715     return false;
1716   }
1717 
1718   return true;
1719 }
1720 
CheckIntraDebugInfoItem()1721 bool DexFileVerifier::CheckIntraDebugInfoItem() {
1722   DECODE_UNSIGNED_CHECKED_FROM(ptr_, unused_line_start);
1723   DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameters_size);
1724   if (UNLIKELY(parameters_size > 65536)) {
1725     ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
1726     return false;
1727   }
1728 
1729   for (uint32_t j = 0; j < parameters_size; j++) {
1730     DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameter_name);
1731     if (parameter_name != 0) {
1732       parameter_name--;
1733       if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
1734         return false;
1735       }
1736     }
1737   }
1738 
1739   while (true) {
1740     uint8_t opcode = *(ptr_++);
1741     switch (opcode) {
1742       case DexFile::DBG_END_SEQUENCE: {
1743         return true;
1744       }
1745       case DexFile::DBG_ADVANCE_PC: {
1746         DECODE_UNSIGNED_CHECKED_FROM(ptr_, unused_advance_pc);
1747         break;
1748       }
1749       case DexFile::DBG_ADVANCE_LINE: {
1750         DECODE_SIGNED_CHECKED_FROM(ptr_, unused_advance_line);
1751         break;
1752       }
1753       case DexFile::DBG_START_LOCAL: {
1754         DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1755         if (UNLIKELY(reg_num >= 65536)) {
1756           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1757           return false;
1758         }
1759         DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1760         if (name_idx != 0) {
1761           name_idx--;
1762           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
1763             return false;
1764           }
1765         }
1766         DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
1767         if (type_idx != 0) {
1768           type_idx--;
1769           if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL type_idx")) {
1770             return false;
1771           }
1772         }
1773         break;
1774       }
1775       case DexFile::DBG_END_LOCAL:
1776       case DexFile::DBG_RESTART_LOCAL: {
1777         DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1778         if (UNLIKELY(reg_num >= 65536)) {
1779           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1780           return false;
1781         }
1782         break;
1783       }
1784       case DexFile::DBG_START_LOCAL_EXTENDED: {
1785         DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1786         if (UNLIKELY(reg_num >= 65536)) {
1787           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1788           return false;
1789         }
1790         DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1791         if (name_idx != 0) {
1792           name_idx--;
1793           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
1794             return false;
1795           }
1796         }
1797         DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
1798         if (type_idx != 0) {
1799           type_idx--;
1800           if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
1801             return false;
1802           }
1803         }
1804         DECODE_UNSIGNED_CHECKED_FROM(ptr_, sig_idx);
1805         if (sig_idx != 0) {
1806           sig_idx--;
1807           if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
1808             return false;
1809           }
1810         }
1811         break;
1812       }
1813       case DexFile::DBG_SET_FILE: {
1814         DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1815         if (name_idx != 0) {
1816           name_idx--;
1817           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
1818             return false;
1819           }
1820         }
1821         break;
1822       }
1823     }
1824   }
1825 }
1826 
CheckIntraAnnotationItem()1827 bool DexFileVerifier::CheckIntraAnnotationItem() {
1828   if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "annotation visibility")) {
1829     return false;
1830   }
1831 
1832   // Check visibility
1833   switch (*(ptr_++)) {
1834     case DexFile::kDexVisibilityBuild:
1835     case DexFile::kDexVisibilityRuntime:
1836     case DexFile::kDexVisibilitySystem:
1837       break;
1838     default:
1839       ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
1840       return false;
1841   }
1842 
1843   if (!CheckEncodedAnnotation()) {
1844     return false;
1845   }
1846 
1847   return true;
1848 }
1849 
CheckIntraHiddenapiClassData()1850 bool DexFileVerifier::CheckIntraHiddenapiClassData() {
1851   const dex::HiddenapiClassData* item = reinterpret_cast<const dex::HiddenapiClassData*>(ptr_);
1852 
1853   // Check expected header size.
1854   uint32_t num_header_elems = dex_file_->NumClassDefs() + 1;
1855   uint32_t elem_size = sizeof(uint32_t);
1856   uint32_t header_size = num_header_elems * elem_size;
1857   if (!CheckListSize(item, num_header_elems, elem_size, "hiddenapi class data section header")) {
1858     return false;
1859   }
1860 
1861   // Check total size.
1862   if (!CheckListSize(item, item->size_, 1u, "hiddenapi class data section")) {
1863     return false;
1864   }
1865 
1866   // Check that total size can fit header.
1867   if (item->size_ < header_size) {
1868     ErrorStringPrintf(
1869         "Hiddenapi class data too short to store header (%u < %u)", item->size_, header_size);
1870     return false;
1871   }
1872 
1873   const uint8_t* data_end = ptr_ + item->size_;
1874   ptr_ += header_size;
1875 
1876   // Check offsets for each class def.
1877   for (uint32_t i = 0; i < dex_file_->NumClassDefs(); ++i) {
1878     const dex::ClassDef& class_def = dex_file_->GetClassDef(i);
1879     const uint8_t* class_data = dex_file_->GetClassData(class_def);
1880     uint32_t offset = item->flags_offset_[i];
1881 
1882     if (offset == 0) {
1883       continue;
1884     }
1885 
1886     // Check that class defs with no class data do not have any hiddenapi class data.
1887     if (class_data == nullptr) {
1888       ErrorStringPrintf(
1889           "Hiddenapi class data offset not zero for class def %u with no class data", i);
1890       return false;
1891     }
1892 
1893     // Check that the offset is within the section.
1894     if (offset > item->size_) {
1895       ErrorStringPrintf(
1896           "Hiddenapi class data offset out of section bounds (%u > %u) for class def %u",
1897           offset, item->size_, i);
1898       return false;
1899     }
1900 
1901     // Check that the offset matches current pointer position. We do not allow
1902     // offsets into already parsed data, or gaps between class def data.
1903     uint32_t ptr_offset = ptr_ - reinterpret_cast<const uint8_t*>(item);
1904     if (offset != ptr_offset) {
1905       ErrorStringPrintf(
1906           "Hiddenapi class data unexpected offset (%u != %u) for class def %u",
1907           offset, ptr_offset, i);
1908       return false;
1909     }
1910 
1911     // Parse a uleb128 value for each field and method of this class.
1912     bool failure = false;
1913     auto fn_member = [&](const ClassAccessor::BaseItem& member, const char* member_type) {
1914       if (failure) {
1915         return;
1916       }
1917       uint32_t decoded_flags;
1918       if (!DecodeUnsignedLeb128Checked(&ptr_, data_end, &decoded_flags)) {
1919         ErrorStringPrintf("Hiddenapi class data value out of bounds (%p > %p) for %s %i",
1920                           ptr_, data_end, member_type, member.GetIndex());
1921         failure = true;
1922         return;
1923       }
1924       if (!hiddenapi::ApiList(decoded_flags).IsValid()) {
1925         ErrorStringPrintf("Hiddenapi class data flags invalid (%u) for %s %i",
1926                           decoded_flags, member_type, member.GetIndex());
1927         failure = true;
1928         return;
1929       }
1930     };
1931     auto fn_field = [&](const ClassAccessor::Field& field) { fn_member(field, "field"); };
1932     auto fn_method = [&](const ClassAccessor::Method& method) { fn_member(method, "method"); };
1933     ClassAccessor accessor(*dex_file_, class_data);
1934     accessor.VisitFieldsAndMethods(fn_field, fn_field, fn_method, fn_method);
1935     if (failure) {
1936       return false;
1937     }
1938   }
1939 
1940   if (ptr_ != data_end) {
1941     ErrorStringPrintf("Hiddenapi class data wrong reported size (%u != %u)",
1942                        static_cast<uint32_t>(ptr_ - reinterpret_cast<const uint8_t*>(item)),
1943                        item->size_);
1944     return false;
1945   }
1946 
1947   return true;
1948 }
1949 
CheckIntraAnnotationsDirectoryItem()1950 bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1951   const dex::AnnotationsDirectoryItem* item =
1952       reinterpret_cast<const dex::AnnotationsDirectoryItem*>(ptr_);
1953   if (!CheckListSize(item, 1, sizeof(dex::AnnotationsDirectoryItem), "annotations_directory")) {
1954     return false;
1955   }
1956 
1957   // Field annotations follow immediately after the annotations directory.
1958   const dex::FieldAnnotationsItem* field_item =
1959       reinterpret_cast<const dex::FieldAnnotationsItem*>(item + 1);
1960   uint32_t field_count = item->fields_size_;
1961   if (!CheckListSize(field_item,
1962                      field_count,
1963                      sizeof(dex::FieldAnnotationsItem),
1964                      "field_annotations list")) {
1965     return false;
1966   }
1967 
1968   uint32_t last_idx = 0;
1969   for (uint32_t i = 0; i < field_count; i++) {
1970     if (!CheckIndex(field_item->field_idx_, header_->field_ids_size_, "field annotation")) {
1971       return false;
1972     }
1973     if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1974       ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x",
1975                         last_idx, field_item->field_idx_);
1976       return false;
1977     }
1978     last_idx = field_item->field_idx_;
1979     field_item++;
1980   }
1981 
1982   // Method annotations follow immediately after field annotations.
1983   const dex::MethodAnnotationsItem* method_item =
1984       reinterpret_cast<const dex::MethodAnnotationsItem*>(field_item);
1985   uint32_t method_count = item->methods_size_;
1986   if (!CheckListSize(method_item,
1987                      method_count,
1988                      sizeof(dex::MethodAnnotationsItem),
1989                      "method_annotations list")) {
1990     return false;
1991   }
1992 
1993   last_idx = 0;
1994   for (uint32_t i = 0; i < method_count; i++) {
1995     if (!CheckIndex(method_item->method_idx_, header_->method_ids_size_, "method annotation")) {
1996       return false;
1997     }
1998     if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1999       ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
2000                        last_idx, method_item->method_idx_);
2001       return false;
2002     }
2003     last_idx = method_item->method_idx_;
2004     method_item++;
2005   }
2006 
2007   // Parameter annotations follow immediately after method annotations.
2008   const dex::ParameterAnnotationsItem* parameter_item =
2009       reinterpret_cast<const dex::ParameterAnnotationsItem*>(method_item);
2010   uint32_t parameter_count = item->parameters_size_;
2011   if (!CheckListSize(parameter_item, parameter_count, sizeof(dex::ParameterAnnotationsItem),
2012                      "parameter_annotations list")) {
2013     return false;
2014   }
2015 
2016   last_idx = 0;
2017   for (uint32_t i = 0; i < parameter_count; i++) {
2018     if (!CheckIndex(parameter_item->method_idx_,
2019                     header_->method_ids_size_,
2020                     "parameter annotation method")) {
2021       return false;
2022     }
2023     if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
2024       ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
2025                         last_idx, parameter_item->method_idx_);
2026       return false;
2027     }
2028     last_idx = parameter_item->method_idx_;
2029     parameter_item++;
2030   }
2031 
2032   // Return a pointer to the end of the annotations.
2033   ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
2034   return true;
2035 }
2036 
2037 template <DexFile::MapItemType kType>
CheckIntraSectionIterate(size_t offset,uint32_t section_count)2038 bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count) {
2039   // Get the right alignment mask for the type of section.
2040   size_t alignment_mask;
2041   switch (kType) {
2042     case DexFile::kDexTypeClassDataItem:
2043     case DexFile::kDexTypeStringDataItem:
2044     case DexFile::kDexTypeDebugInfoItem:
2045     case DexFile::kDexTypeAnnotationItem:
2046     case DexFile::kDexTypeEncodedArrayItem:
2047       alignment_mask = sizeof(uint8_t) - 1;
2048       break;
2049     default:
2050       alignment_mask = sizeof(uint32_t) - 1;
2051       break;
2052   }
2053 
2054   // Iterate through the items in the section.
2055   for (uint32_t i = 0; i < section_count; i++) {
2056     size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
2057 
2058     // Check the padding between items.
2059     if (!CheckPadding(offset, aligned_offset, kType)) {
2060       return false;
2061     }
2062 
2063     // Check depending on the section type.
2064     const uint8_t* start_ptr = ptr_;
2065     switch (kType) {
2066       case DexFile::kDexTypeStringIdItem: {
2067         if (!CheckListSize(ptr_, 1, sizeof(dex::StringId), "string_ids")) {
2068           return false;
2069         }
2070         ptr_ += sizeof(dex::StringId);
2071         break;
2072       }
2073       case DexFile::kDexTypeTypeIdItem: {
2074         if (!CheckIntraTypeIdItem()) {
2075           return false;
2076         }
2077         break;
2078       }
2079       case DexFile::kDexTypeProtoIdItem: {
2080         if (!CheckIntraProtoIdItem()) {
2081           return false;
2082         }
2083         break;
2084       }
2085       case DexFile::kDexTypeFieldIdItem: {
2086         if (!CheckIntraFieldIdItem()) {
2087           return false;
2088         }
2089         break;
2090       }
2091       case DexFile::kDexTypeMethodIdItem: {
2092         if (!CheckIntraMethodIdItem()) {
2093           return false;
2094         }
2095         break;
2096       }
2097       case DexFile::kDexTypeClassDefItem: {
2098         if (!CheckIntraClassDefItem(/*class_def_index=*/ i)) {
2099           return false;
2100         }
2101         break;
2102       }
2103       case DexFile::kDexTypeCallSiteIdItem: {
2104         if (!CheckListSize(ptr_, 1, sizeof(dex::CallSiteIdItem), "call_site_ids")) {
2105           return false;
2106         }
2107         ptr_ += sizeof(dex::CallSiteIdItem);
2108         break;
2109       }
2110       case DexFile::kDexTypeMethodHandleItem: {
2111         if (!CheckIntraMethodHandleItem()) {
2112           return false;
2113         }
2114         break;
2115       }
2116       case DexFile::kDexTypeTypeList: {
2117         if (!CheckIntraTypeList()) {
2118           return false;
2119         }
2120         break;
2121       }
2122       case DexFile::kDexTypeAnnotationSetRefList: {
2123         if (!CheckList(sizeof(dex::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
2124           return false;
2125         }
2126         break;
2127       }
2128       case DexFile::kDexTypeAnnotationSetItem: {
2129         if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
2130           return false;
2131         }
2132         break;
2133       }
2134       case DexFile::kDexTypeClassDataItem: {
2135         if (!CheckIntraClassDataItem()) {
2136           return false;
2137         }
2138         break;
2139       }
2140       case DexFile::kDexTypeCodeItem: {
2141         if (!CheckIntraCodeItem()) {
2142           return false;
2143         }
2144         break;
2145       }
2146       case DexFile::kDexTypeStringDataItem: {
2147         if (!CheckIntraStringDataItem()) {
2148           return false;
2149         }
2150         break;
2151       }
2152       case DexFile::kDexTypeDebugInfoItem: {
2153         if (!CheckIntraDebugInfoItem()) {
2154           return false;
2155         }
2156         break;
2157       }
2158       case DexFile::kDexTypeAnnotationItem: {
2159         if (!CheckIntraAnnotationItem()) {
2160           return false;
2161         }
2162         break;
2163       }
2164       case DexFile::kDexTypeEncodedArrayItem: {
2165         if (!CheckEncodedArray()) {
2166           return false;
2167         }
2168         break;
2169       }
2170       case DexFile::kDexTypeAnnotationsDirectoryItem: {
2171         if (!CheckIntraAnnotationsDirectoryItem()) {
2172           return false;
2173         }
2174         break;
2175       }
2176       case DexFile::kDexTypeHiddenapiClassData: {
2177         if (!CheckIntraHiddenapiClassData()) {
2178           return false;
2179         }
2180         break;
2181       }
2182       case DexFile::kDexTypeHeaderItem:
2183       case DexFile::kDexTypeMapList:
2184         break;
2185     }
2186 
2187     if (start_ptr == ptr_) {
2188       ErrorStringPrintf("Unknown map item type %x", kType);
2189       return false;
2190     }
2191 
2192     if (IsDataSectionType(kType)) {
2193       if (aligned_offset == 0u) {
2194         ErrorStringPrintf("Item %d offset is 0", i);
2195         return false;
2196       }
2197       DCHECK(offset_to_type_map_.find(aligned_offset) == offset_to_type_map_.end());
2198       offset_to_type_map_.insert(std::pair<uint32_t, uint16_t>(aligned_offset, kType));
2199     }
2200 
2201     aligned_offset = ptr_ - begin_;
2202     if (UNLIKELY(aligned_offset > size_)) {
2203       ErrorStringPrintf("Item %d at ends out of bounds", i);
2204       return false;
2205     }
2206 
2207     offset = aligned_offset;
2208   }
2209 
2210   return true;
2211 }
2212 
2213 template <DexFile::MapItemType kType>
CheckIntraIdSection(size_t offset,uint32_t count)2214 bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count) {
2215   uint32_t expected_offset;
2216   uint32_t expected_size;
2217 
2218   // Get the expected offset and size from the header.
2219   switch (kType) {
2220     case DexFile::kDexTypeStringIdItem:
2221       expected_offset = header_->string_ids_off_;
2222       expected_size = header_->string_ids_size_;
2223       break;
2224     case DexFile::kDexTypeTypeIdItem:
2225       expected_offset = header_->type_ids_off_;
2226       expected_size = header_->type_ids_size_;
2227       break;
2228     case DexFile::kDexTypeProtoIdItem:
2229       expected_offset = header_->proto_ids_off_;
2230       expected_size = header_->proto_ids_size_;
2231       break;
2232     case DexFile::kDexTypeFieldIdItem:
2233       expected_offset = header_->field_ids_off_;
2234       expected_size = header_->field_ids_size_;
2235       break;
2236     case DexFile::kDexTypeMethodIdItem:
2237       expected_offset = header_->method_ids_off_;
2238       expected_size = header_->method_ids_size_;
2239       break;
2240     case DexFile::kDexTypeClassDefItem:
2241       expected_offset = header_->class_defs_off_;
2242       expected_size = header_->class_defs_size_;
2243       break;
2244     default:
2245       ErrorStringPrintf("Bad type for id section: %x", kType);
2246       return false;
2247   }
2248 
2249   // Check that the offset and size are what were expected from the header.
2250   if (UNLIKELY(offset != expected_offset)) {
2251     ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
2252     return false;
2253   }
2254   if (UNLIKELY(count != expected_size)) {
2255     ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
2256     return false;
2257   }
2258 
2259   return CheckIntraSectionIterate<kType>(offset, count);
2260 }
2261 
2262 template <DexFile::MapItemType kType>
CheckIntraDataSection(size_t offset,uint32_t count)2263 bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count) {
2264   size_t data_start = header_->data_off_;
2265   size_t data_end = data_start + header_->data_size_;
2266 
2267   // Check the validity of the offset of the section.
2268   if (UNLIKELY((offset < data_start) || (offset > data_end))) {
2269     ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
2270     return false;
2271   }
2272 
2273   if (!CheckIntraSectionIterate<kType>(offset, count)) {
2274     return false;
2275   }
2276 
2277   // FIXME: Doing this check late means we may have already read memory outside the
2278   // data section and potentially outside the file, thus risking a segmentation fault.
2279   size_t next_offset = ptr_ - begin_;
2280   if (next_offset > data_end) {
2281     ErrorStringPrintf("Out-of-bounds end of data subsection: %zu data_off=%u data_size=%u",
2282                       next_offset,
2283                       header_->data_off_,
2284                       header_->data_size_);
2285     return false;
2286   }
2287 
2288   return true;
2289 }
2290 
CheckIntraSection()2291 bool DexFileVerifier::CheckIntraSection() {
2292   const dex::MapList* map = reinterpret_cast<const dex::MapList*>(begin_ + header_->map_off_);
2293   const dex::MapItem* item = map->list_;
2294   size_t offset = 0;
2295   uint32_t count = map->size_;
2296   ptr_ = begin_;
2297 
2298   // Preallocate offset map to avoid some allocations. We can only guess from the list items,
2299   // not derived things.
2300   offset_to_type_map_.reserve(
2301       std::min(header_->class_defs_size_, 65535u) +
2302       std::min(header_->string_ids_size_, 65535u) +
2303       2 * std::min(header_->method_ids_size_, 65535u));
2304 
2305   // Check the items listed in the map.
2306   for (; count != 0u; --count) {
2307     const size_t current_offset = offset;
2308     uint32_t section_offset = item->offset_;
2309     uint32_t section_count = item->size_;
2310     DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
2311 
2312     // Check for padding and overlap between items.
2313     if (!CheckPadding(offset, section_offset, type)) {
2314       return false;
2315     } else if (UNLIKELY(offset > section_offset)) {
2316       ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
2317       return false;
2318     }
2319 
2320     if (type == DexFile::kDexTypeClassDataItem) {
2321       FindStringRangesForMethodNames();
2322     }
2323 
2324     // Check each item based on its type.
2325     switch (type) {
2326       case DexFile::kDexTypeHeaderItem:
2327         if (UNLIKELY(section_count != 1)) {
2328           ErrorStringPrintf("Multiple header items");
2329           return false;
2330         }
2331         if (UNLIKELY(section_offset != 0)) {
2332           ErrorStringPrintf("Header at %x, not at start of file", section_offset);
2333           return false;
2334         }
2335         ptr_ = begin_ + header_->header_size_;
2336         offset = header_->header_size_;
2337         break;
2338 
2339 #define CHECK_INTRA_ID_SECTION_CASE(type)                                   \
2340       case type:                                                            \
2341         if (!CheckIntraIdSection<type>(section_offset, section_count)) {    \
2342           return false;                                                     \
2343         }                                                                   \
2344         offset = ptr_ - begin_;                                             \
2345         break;
2346       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeStringIdItem)
2347       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeTypeIdItem)
2348       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeProtoIdItem)
2349       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeFieldIdItem)
2350       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeMethodIdItem)
2351       CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeClassDefItem)
2352 #undef CHECK_INTRA_ID_SECTION_CASE
2353 
2354       case DexFile::kDexTypeMapList:
2355         if (UNLIKELY(section_count != 1)) {
2356           ErrorStringPrintf("Multiple map list items");
2357           return false;
2358         }
2359         if (UNLIKELY(section_offset != header_->map_off_)) {
2360           ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
2361                             section_offset, header_->map_off_);
2362           return false;
2363         }
2364         ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(dex::MapItem));
2365         offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(dex::MapItem));
2366         break;
2367 
2368 #define CHECK_INTRA_SECTION_ITERATE_CASE(type)                                 \
2369       case type:                                                               \
2370         if (!CheckIntraSectionIterate<type>(section_offset, section_count)) {  \
2371           return false;                                                        \
2372         }                                                                      \
2373         offset = ptr_ - begin_;                                                \
2374         break;
2375       CHECK_INTRA_SECTION_ITERATE_CASE(DexFile::kDexTypeMethodHandleItem)
2376       CHECK_INTRA_SECTION_ITERATE_CASE(DexFile::kDexTypeCallSiteIdItem)
2377 #undef CHECK_INTRA_SECTION_ITERATE_CASE
2378 
2379 #define CHECK_INTRA_DATA_SECTION_CASE(type)                                 \
2380       case type:                                                            \
2381         if (!CheckIntraDataSection<type>(section_offset, section_count)) {  \
2382           return false;                                                     \
2383         }                                                                   \
2384         offset = ptr_ - begin_;                                             \
2385         break;
2386       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeTypeList)
2387       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationSetRefList)
2388       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationSetItem)
2389       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeClassDataItem)
2390       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeCodeItem)
2391       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeStringDataItem)
2392       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeDebugInfoItem)
2393       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationItem)
2394       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeEncodedArrayItem)
2395       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationsDirectoryItem)
2396       CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeHiddenapiClassData)
2397 #undef CHECK_INTRA_DATA_SECTION_CASE
2398     }
2399 
2400     if (offset == current_offset) {
2401         ErrorStringPrintf("Unknown map item type %x", type);
2402         return false;
2403     }
2404 
2405     item++;
2406   }
2407 
2408   return true;
2409 }
2410 
CheckOffsetToTypeMap(size_t offset,uint16_t type)2411 bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
2412   DCHECK_NE(offset, 0u);
2413   auto it = offset_to_type_map_.find(offset);
2414   if (UNLIKELY(it == offset_to_type_map_.end())) {
2415     ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
2416     return false;
2417   }
2418   if (UNLIKELY(it->second != type)) {
2419     ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
2420                       offset, type, it->second);
2421     return false;
2422   }
2423   return true;
2424 }
2425 
FindFirstClassDataDefiner(const ClassAccessor & accessor)2426 uint32_t DexFileVerifier::FindFirstClassDataDefiner(const ClassAccessor& accessor) {
2427   // The data item and field/method indexes have already been checked in
2428   // `CheckIntraClassDataItem()` or its helper functions.
2429   if (accessor.NumFields() != 0) {
2430     ClassAccessor::Field read_field(*dex_file_, accessor.ptr_pos_);
2431     read_field.Read();
2432     DCHECK_LE(read_field.GetIndex(), dex_file_->NumFieldIds());
2433     return dex_file_->GetFieldId(read_field.GetIndex()).class_idx_.index_;
2434   }
2435 
2436   if (accessor.NumMethods() != 0) {
2437     ClassAccessor::Method read_method(*dex_file_, accessor.ptr_pos_);
2438     read_method.Read();
2439     DCHECK_LE(read_method.GetIndex(), dex_file_->NumMethodIds());
2440     return dex_file_->GetMethodId(read_method.GetIndex()).class_idx_.index_;
2441   }
2442 
2443   return kDexNoIndex;
2444 }
2445 
FindFirstAnnotationsDirectoryDefiner(const uint8_t * ptr)2446 uint32_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr) {
2447   // The annotations directory and field/method indexes have already been checked in
2448   // `CheckIntraAnnotationsDirectoryItem()`.
2449   const dex::AnnotationsDirectoryItem* item =
2450       reinterpret_cast<const dex::AnnotationsDirectoryItem*>(ptr);
2451 
2452   if (item->fields_size_ != 0) {
2453     dex::FieldAnnotationsItem* field_items = (dex::FieldAnnotationsItem*) (item + 1);
2454     DCHECK_LE(field_items[0].field_idx_, dex_file_->NumFieldIds());
2455     return dex_file_->GetFieldId(field_items[0].field_idx_).class_idx_.index_;
2456   }
2457 
2458   if (item->methods_size_ != 0) {
2459     dex::MethodAnnotationsItem* method_items = (dex::MethodAnnotationsItem*) (item + 1);
2460     DCHECK_LE(method_items[0].method_idx_, dex_file_->NumMethodIds());
2461     return dex_file_->GetMethodId(method_items[0].method_idx_).class_idx_.index_;
2462   }
2463 
2464   if (item->parameters_size_ != 0) {
2465     dex::ParameterAnnotationsItem* parameter_items = (dex::ParameterAnnotationsItem*) (item + 1);
2466     DCHECK_LE(parameter_items[0].method_idx_, dex_file_->NumMethodIds());
2467     return dex_file_->GetMethodId(parameter_items[0].method_idx_).class_idx_.index_;
2468   }
2469 
2470   return kDexNoIndex;
2471 }
2472 
CheckInterStringIdItem()2473 bool DexFileVerifier::CheckInterStringIdItem() {
2474   const dex::StringId* item = reinterpret_cast<const dex::StringId*>(ptr_);
2475 
2476   // Note: The mapping to string data items is eagerly verified at the start of CheckInterSection().
2477 
2478   // Check ordering between items.
2479   if (previous_item_ != nullptr) {
2480     const dex::StringId* prev_item = reinterpret_cast<const dex::StringId*>(previous_item_);
2481     const char* prev_str = dex_file_->GetStringData(*prev_item);
2482     const char* str = dex_file_->GetStringData(*item);
2483     if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
2484       ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
2485       return false;
2486     }
2487   }
2488 
2489   ptr_ += sizeof(dex::StringId);
2490   return true;
2491 }
2492 
CheckInterTypeIdItem()2493 bool DexFileVerifier::CheckInterTypeIdItem() {
2494   const dex::TypeId* item = reinterpret_cast<const dex::TypeId*>(ptr_);
2495 
2496   {
2497     // Translate to index to potentially use cache.
2498     // The check in `CheckIntraIdSection()` guarantees that this index is valid.
2499     size_t index = item - reinterpret_cast<const dex::TypeId*>(begin_ + header_->type_ids_off_);
2500     DCHECK_LE(index, header_->type_ids_size_);
2501     if (UNLIKELY(!VerifyTypeDescriptor(
2502         dex::TypeIndex(static_cast<decltype(dex::TypeIndex::index_)>(index)),
2503         "Invalid type descriptor",
2504         [](char) { return true; }))) {
2505       return false;
2506     }
2507   }
2508 
2509   // Check ordering between items.
2510   if (previous_item_ != nullptr) {
2511     const dex::TypeId* prev_item = reinterpret_cast<const dex::TypeId*>(previous_item_);
2512     if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
2513       ErrorStringPrintf("Out-of-order type_ids: %x then %x",
2514                         prev_item->descriptor_idx_.index_,
2515                         item->descriptor_idx_.index_);
2516       return false;
2517     }
2518   }
2519 
2520   ptr_ += sizeof(dex::TypeId);
2521   return true;
2522 }
2523 
CheckInterProtoIdItem()2524 bool DexFileVerifier::CheckInterProtoIdItem() {
2525   const dex::ProtoId* item = reinterpret_cast<const dex::ProtoId*>(ptr_);
2526 
2527   const char* shorty = dex_file_->StringDataByIdx(item->shorty_idx_);
2528 
2529   if (item->parameters_off_ != 0 &&
2530       !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
2531     return false;
2532   }
2533 
2534   // Check that return type is representable as a uint16_t;
2535   if (UNLIKELY(!IsValidOrNoTypeId(item->return_type_idx_.index_, item->pad_))) {
2536     ErrorStringPrintf("proto with return type idx outside uint16_t range '%x:%x'",
2537                       item->pad_, item->return_type_idx_.index_);
2538     return false;
2539   }
2540   // Check the return type and advance the shorty.
2541   const char* return_type = dex_file_->StringByTypeIdx(item->return_type_idx_);
2542   if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
2543     return false;
2544   }
2545   shorty++;
2546 
2547   DexFileParameterIterator it(*dex_file_, *item);
2548   while (it.HasNext() && *shorty != '\0') {
2549     if (!CheckIndex(it.GetTypeIdx().index_,
2550                     dex_file_->NumTypeIds(),
2551                     "inter_proto_id_item shorty type_idx")) {
2552       return false;
2553     }
2554     const char* descriptor = it.GetDescriptor();
2555     if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
2556       return false;
2557     }
2558     it.Next();
2559     shorty++;
2560   }
2561   if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
2562     ErrorStringPrintf("Mismatched length for parameters and shorty");
2563     return false;
2564   }
2565 
2566   // Check ordering between items. This relies on type_ids being in order.
2567   if (previous_item_ != nullptr) {
2568     const dex::ProtoId* prev = reinterpret_cast<const dex::ProtoId*>(previous_item_);
2569     if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
2570       ErrorStringPrintf("Out-of-order proto_id return types");
2571       return false;
2572     } else if (prev->return_type_idx_ == item->return_type_idx_) {
2573       DexFileParameterIterator curr_it(*dex_file_, *item);
2574       DexFileParameterIterator prev_it(*dex_file_, *prev);
2575 
2576       while (curr_it.HasNext() && prev_it.HasNext()) {
2577         dex::TypeIndex prev_idx = prev_it.GetTypeIdx();
2578         dex::TypeIndex curr_idx = curr_it.GetTypeIdx();
2579         DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
2580         DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
2581 
2582         if (prev_idx < curr_idx) {
2583           break;
2584         } else if (UNLIKELY(prev_idx > curr_idx)) {
2585           ErrorStringPrintf("Out-of-order proto_id arguments");
2586           return false;
2587         }
2588 
2589         prev_it.Next();
2590         curr_it.Next();
2591       }
2592       if (!curr_it.HasNext()) {
2593         // Either a duplicate ProtoId or a ProtoId with a shorter argument list follows
2594         // a ProtoId with a longer one. Both cases are forbidden by the specification.
2595         ErrorStringPrintf("Out-of-order proto_id arguments");
2596         return false;
2597       }
2598     }
2599   }
2600 
2601   ptr_ += sizeof(dex::ProtoId);
2602   return true;
2603 }
2604 
CheckInterFieldIdItem()2605 bool DexFileVerifier::CheckInterFieldIdItem() {
2606   const dex::FieldId* item = reinterpret_cast<const dex::FieldId*>(ptr_);
2607 
2608   // Check that the class descriptor is valid.
2609   if (UNLIKELY(!VerifyTypeDescriptor(item->class_idx_,
2610                                      "Invalid descriptor for class_idx",
2611                                      [](char d) { return d == 'L'; }))) {
2612     return false;
2613   }
2614 
2615   // Check that the type descriptor is a valid field name.
2616   if (UNLIKELY(!VerifyTypeDescriptor(item->type_idx_,
2617                                      "Invalid descriptor for type_idx",
2618                                      [](char d) { return d != 'V'; }))) {
2619     return false;
2620   }
2621 
2622   // Check that the name is valid.
2623   const char* field_name = dex_file_->StringDataByIdx(item->name_idx_);
2624   if (UNLIKELY(!IsValidMemberName(field_name))) {
2625     ErrorStringPrintf("Invalid field name: '%s'", field_name);
2626     return false;
2627   }
2628 
2629   // Check ordering between items. This relies on the other sections being in order.
2630   if (previous_item_ != nullptr) {
2631     const dex::FieldId* prev_item = reinterpret_cast<const dex::FieldId*>(previous_item_);
2632     if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
2633       ErrorStringPrintf("Out-of-order field_ids");
2634       return false;
2635     } else if (prev_item->class_idx_ == item->class_idx_) {
2636       if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
2637         ErrorStringPrintf("Out-of-order field_ids");
2638         return false;
2639       } else if (prev_item->name_idx_ == item->name_idx_) {
2640         if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
2641           ErrorStringPrintf("Out-of-order field_ids");
2642           return false;
2643         }
2644       }
2645     }
2646   }
2647 
2648   ptr_ += sizeof(dex::FieldId);
2649   return true;
2650 }
2651 
CheckInterMethodIdItem()2652 bool DexFileVerifier::CheckInterMethodIdItem() {
2653   const dex::MethodId* item = reinterpret_cast<const dex::MethodId*>(ptr_);
2654 
2655   // Check that the class descriptor is a valid reference name.
2656   if (UNLIKELY(!VerifyTypeDescriptor(item->class_idx_,
2657                                      "Invalid descriptor for class_idx",
2658                                      [](char d) { return d == 'L' || d == '['; }))) {
2659     return false;
2660   }
2661 
2662   // Check that the name is valid.
2663   const char* method_name = dex_file_->StringDataByIdx(item->name_idx_);
2664   if (UNLIKELY(!IsValidMemberName(method_name))) {
2665     ErrorStringPrintf("Invalid method name: '%s'", method_name);
2666     return false;
2667   }
2668 
2669   // Check that the proto id is valid.
2670   if (UNLIKELY(!CheckIndex(item->proto_idx_.index_, dex_file_->NumProtoIds(),
2671                            "inter_method_id_item proto_idx"))) {
2672     return false;
2673   }
2674 
2675   // Check ordering between items. This relies on the other sections being in order.
2676   if (previous_item_ != nullptr) {
2677     const dex::MethodId* prev_item = reinterpret_cast<const dex::MethodId*>(previous_item_);
2678     if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
2679       ErrorStringPrintf("Out-of-order method_ids");
2680       return false;
2681     } else if (prev_item->class_idx_ == item->class_idx_) {
2682       if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
2683         ErrorStringPrintf("Out-of-order method_ids");
2684         return false;
2685       } else if (prev_item->name_idx_ == item->name_idx_) {
2686         if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
2687           ErrorStringPrintf("Out-of-order method_ids");
2688           return false;
2689         }
2690       }
2691     }
2692   }
2693 
2694   ptr_ += sizeof(dex::MethodId);
2695   return true;
2696 }
2697 
CheckInterClassDefItem()2698 bool DexFileVerifier::CheckInterClassDefItem() {
2699   const dex::ClassDef* item = reinterpret_cast<const dex::ClassDef*>(ptr_);
2700 
2701   // Check that class_idx_ is representable as a uint16_t;
2702   if (UNLIKELY(!IsValidTypeId(item->class_idx_.index_, item->pad1_))) {
2703     ErrorStringPrintf("class with type idx outside uint16_t range '%x:%x'", item->pad1_,
2704                       item->class_idx_.index_);
2705     return false;
2706   }
2707   // Check that superclass_idx_ is representable as a uint16_t;
2708   if (UNLIKELY(!IsValidOrNoTypeId(item->superclass_idx_.index_, item->pad2_))) {
2709     ErrorStringPrintf("class with superclass type idx outside uint16_t range '%x:%x'", item->pad2_,
2710                       item->superclass_idx_.index_);
2711     return false;
2712   }
2713   // Check for duplicate class def.
2714 
2715   if (UNLIKELY(!VerifyTypeDescriptor(item->class_idx_,
2716                                      "Invalid class descriptor",
2717                                      [](char d) { return d == 'L'; }))) {
2718     return false;
2719   }
2720 
2721   // Only allow non-runtime modifiers.
2722   if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
2723     ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
2724     return false;
2725   }
2726 
2727   if (item->interfaces_off_ != 0 &&
2728       !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
2729     return false;
2730   }
2731   if (item->annotations_off_ != 0 &&
2732       !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
2733     return false;
2734   }
2735   if (item->class_data_off_ != 0 &&
2736       !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
2737     return false;
2738   }
2739   if (item->static_values_off_ != 0 &&
2740       !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
2741     return false;
2742   }
2743 
2744   if (item->superclass_idx_.IsValid()) {
2745     if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2746       // Check that a class does not inherit from itself directly (by having
2747       // the same type idx as its super class).
2748       if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) {
2749         ErrorStringPrintf("Class with same type idx as its superclass: '%d'",
2750                           item->class_idx_.index_);
2751         return false;
2752       }
2753 
2754       // Check that a class is defined after its super class (if the
2755       // latter is defined in the same Dex file).
2756       uint16_t superclass_idx = item->superclass_idx_.index_;
2757       if (defined_classes_[superclass_idx]) {
2758         // The superclass is defined in this Dex file.
2759         if (&dex_file_->GetClassDef(defined_class_indexes_[superclass_idx]) > item) {
2760           // ClassDef item for super class appearing after the class' ClassDef item.
2761           ErrorStringPrintf("Invalid class definition ordering:"
2762                             " class with type idx: '%d' defined before"
2763                             " superclass with type idx: '%d'",
2764                             item->class_idx_.index_,
2765                             superclass_idx);
2766           return false;
2767         }
2768       }
2769     }
2770 
2771     if (UNLIKELY(!VerifyTypeDescriptor(item->superclass_idx_,
2772                                        "Invalid superclass",
2773                                        [](char d) { return d == 'L'; }))) {
2774       return false;
2775     }
2776   }
2777 
2778   // Check interfaces.
2779   const dex::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
2780   if (interfaces != nullptr) {
2781     uint32_t size = interfaces->Size();
2782     for (uint32_t i = 0; i < size; i++) {
2783       if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2784         // Check that a class does not implement itself directly (by having the
2785         // same type idx as one of its immediate implemented interfaces).
2786         if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) {
2787           ErrorStringPrintf("Class with same type idx as implemented interface: '%d'",
2788                             item->class_idx_.index_);
2789           return false;
2790         }
2791 
2792         // Check that a class is defined after the interfaces it implements
2793         // (if they are defined in the same Dex file).
2794         uint16_t interface_idx = interfaces->GetTypeItem(i).type_idx_.index_;
2795         if (defined_classes_[interface_idx]) {
2796           // The interface is defined in this Dex file.
2797           if (&dex_file_->GetClassDef(defined_class_indexes_[interface_idx]) > item) {
2798             // ClassDef item for interface appearing after the class' ClassDef item.
2799             ErrorStringPrintf("Invalid class definition ordering:"
2800                               " class with type idx: '%d' defined before"
2801                               " implemented interface with type idx: '%d'",
2802                               item->class_idx_.index_,
2803                               interface_idx);
2804             return false;
2805           }
2806         }
2807       }
2808 
2809       // Ensure that the interface refers to a class (not an array nor a primitive type).
2810       if (UNLIKELY(!VerifyTypeDescriptor(interfaces->GetTypeItem(i).type_idx_,
2811                                          "Invalid interface",
2812                                          [](char d) { return d == 'L'; }))) {
2813         return false;
2814       }
2815     }
2816 
2817     /*
2818      * Ensure that there are no duplicates. This is an O(N^2) test, but in
2819      * practice the number of interfaces implemented by any given class is low.
2820      */
2821     for (uint32_t i = 1; i < size; i++) {
2822       dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_;
2823       for (uint32_t j =0; j < i; j++) {
2824         dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_;
2825         if (UNLIKELY(idx1 == idx2)) {
2826           ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
2827           return false;
2828         }
2829       }
2830     }
2831   }
2832 
2833   // Check that references in class_data_item are to the right class.
2834   if (item->class_data_off_ != 0) {
2835     ClassAccessor accessor(*dex_file_, begin_ + item->class_data_off_);
2836     uint32_t data_definer = FindFirstClassDataDefiner(accessor);
2837     DCHECK(IsUint<16>(data_definer) || data_definer == kDexNoIndex) << data_definer;
2838     if (UNLIKELY((data_definer != item->class_idx_.index_) && (data_definer != kDexNoIndex))) {
2839       ErrorStringPrintf("Invalid class_data_item");
2840       return false;
2841     }
2842   }
2843 
2844   // Check that references in annotations_directory_item are to right class.
2845   if (item->annotations_off_ != 0) {
2846     // annotations_off_ is supposed to be aligned by 4.
2847     if (!IsAlignedParam(item->annotations_off_, 4)) {
2848       ErrorStringPrintf("Invalid annotations_off_, not aligned by 4");
2849       return false;
2850     }
2851     const uint8_t* data = begin_ + item->annotations_off_;
2852     uint32_t defining_class = FindFirstAnnotationsDirectoryDefiner(data);
2853     DCHECK(IsUint<16>(defining_class) || defining_class == kDexNoIndex) << defining_class;
2854     if (UNLIKELY((defining_class != item->class_idx_.index_) && (defining_class != kDexNoIndex))) {
2855       ErrorStringPrintf("Invalid annotations_directory_item");
2856       return false;
2857     }
2858   }
2859 
2860   ptr_ += sizeof(dex::ClassDef);
2861   return true;
2862 }
2863 
CheckInterCallSiteIdItem()2864 bool DexFileVerifier::CheckInterCallSiteIdItem() {
2865   const dex::CallSiteIdItem* item = reinterpret_cast<const dex::CallSiteIdItem*>(ptr_);
2866 
2867   // Check call site referenced by item is in encoded array section.
2868   if (!CheckOffsetToTypeMap(item->data_off_, DexFile::kDexTypeEncodedArrayItem)) {
2869     ErrorStringPrintf("Invalid offset in CallSideIdItem");
2870     return false;
2871   }
2872 
2873   CallSiteArrayValueIterator it(*dex_file_, *item);
2874 
2875   // Check Method Handle
2876   if (!it.HasNext() || it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodHandle) {
2877     ErrorStringPrintf("CallSiteArray missing method handle");
2878     return false;
2879   }
2880 
2881   uint32_t handle_index = static_cast<uint32_t>(it.GetJavaValue().i);
2882   if (handle_index >= dex_file_->NumMethodHandles()) {
2883     ErrorStringPrintf("CallSite has bad method handle id: %x", handle_index);
2884     return false;
2885   }
2886 
2887   // Check target method name.
2888   it.Next();
2889   if (!it.HasNext() ||
2890       it.GetValueType() != EncodedArrayValueIterator::ValueType::kString) {
2891     ErrorStringPrintf("CallSiteArray missing target method name");
2892     return false;
2893   }
2894 
2895   uint32_t name_index = static_cast<uint32_t>(it.GetJavaValue().i);
2896   if (name_index >= dex_file_->NumStringIds()) {
2897     ErrorStringPrintf("CallSite has bad method name id: %x", name_index);
2898     return false;
2899   }
2900 
2901   // Check method type.
2902   it.Next();
2903   if (!it.HasNext() ||
2904       it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodType) {
2905     ErrorStringPrintf("CallSiteArray missing method type");
2906     return false;
2907   }
2908 
2909   uint32_t proto_index = static_cast<uint32_t>(it.GetJavaValue().i);
2910   if (proto_index >= dex_file_->NumProtoIds()) {
2911     ErrorStringPrintf("CallSite has bad method type: %x", proto_index);
2912     return false;
2913   }
2914 
2915   ptr_ += sizeof(dex::CallSiteIdItem);
2916   return true;
2917 }
2918 
CheckInterAnnotationSetRefList()2919 bool DexFileVerifier::CheckInterAnnotationSetRefList() {
2920   const dex::AnnotationSetRefList* list = reinterpret_cast<const dex::AnnotationSetRefList*>(ptr_);
2921   const dex::AnnotationSetRefItem* item = list->list_;
2922   uint32_t count = list->size_;
2923 
2924   for (; count != 0u; --count) {
2925     if (item->annotations_off_ != 0 &&
2926         !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2927       return false;
2928     }
2929     item++;
2930   }
2931 
2932   ptr_ = reinterpret_cast<const uint8_t*>(item);
2933   return true;
2934 }
2935 
CheckInterAnnotationSetItem()2936 bool DexFileVerifier::CheckInterAnnotationSetItem() {
2937   const dex::AnnotationSetItem* set = reinterpret_cast<const dex::AnnotationSetItem*>(ptr_);
2938   const uint32_t* offsets = set->entries_;
2939   uint32_t count = set->size_;
2940   uint32_t last_idx = 0;
2941 
2942   for (uint32_t i = 0; i < count; i++) {
2943     if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
2944       return false;
2945     }
2946 
2947     // Get the annotation from the offset and the type index for the annotation.
2948     const dex::AnnotationItem* annotation =
2949         reinterpret_cast<const dex::AnnotationItem*>(begin_ + *offsets);
2950     const uint8_t* data = annotation->annotation_;
2951     DECODE_UNSIGNED_CHECKED_FROM(data, idx);
2952 
2953     if (UNLIKELY(last_idx >= idx && i != 0)) {
2954       ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
2955       return false;
2956     }
2957 
2958     last_idx = idx;
2959     offsets++;
2960   }
2961 
2962   ptr_ = reinterpret_cast<const uint8_t*>(offsets);
2963   return true;
2964 }
2965 
CheckInterClassDataItem()2966 bool DexFileVerifier::CheckInterClassDataItem() {
2967   ClassAccessor accessor(*dex_file_, ptr_);
2968   uint32_t defining_class = FindFirstClassDataDefiner(accessor);
2969   DCHECK(IsUint<16>(defining_class) || defining_class == kDexNoIndex) << defining_class;
2970   if (defining_class == kDexNoIndex) {
2971     return true;  // Empty definitions are OK (but useless) and could be shared by multiple classes.
2972   }
2973   if (!defined_classes_[defining_class]) {
2974       // Should really have a class definition for this class data item.
2975       ErrorStringPrintf("Could not find declaring class for non-empty class data item.");
2976       return false;
2977   }
2978   const dex::TypeIndex class_type_index(defining_class);
2979   const dex::ClassDef& class_def = dex_file_->GetClassDef(defined_class_indexes_[defining_class]);
2980 
2981   for (const ClassAccessor::Field& read_field : accessor.GetFields()) {
2982     // The index has already been checked in `CheckIntraClassDataItemFields()`.
2983     DCHECK_LE(read_field.GetIndex(), header_->field_ids_size_);
2984     const dex::FieldId& field = dex_file_->GetFieldId(read_field.GetIndex());
2985     if (UNLIKELY(field.class_idx_ != class_type_index)) {
2986       ErrorStringPrintf("Mismatched defining class for class_data_item field");
2987       return false;
2988     }
2989     if (!CheckClassDataItemField(read_field.GetIndex(),
2990                                  read_field.GetAccessFlags(),
2991                                  class_def.access_flags_,
2992                                  class_type_index)) {
2993       return false;
2994     }
2995   }
2996   size_t num_direct_methods = accessor.NumDirectMethods();
2997   size_t num_processed_methods = 0u;
2998   auto methods = accessor.GetMethods();
2999   auto it = methods.begin();
3000   for (; it != methods.end(); ++it, ++num_processed_methods) {
3001     uint32_t code_off = it->GetCodeItemOffset();
3002     if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
3003       return false;
3004     }
3005     // The index has already been checked in `CheckIntraClassDataItemMethods()`.
3006     DCHECK_LE(it->GetIndex(), header_->method_ids_size_);
3007     const dex::MethodId& method = dex_file_->GetMethodId(it->GetIndex());
3008     if (UNLIKELY(method.class_idx_ != class_type_index)) {
3009       ErrorStringPrintf("Mismatched defining class for class_data_item method");
3010       return false;
3011     }
3012     bool expect_direct = num_processed_methods < num_direct_methods;
3013     if (!CheckClassDataItemMethod(it->GetIndex(),
3014                                   it->GetAccessFlags(),
3015                                   class_def.access_flags_,
3016                                   class_type_index,
3017                                   it->GetCodeItemOffset(),
3018                                   expect_direct)) {
3019       return false;
3020     }
3021   }
3022 
3023   // Check static field types against initial static values in encoded array.
3024   if (!CheckStaticFieldTypes(class_def)) {
3025     return false;
3026   }
3027 
3028   ptr_ = it.GetDataPointer();
3029   return true;
3030 }
3031 
CheckInterAnnotationsDirectoryItem()3032 bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
3033   const dex::AnnotationsDirectoryItem* item =
3034       reinterpret_cast<const dex::AnnotationsDirectoryItem*>(ptr_);
3035   uint32_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_);
3036   DCHECK(IsUint<16>(defining_class) || defining_class == kDexNoIndex) << defining_class;
3037 
3038   if (item->class_annotations_off_ != 0 &&
3039       !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
3040     return false;
3041   }
3042 
3043   // Field annotations follow immediately after the annotations directory.
3044   const dex::FieldAnnotationsItem* field_item =
3045       reinterpret_cast<const dex::FieldAnnotationsItem*>(item + 1);
3046   uint32_t field_count = item->fields_size_;
3047   for (uint32_t i = 0; i < field_count; i++) {
3048     // The index has already been checked in `CheckIntraAnnotationsDirectoryItem()`.
3049     DCHECK_LE(field_item->field_idx_, header_->field_ids_size_);
3050     const dex::FieldId& field = dex_file_->GetFieldId(field_item->field_idx_);
3051     if (UNLIKELY(field.class_idx_.index_ != defining_class)) {
3052       ErrorStringPrintf("Mismatched defining class for field_annotation");
3053       return false;
3054     }
3055     if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
3056       return false;
3057     }
3058     field_item++;
3059   }
3060 
3061   // Method annotations follow immediately after field annotations.
3062   const dex::MethodAnnotationsItem* method_item =
3063       reinterpret_cast<const dex::MethodAnnotationsItem*>(field_item);
3064   uint32_t method_count = item->methods_size_;
3065   for (uint32_t i = 0; i < method_count; i++) {
3066     // The index has already been checked in `CheckIntraAnnotationsDirectoryItem()`.
3067     DCHECK_LE(method_item->method_idx_, header_->method_ids_size_);
3068     const dex::MethodId& method = dex_file_->GetMethodId(method_item->method_idx_);
3069     if (UNLIKELY(method.class_idx_.index_ != defining_class)) {
3070       ErrorStringPrintf("Mismatched defining class for method_annotation");
3071       return false;
3072     }
3073     if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
3074       return false;
3075     }
3076     method_item++;
3077   }
3078 
3079   // Parameter annotations follow immediately after method annotations.
3080   const dex::ParameterAnnotationsItem* parameter_item =
3081       reinterpret_cast<const dex::ParameterAnnotationsItem*>(method_item);
3082   uint32_t parameter_count = item->parameters_size_;
3083   for (uint32_t i = 0; i < parameter_count; i++) {
3084     // The index has already been checked in `CheckIntraAnnotationsDirectoryItem()`.
3085     DCHECK_LE(parameter_item->method_idx_, header_->method_ids_size_);
3086     const dex::MethodId& parameter_method = dex_file_->GetMethodId(parameter_item->method_idx_);
3087     if (UNLIKELY(parameter_method.class_idx_.index_ != defining_class)) {
3088       ErrorStringPrintf("Mismatched defining class for parameter_annotation");
3089       return false;
3090     }
3091     if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
3092         DexFile::kDexTypeAnnotationSetRefList)) {
3093       return false;
3094     }
3095     parameter_item++;
3096   }
3097 
3098   ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
3099   return true;
3100 }
3101 
CheckInterSectionIterate(size_t offset,uint32_t count,DexFile::MapItemType type)3102 bool DexFileVerifier::CheckInterSectionIterate(size_t offset,
3103                                                uint32_t count,
3104                                                DexFile::MapItemType type) {
3105   // Get the right alignment mask for the type of section.
3106   size_t alignment_mask;
3107   switch (type) {
3108     case DexFile::kDexTypeClassDataItem:
3109       alignment_mask = sizeof(uint8_t) - 1;
3110       break;
3111     default:
3112       alignment_mask = sizeof(uint32_t) - 1;
3113       break;
3114   }
3115 
3116   // Iterate through the items in the section.
3117   previous_item_ = nullptr;
3118   for (uint32_t i = 0; i < count; i++) {
3119     uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
3120     ptr_ = begin_ + new_offset;
3121     const uint8_t* prev_ptr = ptr_;
3122 
3123     if (MapTypeToBitMask(type) == 0) {
3124       ErrorStringPrintf("Unknown map item type %x", type);
3125       return false;
3126     }
3127 
3128     // Check depending on the section type.
3129     switch (type) {
3130       case DexFile::kDexTypeHeaderItem:
3131       case DexFile::kDexTypeMethodHandleItem:
3132       case DexFile::kDexTypeMapList:
3133       case DexFile::kDexTypeTypeList:
3134       case DexFile::kDexTypeCodeItem:
3135       case DexFile::kDexTypeStringDataItem:
3136       case DexFile::kDexTypeDebugInfoItem:
3137       case DexFile::kDexTypeAnnotationItem:
3138       case DexFile::kDexTypeEncodedArrayItem:
3139       case DexFile::kDexTypeHiddenapiClassData:
3140         break;
3141       case DexFile::kDexTypeStringIdItem: {
3142         if (!CheckInterStringIdItem()) {
3143           return false;
3144         }
3145         break;
3146       }
3147       case DexFile::kDexTypeTypeIdItem: {
3148         if (!CheckInterTypeIdItem()) {
3149           return false;
3150         }
3151         break;
3152       }
3153       case DexFile::kDexTypeProtoIdItem: {
3154         if (!CheckInterProtoIdItem()) {
3155           return false;
3156         }
3157         break;
3158       }
3159       case DexFile::kDexTypeFieldIdItem: {
3160         if (!CheckInterFieldIdItem()) {
3161           return false;
3162         }
3163         break;
3164       }
3165       case DexFile::kDexTypeMethodIdItem: {
3166         if (!CheckInterMethodIdItem()) {
3167           return false;
3168         }
3169         break;
3170       }
3171       case DexFile::kDexTypeClassDefItem: {
3172         // There shouldn't be more class definitions than type ids allow.
3173         // This is checked in `CheckIntraClassDefItem()` by checking the type
3174         // index against `kTypeIdLimit` and rejecting dulicate definitions.
3175         DCHECK_LE(i, kTypeIdLimit);
3176         if (!CheckInterClassDefItem()) {
3177           return false;
3178         }
3179         break;
3180       }
3181       case DexFile::kDexTypeCallSiteIdItem: {
3182         if (!CheckInterCallSiteIdItem()) {
3183           return false;
3184         }
3185         break;
3186       }
3187       case DexFile::kDexTypeAnnotationSetRefList: {
3188         if (!CheckInterAnnotationSetRefList()) {
3189           return false;
3190         }
3191         break;
3192       }
3193       case DexFile::kDexTypeAnnotationSetItem: {
3194         if (!CheckInterAnnotationSetItem()) {
3195           return false;
3196         }
3197         break;
3198       }
3199       case DexFile::kDexTypeClassDataItem: {
3200         // There shouldn't be more class data than type ids allow.
3201         // This check should be redundant, since there are checks that the
3202         // class_idx_ is within range and that there is only one definition
3203         // for a given type id.
3204         if (i > kTypeIdLimit) {
3205           ErrorStringPrintf("Too many class data items");
3206           return false;
3207         }
3208         if (!CheckInterClassDataItem()) {
3209           return false;
3210         }
3211         break;
3212       }
3213       case DexFile::kDexTypeAnnotationsDirectoryItem: {
3214         if (!CheckInterAnnotationsDirectoryItem()) {
3215           return false;
3216         }
3217         break;
3218       }
3219     }
3220 
3221     previous_item_ = prev_ptr;
3222     offset = ptr_ - begin_;
3223   }
3224 
3225   return true;
3226 }
3227 
CheckInterSection()3228 bool DexFileVerifier::CheckInterSection() {
3229   // Eagerly verify that `StringId` offsets map to string data items to make sure
3230   // we can retrieve the string data for verifying other items (types, shorties, etc.).
3231   // After this we can safely use `DexFile` helpers such as `GetFieldId()` or `GetMethodId()`
3232   // but not `PrettyMethod()` or `PrettyField()` as descriptors have not been verified yet.
3233   const dex::StringId* string_ids =
3234       reinterpret_cast<const dex::StringId*>(begin_ + header_->string_ids_off_);
3235   for (size_t i = 0, num_strings = header_->string_ids_size_; i != num_strings; ++i) {
3236     if (!CheckOffsetToTypeMap(string_ids[i].string_data_off_, DexFile::kDexTypeStringDataItem)) {
3237       return false;
3238     }
3239   }
3240 
3241   const dex::MapList* map = reinterpret_cast<const dex::MapList*>(begin_ + header_->map_off_);
3242   const dex::MapItem* item = map->list_;
3243   uint32_t count = map->size_;
3244 
3245   // Cross check the items listed in the map.
3246   for (; count != 0u; --count) {
3247     uint32_t section_offset = item->offset_;
3248     uint32_t section_count = item->size_;
3249     DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
3250     bool found = false;
3251 
3252     switch (type) {
3253       case DexFile::kDexTypeHeaderItem:
3254       case DexFile::kDexTypeMapList:
3255       case DexFile::kDexTypeTypeList:
3256       case DexFile::kDexTypeCodeItem:
3257       case DexFile::kDexTypeStringDataItem:
3258       case DexFile::kDexTypeDebugInfoItem:
3259       case DexFile::kDexTypeAnnotationItem:
3260       case DexFile::kDexTypeEncodedArrayItem:
3261         found = true;
3262         break;
3263       case DexFile::kDexTypeStringIdItem:
3264       case DexFile::kDexTypeTypeIdItem:
3265       case DexFile::kDexTypeProtoIdItem:
3266       case DexFile::kDexTypeFieldIdItem:
3267       case DexFile::kDexTypeMethodIdItem:
3268       case DexFile::kDexTypeClassDefItem:
3269       case DexFile::kDexTypeCallSiteIdItem:
3270       case DexFile::kDexTypeMethodHandleItem:
3271       case DexFile::kDexTypeAnnotationSetRefList:
3272       case DexFile::kDexTypeAnnotationSetItem:
3273       case DexFile::kDexTypeClassDataItem:
3274       case DexFile::kDexTypeAnnotationsDirectoryItem:
3275       case DexFile::kDexTypeHiddenapiClassData: {
3276         if (!CheckInterSectionIterate(section_offset, section_count, type)) {
3277           return false;
3278         }
3279         found = true;
3280         break;
3281       }
3282     }
3283 
3284     if (!found) {
3285       ErrorStringPrintf("Unknown map item type %x", item->type_);
3286       return false;
3287     }
3288 
3289     item++;
3290   }
3291 
3292   return true;
3293 }
3294 
Verify()3295 bool DexFileVerifier::Verify() {
3296   // Check the header.
3297   if (!CheckHeader()) {
3298     return false;
3299   }
3300 
3301   // Check the map section.
3302   if (!CheckMap()) {
3303     return false;
3304   }
3305 
3306   DCHECK_LE(header_->type_ids_size_, kTypeIdLimit + 1u);  // Checked in CheckHeader().
3307   verified_type_descriptors_.resize(header_->type_ids_size_, 0);
3308   defined_class_indexes_.resize(header_->type_ids_size_);
3309 
3310   // Check structure within remaining sections.
3311   if (!CheckIntraSection()) {
3312     return false;
3313   }
3314 
3315   // Check references from one section to another.
3316   if (!CheckInterSection()) {
3317     return false;
3318   }
3319 
3320   return true;
3321 }
3322 
CheckFieldAccessFlags(uint32_t idx,uint32_t field_access_flags,uint32_t class_access_flags,std::string * error_msg)3323 bool DexFileVerifier::CheckFieldAccessFlags(uint32_t idx,
3324                                             uint32_t field_access_flags,
3325                                             uint32_t class_access_flags,
3326                                             std::string* error_msg) {
3327   // Generally sort out >16-bit flags.
3328   if ((field_access_flags & ~kAccJavaFlagsMask) != 0) {
3329     *error_msg = StringPrintf("Bad field access_flags for %s: %x(%s)",
3330                               GetFieldDescription(begin_, header_, idx).c_str(),
3331                               field_access_flags,
3332                               PrettyJavaAccessFlags(field_access_flags).c_str());
3333     return false;
3334   }
3335 
3336   // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
3337   constexpr uint32_t kFieldAccessFlags = kAccPublic |
3338                                          kAccPrivate |
3339                                          kAccProtected |
3340                                          kAccStatic |
3341                                          kAccFinal |
3342                                          kAccVolatile |
3343                                          kAccTransient |
3344                                          kAccSynthetic |
3345                                          kAccEnum;
3346 
3347   // Fields may have only one of public/protected/final.
3348   if (!CheckAtMostOneOfPublicProtectedPrivate(field_access_flags)) {
3349     *error_msg = StringPrintf("Field may have only one of public/protected/private, %s: %x(%s)",
3350                               GetFieldDescription(begin_, header_, idx).c_str(),
3351                               field_access_flags,
3352                               PrettyJavaAccessFlags(field_access_flags).c_str());
3353     return false;
3354   }
3355 
3356   // Interfaces have a pretty restricted list.
3357   if ((class_access_flags & kAccInterface) != 0) {
3358     // Interface fields must be public final static.
3359     constexpr uint32_t kPublicFinalStatic = kAccPublic | kAccFinal | kAccStatic;
3360     if ((field_access_flags & kPublicFinalStatic) != kPublicFinalStatic) {
3361       *error_msg = StringPrintf("Interface field is not public final static, %s: %x(%s)",
3362                                 GetFieldDescription(begin_, header_, idx).c_str(),
3363                                 field_access_flags,
3364                                 PrettyJavaAccessFlags(field_access_flags).c_str());
3365       if (dex_file_->SupportsDefaultMethods()) {
3366         return false;
3367       } else {
3368         // Allow in older versions, but warn.
3369         LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3370                      << *error_msg;
3371       }
3372     }
3373     // Interface fields may be synthetic, but may not have other flags.
3374     constexpr uint32_t kDisallowed = ~(kPublicFinalStatic | kAccSynthetic);
3375     if ((field_access_flags & kFieldAccessFlags & kDisallowed) != 0) {
3376       *error_msg = StringPrintf("Interface field has disallowed flag, %s: %x(%s)",
3377                                 GetFieldDescription(begin_, header_, idx).c_str(),
3378                                 field_access_flags,
3379                                 PrettyJavaAccessFlags(field_access_flags).c_str());
3380       if (dex_file_->SupportsDefaultMethods()) {
3381         return false;
3382       } else {
3383         // Allow in older versions, but warn.
3384         LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3385                      << *error_msg;
3386       }
3387     }
3388     return true;
3389   }
3390 
3391   // Volatile fields may not be final.
3392   constexpr uint32_t kVolatileFinal = kAccVolatile | kAccFinal;
3393   if ((field_access_flags & kVolatileFinal) == kVolatileFinal) {
3394     *error_msg = StringPrintf("Fields may not be volatile and final: %s",
3395                               GetFieldDescription(begin_, header_, idx).c_str());
3396     return false;
3397   }
3398 
3399   return true;
3400 }
3401 
FindStringRangesForMethodNames()3402 void DexFileVerifier::FindStringRangesForMethodNames() {
3403   // Use DexFile::StringId* as RandomAccessIterator.
3404   const dex::StringId* first = reinterpret_cast<const dex::StringId*>(
3405       begin_ + header_->string_ids_off_);
3406   const dex::StringId* last = first + header_->string_ids_size_;
3407 
3408   auto get_string = [begin = begin_](const dex::StringId& id) {
3409     const uint8_t* str_data_ptr = begin + id.string_data_off_;
3410     DecodeUnsignedLeb128(&str_data_ptr);
3411     return reinterpret_cast<const char*>(str_data_ptr);
3412   };
3413   auto compare = [&get_string](const dex::StringId& lhs, const char* rhs) {
3414     return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(get_string(lhs), rhs) < 0;
3415   };
3416 
3417   // '=' follows '<'
3418   static_assert('<' + 1 == '=', "Unexpected character relation");
3419   const auto angle_end = std::lower_bound(first, last, "=", compare);
3420   init_indices_.angle_bracket_end_index = angle_end - first;
3421 
3422   const auto angle_start = std::lower_bound(first, angle_end, "<", compare);
3423   init_indices_.angle_bracket_start_index = angle_start - first;
3424   if (angle_start == angle_end) {
3425     // No strings starting with '<'.
3426     init_indices_.angle_init_angle_index = std::numeric_limits<size_t>::max();
3427     init_indices_.angle_clinit_angle_index = std::numeric_limits<size_t>::max();
3428     return;
3429   }
3430 
3431   {
3432     constexpr const char* kClinit = "<clinit>";
3433     const auto it = std::lower_bound(angle_start, angle_end, kClinit, compare);
3434     if (it != angle_end && strcmp(get_string(*it), kClinit) == 0) {
3435       init_indices_.angle_clinit_angle_index = it - first;
3436     } else {
3437       init_indices_.angle_clinit_angle_index = std::numeric_limits<size_t>::max();
3438     }
3439   }
3440   {
3441     constexpr const char* kInit = "<init>";
3442     const auto it = std::lower_bound(angle_start, angle_end, kInit, compare);
3443     if (it != angle_end && strcmp(get_string(*it), kInit) == 0) {
3444       init_indices_.angle_init_angle_index = it - first;
3445     } else {
3446       init_indices_.angle_init_angle_index = std::numeric_limits<size_t>::max();
3447     }
3448   }
3449 }
3450 
CheckMethodAccessFlags(uint32_t method_index,uint32_t method_access_flags,uint32_t class_access_flags,uint32_t constructor_flags_by_name,bool has_code,bool expect_direct,std::string * error_msg)3451 bool DexFileVerifier::CheckMethodAccessFlags(uint32_t method_index,
3452                                              uint32_t method_access_flags,
3453                                              uint32_t class_access_flags,
3454                                              uint32_t constructor_flags_by_name,
3455                                              bool has_code,
3456                                              bool expect_direct,
3457                                              std::string* error_msg) {
3458   // Generally sort out >16-bit flags, except dex knows Constructor and DeclaredSynchronized.
3459   constexpr uint32_t kAllMethodFlags =
3460       kAccJavaFlagsMask | kAccConstructor | kAccDeclaredSynchronized;
3461   if ((method_access_flags & ~kAllMethodFlags) != 0) {
3462     *error_msg = StringPrintf("Bad method access_flags for %s: %x",
3463                               GetMethodDescription(begin_, header_, method_index).c_str(),
3464                               method_access_flags);
3465     return false;
3466   }
3467 
3468   // Flags allowed on methods, in general. Other lower-16-bit flags are to be ignored.
3469   constexpr uint32_t kMethodAccessFlags = kAccPublic |
3470                                           kAccPrivate |
3471                                           kAccProtected |
3472                                           kAccStatic |
3473                                           kAccFinal |
3474                                           kAccSynthetic |
3475                                           kAccSynchronized |
3476                                           kAccBridge |
3477                                           kAccVarargs |
3478                                           kAccNative |
3479                                           kAccAbstract |
3480                                           kAccStrict;
3481 
3482   // Methods may have only one of public/protected/final.
3483   if (!CheckAtMostOneOfPublicProtectedPrivate(method_access_flags)) {
3484     *error_msg = StringPrintf("Method may have only one of public/protected/private, %s: %x",
3485                               GetMethodDescription(begin_, header_, method_index).c_str(),
3486                               method_access_flags);
3487     return false;
3488   }
3489 
3490   constexpr uint32_t kConstructorFlags = kAccStatic | kAccConstructor;
3491   const bool is_constructor_by_name = (constructor_flags_by_name & kConstructorFlags) != 0;
3492   const bool is_clinit_by_name = constructor_flags_by_name == kConstructorFlags;
3493 
3494   // Only methods named "<clinit>" or "<init>" may be marked constructor. Note: we cannot enforce
3495   // the reverse for backwards compatibility reasons.
3496   if (((method_access_flags & kAccConstructor) != 0) && !is_constructor_by_name) {
3497     *error_msg =
3498         StringPrintf("Method %" PRIu32 "(%s) is marked constructor, but doesn't match name",
3499                       method_index,
3500                       GetMethodDescription(begin_, header_, method_index).c_str());
3501     return false;
3502   }
3503 
3504   if (is_constructor_by_name) {
3505     // Check that the static constructor (= static initializer) is named "<clinit>" and that the
3506     // instance constructor is called "<init>".
3507     bool is_static = (method_access_flags & kAccStatic) != 0;
3508     if (is_static ^ is_clinit_by_name) {
3509       *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) is not flagged correctly wrt/ static.",
3510                                 method_index,
3511                                 GetMethodDescription(begin_, header_, method_index).c_str());
3512       if (dex_file_->SupportsDefaultMethods()) {
3513         return false;
3514       } else {
3515         // Allow in older versions, but warn.
3516         LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3517                      << *error_msg;
3518       }
3519     }
3520   }
3521 
3522   // Check that static and private methods, as well as constructors, are in the direct methods list,
3523   // and other methods in the virtual methods list.
3524   bool is_direct = ((method_access_flags & (kAccStatic | kAccPrivate)) != 0) ||
3525                    is_constructor_by_name;
3526   if (is_direct != expect_direct) {
3527     *error_msg = StringPrintf("Direct/virtual method %" PRIu32 "(%s) not in expected list %d",
3528                               method_index,
3529                               GetMethodDescription(begin_, header_, method_index).c_str(),
3530                               expect_direct);
3531     return false;
3532   }
3533 
3534   // From here on out it is easier to mask out the bits we're supposed to ignore.
3535   method_access_flags &= kMethodAccessFlags;
3536 
3537   // Interfaces are special.
3538   if ((class_access_flags & kAccInterface) != 0) {
3539     // Non-static interface methods must be public or private.
3540     uint32_t desired_flags = (kAccPublic | kAccStatic);
3541     if (dex_file_->SupportsDefaultMethods()) {
3542       desired_flags |= kAccPrivate;
3543     }
3544     if ((method_access_flags & desired_flags) == 0) {
3545       *error_msg = StringPrintf("Interface virtual method %" PRIu32 "(%s) is not public",
3546                                 method_index,
3547                                 GetMethodDescription(begin_, header_, method_index).c_str());
3548       if (dex_file_->SupportsDefaultMethods()) {
3549         return false;
3550       } else {
3551         // Allow in older versions, but warn.
3552         LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3553                       << *error_msg;
3554       }
3555     }
3556   }
3557 
3558   // If there aren't any instructions, make sure that's expected.
3559   if (!has_code) {
3560     // Only native or abstract methods may not have code.
3561     if ((method_access_flags & (kAccNative | kAccAbstract)) == 0) {
3562       *error_msg = StringPrintf("Method %" PRIu32 "(%s) has no code, but is not marked native or "
3563                                 "abstract",
3564                                 method_index,
3565                                 GetMethodDescription(begin_, header_, method_index).c_str());
3566       return false;
3567     }
3568     // Constructors must always have code.
3569     if (is_constructor_by_name) {
3570       *error_msg = StringPrintf("Constructor %u(%s) must not be abstract or native",
3571                                 method_index,
3572                                 GetMethodDescription(begin_, header_, method_index).c_str());
3573       if (dex_file_->SupportsDefaultMethods()) {
3574         return false;
3575       } else {
3576         // Allow in older versions, but warn.
3577         LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3578                       << *error_msg;
3579       }
3580     }
3581     if ((method_access_flags & kAccAbstract) != 0) {
3582       // Abstract methods are not allowed to have the following flags.
3583       constexpr uint32_t kForbidden =
3584           kAccPrivate | kAccStatic | kAccFinal | kAccNative | kAccStrict | kAccSynchronized;
3585       if ((method_access_flags & kForbidden) != 0) {
3586         *error_msg = StringPrintf("Abstract method %" PRIu32 "(%s) has disallowed access flags %x",
3587                                   method_index,
3588                                   GetMethodDescription(begin_, header_, method_index).c_str(),
3589                                   method_access_flags);
3590         return false;
3591       }
3592       // Abstract methods should be in an abstract class or interface.
3593       if ((class_access_flags & (kAccInterface | kAccAbstract)) == 0) {
3594         LOG(WARNING) << "Method " << GetMethodDescription(begin_, header_, method_index)
3595                      << " is abstract, but the declaring class is neither abstract nor an "
3596                      << "interface in dex file "
3597                      << dex_file_->GetLocation();
3598       }
3599     }
3600     // Interfaces are special.
3601     if ((class_access_flags & kAccInterface) != 0) {
3602       // Interface methods without code must be abstract.
3603       if ((method_access_flags & (kAccPublic | kAccAbstract)) != (kAccPublic | kAccAbstract)) {
3604         *error_msg = StringPrintf("Interface method %" PRIu32 "(%s) is not public and abstract",
3605                                   method_index,
3606                                   GetMethodDescription(begin_, header_, method_index).c_str());
3607         if (dex_file_->SupportsDefaultMethods()) {
3608           return false;
3609         } else {
3610           // Allow in older versions, but warn.
3611           LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3612                        << *error_msg;
3613         }
3614       }
3615       // At this point, we know the method is public and abstract. This means that all the checks
3616       // for invalid combinations above applies. In addition, interface methods must not be
3617       // protected. This is caught by the check for only-one-of-public-protected-private.
3618     }
3619     return true;
3620   }
3621 
3622   // When there's code, the method must not be native or abstract.
3623   if ((method_access_flags & (kAccNative | kAccAbstract)) != 0) {
3624     *error_msg = StringPrintf("Method %" PRIu32 "(%s) has code, but is marked native or abstract",
3625                               method_index,
3626                               GetMethodDescription(begin_, header_, method_index).c_str());
3627     return false;
3628   }
3629 
3630   // Instance constructors must not be synchronized and a few other flags.
3631   if (constructor_flags_by_name == kAccConstructor) {
3632     static constexpr uint32_t kInitAllowed =
3633         kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic;
3634     if ((method_access_flags & ~kInitAllowed) != 0) {
3635       *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) flagged inappropriately %x",
3636                                 method_index,
3637                                 GetMethodDescription(begin_, header_, method_index).c_str(),
3638                                 method_access_flags);
3639       return false;
3640     }
3641   }
3642 
3643   return true;
3644 }
3645 
CheckConstructorProperties(uint32_t method_index,uint32_t constructor_flags)3646 bool DexFileVerifier::CheckConstructorProperties(
3647       uint32_t method_index,
3648       uint32_t constructor_flags) {
3649   DCHECK(constructor_flags == kAccConstructor ||
3650          constructor_flags == (kAccConstructor | kAccStatic));
3651 
3652   // Check signature matches expectations.
3653   // The `method_index` has already been checked in `CheckIntraClassDataItemMethods()`.
3654   CHECK_LT(method_index, header_->method_ids_size_);
3655   const dex::MethodId& method_id = dex_file_->GetMethodId(method_index);
3656 
3657   // The `method_id.proto_idx_` has already been checked in `CheckIntraMethodIdItem()`
3658   DCHECK_LE(method_id.proto_idx_.index_, header_->proto_ids_size_);
3659 
3660   Signature signature = dex_file_->GetMethodSignature(method_id);
3661   if (constructor_flags == (kAccStatic | kAccConstructor)) {
3662     if (!signature.IsVoid() || signature.GetNumberOfParameters() != 0) {
3663       ErrorStringPrintf("<clinit> must have descriptor ()V");
3664       return false;
3665     }
3666   } else if (!signature.IsVoid()) {
3667     ErrorStringPrintf("Constructor %u(%s) must be void",
3668                       method_index,
3669                       GetMethodDescription(begin_, header_, method_index).c_str());
3670     return false;
3671   }
3672 
3673   return true;
3674 }
3675 
Verify(const DexFile * dex_file,const char * location,bool verify_checksum,std::string * error_msg)3676 bool Verify(const DexFile* dex_file,
3677             const char* location,
3678             bool verify_checksum,
3679             std::string* error_msg) {
3680   std::unique_ptr<DexFileVerifier> verifier(
3681       new DexFileVerifier(dex_file, location, verify_checksum));
3682   if (!verifier->Verify()) {
3683     *error_msg = verifier->FailureReason();
3684     return false;
3685   }
3686   return true;
3687 }
3688 
3689 }  // namespace dex
3690 }  // namespace art
3691