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