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