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