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