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