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