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 <zlib.h>
20 #include <memory>
21 
22 #include "base/stringprintf.h"
23 #include "dex_file-inl.h"
24 #include "leb128.h"
25 #include "safe_map.h"
26 #include "utf-inl.h"
27 #include "utils.h"
28 
29 namespace art {
30 
MapTypeToBitMask(uint32_t map_type)31 static uint32_t MapTypeToBitMask(uint32_t map_type) {
32   switch (map_type) {
33     case DexFile::kDexTypeHeaderItem:               return 1 << 0;
34     case DexFile::kDexTypeStringIdItem:             return 1 << 1;
35     case DexFile::kDexTypeTypeIdItem:               return 1 << 2;
36     case DexFile::kDexTypeProtoIdItem:              return 1 << 3;
37     case DexFile::kDexTypeFieldIdItem:              return 1 << 4;
38     case DexFile::kDexTypeMethodIdItem:             return 1 << 5;
39     case DexFile::kDexTypeClassDefItem:             return 1 << 6;
40     case DexFile::kDexTypeMapList:                  return 1 << 7;
41     case DexFile::kDexTypeTypeList:                 return 1 << 8;
42     case DexFile::kDexTypeAnnotationSetRefList:     return 1 << 9;
43     case DexFile::kDexTypeAnnotationSetItem:        return 1 << 10;
44     case DexFile::kDexTypeClassDataItem:            return 1 << 11;
45     case DexFile::kDexTypeCodeItem:                 return 1 << 12;
46     case DexFile::kDexTypeStringDataItem:           return 1 << 13;
47     case DexFile::kDexTypeDebugInfoItem:            return 1 << 14;
48     case DexFile::kDexTypeAnnotationItem:           return 1 << 15;
49     case DexFile::kDexTypeEncodedArrayItem:         return 1 << 16;
50     case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 17;
51   }
52   return 0;
53 }
54 
IsDataSectionType(uint32_t map_type)55 static bool IsDataSectionType(uint32_t map_type) {
56   switch (map_type) {
57     case DexFile::kDexTypeHeaderItem:
58     case DexFile::kDexTypeStringIdItem:
59     case DexFile::kDexTypeTypeIdItem:
60     case DexFile::kDexTypeProtoIdItem:
61     case DexFile::kDexTypeFieldIdItem:
62     case DexFile::kDexTypeMethodIdItem:
63     case DexFile::kDexTypeClassDefItem:
64       return false;
65   }
66   return true;
67 }
68 
CheckLoadStringByIdx(uint32_t idx,const char * error_string)69 const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* error_string) {
70   if (UNLIKELY(!CheckIndex(idx, dex_file_->NumStringIds(), error_string))) {
71     return nullptr;
72   }
73   return dex_file_->StringDataByIdx(idx);
74 }
75 
CheckLoadStringByTypeIdx(uint32_t type_idx,const char * error_string)76 const char* DexFileVerifier::CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_string) {
77   if (UNLIKELY(!CheckIndex(type_idx, dex_file_->NumTypeIds(), error_string))) {
78     return nullptr;
79   }
80   const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx);
81   uint32_t idx = type_id.descriptor_idx_;
82   return CheckLoadStringByIdx(idx, error_string);
83 }
84 
CheckLoadFieldId(uint32_t idx,const char * error_string)85 const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
86   if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
87     return nullptr;
88   }
89   return &dex_file_->GetFieldId(idx);
90 }
91 
CheckLoadMethodId(uint32_t idx,const char * err_string)92 const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
93   if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
94     return nullptr;
95   }
96   return &dex_file_->GetMethodId(idx);
97 }
98 
99 // Helper macro to load string and return false on error.
100 #define LOAD_STRING(var, idx, error)                  \
101   const char* var = CheckLoadStringByIdx(idx, error); \
102   if (UNLIKELY(var == nullptr)) {                     \
103     return false;                                     \
104   }
105 
106 // Helper macro to load string by type idx and return false on error.
107 #define LOAD_STRING_BY_TYPE(var, type_idx, error)              \
108   const char* var = CheckLoadStringByTypeIdx(type_idx, error); \
109   if (UNLIKELY(var == nullptr)) {                              \
110     return false;                                              \
111   }
112 
113 // Helper macro to load method id. Return last parameter on error.
114 #define LOAD_METHOD(var, idx, error_string, error_stmt)                 \
115   const DexFile::MethodId* var  = CheckLoadMethodId(idx, error_string); \
116   if (UNLIKELY(var == nullptr)) {                                       \
117     error_stmt;                                                         \
118   }
119 
120 // Helper macro to load method id. Return last parameter on error.
121 #define LOAD_FIELD(var, idx, fmt, error_stmt)               \
122   const DexFile::FieldId* var = CheckLoadFieldId(idx, fmt); \
123   if (UNLIKELY(var == nullptr)) {                           \
124     error_stmt;                                             \
125   }
126 
Verify(const DexFile * dex_file,const byte * begin,size_t size,const char * location,std::string * error_msg)127 bool DexFileVerifier::Verify(const DexFile* dex_file, const byte* begin, size_t size,
128                              const char* location, std::string* error_msg) {
129   std::unique_ptr<DexFileVerifier> verifier(new DexFileVerifier(dex_file, begin, size, location));
130   if (!verifier->Verify()) {
131     *error_msg = verifier->FailureReason();
132     return false;
133   }
134   return true;
135 }
136 
CheckShortyDescriptorMatch(char shorty_char,const char * descriptor,bool is_return_type)137 bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
138                                                 bool is_return_type) {
139   switch (shorty_char) {
140     case 'V':
141       if (UNLIKELY(!is_return_type)) {
142         ErrorStringPrintf("Invalid use of void");
143         return false;
144       }
145       // Intentional fallthrough.
146     case 'B':
147     case 'C':
148     case 'D':
149     case 'F':
150     case 'I':
151     case 'J':
152     case 'S':
153     case 'Z':
154       if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
155         ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
156                           shorty_char, descriptor);
157         return false;
158       }
159       break;
160     case 'L':
161       if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
162         ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
163         return false;
164       }
165       break;
166     default:
167       ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
168       return false;
169   }
170   return true;
171 }
172 
CheckListSize(const void * start,size_t count,size_t elem_size,const char * label)173 bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
174                                     const char* label) {
175   // Check that size is not 0.
176   CHECK_NE(elem_size, 0U);
177 
178   const byte* range_start = reinterpret_cast<const byte*>(start);
179   const byte* file_start = reinterpret_cast<const byte*>(begin_);
180 
181   // Check for overflow.
182   uintptr_t max = 0 - 1;
183   size_t available_bytes_till_end_of_mem = max - reinterpret_cast<uintptr_t>(start);
184   size_t max_count = available_bytes_till_end_of_mem / elem_size;
185   if (max_count < count) {
186     ErrorStringPrintf("Overflow in range for %s: %zx for %zu@%zu", label,
187                       static_cast<size_t>(range_start - file_start),
188                       count, elem_size);
189     return false;
190   }
191 
192   const byte* range_end = range_start + count * elem_size;
193   const byte* file_end = file_start + size_;
194   if (UNLIKELY((range_start < file_start) || (range_end > file_end))) {
195     // Note: these two tests are enough as we make sure above that there's no overflow.
196     ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
197                       static_cast<size_t>(range_start - file_start),
198                       static_cast<size_t>(range_end - file_start));
199     return false;
200   }
201   return true;
202 }
203 
CheckList(size_t element_size,const char * label,const byte ** ptr)204 bool DexFileVerifier::CheckList(size_t element_size, const char* label, const byte* *ptr) {
205   // Check that the list is available. The first 4B are the count.
206   if (!CheckListSize(*ptr, 1, 4U, label)) {
207     return false;
208   }
209 
210   uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
211   if (count > 0) {
212     if (!CheckListSize(*ptr + 4, count, element_size, label)) {
213       return false;
214     }
215   }
216 
217   *ptr += 4 + count * element_size;
218   return true;
219 }
220 
CheckIndex(uint32_t field,uint32_t limit,const char * label)221 bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
222   if (UNLIKELY(field >= limit)) {
223     ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
224     return false;
225   }
226   return true;
227 }
228 
CheckValidOffsetAndSize(uint32_t offset,uint32_t size,const char * label)229 bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset, uint32_t size, const char* label) {
230   if (size == 0) {
231     if (offset != 0) {
232       ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
233       return false;
234     }
235   }
236   if (size_ <= offset) {
237     ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
238     return false;
239   }
240   return true;
241 }
242 
CheckHeader()243 bool DexFileVerifier::CheckHeader() {
244   // Check file size from the header.
245   uint32_t expected_size = header_->file_size_;
246   if (size_ != expected_size) {
247     ErrorStringPrintf("Bad file size (%zd, expected %ud)", size_, expected_size);
248     return false;
249   }
250 
251   // Compute and verify the checksum in the header.
252   uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
253   const uint32_t non_sum = sizeof(header_->magic_) + sizeof(header_->checksum_);
254   const byte* non_sum_ptr = reinterpret_cast<const byte*>(header_) + non_sum;
255   adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
256   if (adler_checksum != header_->checksum_) {
257     ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
258     return false;
259   }
260 
261   // Check the contents of the header.
262   if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
263     ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
264     return false;
265   }
266 
267   if (header_->header_size_ != sizeof(DexFile::Header)) {
268     ErrorStringPrintf("Bad header size: %ud", header_->header_size_);
269     return false;
270   }
271 
272   // Check that all offsets are inside the file.
273   bool result =
274       CheckValidOffsetAndSize(header_->link_off_, header_->link_size_, "link") &&
275       CheckValidOffsetAndSize(header_->map_off_, header_->map_off_, "map") &&
276       CheckValidOffsetAndSize(header_->string_ids_off_, header_->string_ids_size_, "string-ids") &&
277       CheckValidOffsetAndSize(header_->type_ids_off_, header_->type_ids_size_, "type-ids") &&
278       CheckValidOffsetAndSize(header_->proto_ids_off_, header_->proto_ids_size_, "proto-ids") &&
279       CheckValidOffsetAndSize(header_->field_ids_off_, header_->field_ids_size_, "field-ids") &&
280       CheckValidOffsetAndSize(header_->method_ids_off_, header_->method_ids_size_, "method-ids") &&
281       CheckValidOffsetAndSize(header_->class_defs_off_, header_->class_defs_size_, "class-defs") &&
282       CheckValidOffsetAndSize(header_->data_off_, header_->data_size_, "data");
283 
284   return result;
285 }
286 
CheckMap()287 bool DexFileVerifier::CheckMap() {
288   const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ +
289                                                                           header_->map_off_);
290   // Check that map list content is available.
291   if (!CheckListSize(map, 1, sizeof(DexFile::MapList), "maplist content")) {
292     return false;
293   }
294 
295   const DexFile::MapItem* item = map->list_;
296 
297   uint32_t count = map->size_;
298   uint32_t last_offset = 0;
299   uint32_t data_item_count = 0;
300   uint32_t data_items_left = header_->data_size_;
301   uint32_t used_bits = 0;
302 
303   // Sanity check the size of the map list.
304   if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
305     return false;
306   }
307 
308   // Check the items listed in the map.
309   for (uint32_t i = 0; i < count; i++) {
310     if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
311       ErrorStringPrintf("Out of order map item: %x then %x", last_offset, item->offset_);
312       return false;
313     }
314     if (UNLIKELY(item->offset_ >= header_->file_size_)) {
315       ErrorStringPrintf("Map item after end of file: %x, size %x",
316                         item->offset_, header_->file_size_);
317       return false;
318     }
319 
320     if (IsDataSectionType(item->type_)) {
321       uint32_t icount = item->size_;
322       if (UNLIKELY(icount > data_items_left)) {
323         ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
324         return false;
325       }
326       data_items_left -= icount;
327       data_item_count += icount;
328     }
329 
330     uint32_t bit = MapTypeToBitMask(item->type_);
331 
332     if (UNLIKELY(bit == 0)) {
333       ErrorStringPrintf("Unknown map section type %x", item->type_);
334       return false;
335     }
336 
337     if (UNLIKELY((used_bits & bit) != 0)) {
338       ErrorStringPrintf("Duplicate map section of type %x", item->type_);
339       return false;
340     }
341 
342     used_bits |= bit;
343     last_offset = item->offset_;
344     item++;
345   }
346 
347   // Check for missing sections in the map.
348   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
349     ErrorStringPrintf("Map is missing header entry");
350     return false;
351   }
352   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
353     ErrorStringPrintf("Map is missing map_list entry");
354     return false;
355   }
356   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
357                ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
358     ErrorStringPrintf("Map is missing string_ids entry");
359     return false;
360   }
361   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
362                ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
363     ErrorStringPrintf("Map is missing type_ids entry");
364     return false;
365   }
366   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
367                ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
368     ErrorStringPrintf("Map is missing proto_ids entry");
369     return false;
370   }
371   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
372                ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
373     ErrorStringPrintf("Map is missing field_ids entry");
374     return false;
375   }
376   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
377                ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
378     ErrorStringPrintf("Map is missing method_ids entry");
379     return false;
380   }
381   if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
382                ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
383     ErrorStringPrintf("Map is missing class_defs entry");
384     return false;
385   }
386   return true;
387 }
388 
ReadUnsignedLittleEndian(uint32_t size)389 uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
390   uint32_t result = 0;
391   if (LIKELY(CheckListSize(ptr_, size, sizeof(byte), "encoded_value"))) {
392     for (uint32_t i = 0; i < size; i++) {
393       result |= ((uint32_t) *(ptr_++)) << (i * 8);
394     }
395   }
396   return result;
397 }
398 
CheckAndGetHandlerOffsets(const DexFile::CodeItem * code_item,uint32_t * handler_offsets,uint32_t handlers_size)399 bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
400                                                 uint32_t* handler_offsets, uint32_t handlers_size) {
401   const byte* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
402 
403   for (uint32_t i = 0; i < handlers_size; i++) {
404     bool catch_all;
405     size_t offset = ptr_ - handlers_base;
406     int32_t size = DecodeSignedLeb128(&ptr_);
407 
408     if (UNLIKELY((size < -65536) || (size > 65536))) {
409       ErrorStringPrintf("Invalid exception handler size: %d", size);
410       return false;
411     }
412 
413     if (size <= 0) {
414       catch_all = true;
415       size = -size;
416     } else {
417       catch_all = false;
418     }
419 
420     handler_offsets[i] = static_cast<uint32_t>(offset);
421 
422     while (size-- > 0) {
423       uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
424       if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
425         return false;
426       }
427 
428       uint32_t addr = DecodeUnsignedLeb128(&ptr_);
429       if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
430         ErrorStringPrintf("Invalid handler addr: %x", addr);
431         return false;
432       }
433     }
434 
435     if (catch_all) {
436       uint32_t addr = DecodeUnsignedLeb128(&ptr_);
437       if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
438         ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
439         return false;
440       }
441     }
442   }
443 
444   return true;
445 }
446 
CheckClassDataItemField(uint32_t idx,uint32_t access_flags,bool expect_static)447 bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, uint32_t access_flags,
448                                               bool expect_static) {
449   if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
450     return false;
451   }
452 
453   bool is_static = (access_flags & kAccStatic) != 0;
454   if (UNLIKELY(is_static != expect_static)) {
455     ErrorStringPrintf("Static/instance field not in expected list");
456     return false;
457   }
458 
459   if (UNLIKELY((access_flags & ~kAccJavaFlagsMask) != 0)) {
460     ErrorStringPrintf("Bad class_data_item field access_flags %x", access_flags);
461     return false;
462   }
463 
464   return true;
465 }
466 
CheckClassDataItemMethod(uint32_t idx,uint32_t access_flags,uint32_t code_offset,bool expect_direct)467 bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags,
468                                                uint32_t code_offset, bool expect_direct) {
469   if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
470     return false;
471   }
472 
473   bool is_direct = (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
474   bool expect_code = (access_flags & (kAccNative | kAccAbstract)) == 0;
475   bool is_synchronized = (access_flags & kAccSynchronized) != 0;
476   bool allow_synchronized = (access_flags & kAccNative) != 0;
477 
478   if (UNLIKELY(is_direct != expect_direct)) {
479     ErrorStringPrintf("Direct/virtual method not in expected list");
480     return false;
481   }
482 
483   constexpr uint32_t access_method_mask = kAccJavaFlagsMask | kAccConstructor |
484       kAccDeclaredSynchronized;
485   if (UNLIKELY(((access_flags & ~access_method_mask) != 0) ||
486                (is_synchronized && !allow_synchronized))) {
487     ErrorStringPrintf("Bad class_data_item method access_flags %x", access_flags);
488     return false;
489   }
490 
491   if (UNLIKELY(expect_code && (code_offset == 0))) {
492     ErrorStringPrintf("Unexpected zero value for class_data_item method code_off with access "
493                       "flags %x", access_flags);
494     return false;
495   } else if (UNLIKELY(!expect_code && (code_offset != 0))) {
496     ErrorStringPrintf("Unexpected non-zero value %x for class_data_item method code_off"
497                       " with access flags %x", code_offset, access_flags);
498     return false;
499   }
500 
501   return true;
502 }
503 
CheckPadding(size_t offset,uint32_t aligned_offset)504 bool DexFileVerifier::CheckPadding(size_t offset, uint32_t aligned_offset) {
505   if (offset < aligned_offset) {
506     if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(byte), "section")) {
507       return false;
508     }
509     while (offset < aligned_offset) {
510       if (UNLIKELY(*ptr_ != '\0')) {
511         ErrorStringPrintf("Non-zero padding %x before section start at %zx", *ptr_, offset);
512         return false;
513       }
514       ptr_++;
515       offset++;
516     }
517   }
518   return true;
519 }
520 
CheckEncodedValue()521 bool DexFileVerifier::CheckEncodedValue() {
522   if (!CheckListSize(ptr_, 1, sizeof(byte), "encoded_value header")) {
523     return false;
524   }
525 
526   uint8_t header_byte = *(ptr_++);
527   uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
528   uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
529 
530   switch (value_type) {
531     case DexFile::kDexAnnotationByte:
532       if (UNLIKELY(value_arg != 0)) {
533         ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
534         return false;
535       }
536       ptr_++;
537       break;
538     case DexFile::kDexAnnotationShort:
539     case DexFile::kDexAnnotationChar:
540       if (UNLIKELY(value_arg > 1)) {
541         ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
542         return false;
543       }
544       ptr_ += value_arg + 1;
545       break;
546     case DexFile::kDexAnnotationInt:
547     case DexFile::kDexAnnotationFloat:
548       if (UNLIKELY(value_arg > 3)) {
549         ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
550         return false;
551       }
552       ptr_ += value_arg + 1;
553       break;
554     case DexFile::kDexAnnotationLong:
555     case DexFile::kDexAnnotationDouble:
556       ptr_ += value_arg + 1;
557       break;
558     case DexFile::kDexAnnotationString: {
559       if (UNLIKELY(value_arg > 3)) {
560         ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
561         return false;
562       }
563       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
564       if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
565         return false;
566       }
567       break;
568     }
569     case DexFile::kDexAnnotationType: {
570       if (UNLIKELY(value_arg > 3)) {
571         ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
572         return false;
573       }
574       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
575       if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
576         return false;
577       }
578       break;
579     }
580     case DexFile::kDexAnnotationField:
581     case DexFile::kDexAnnotationEnum: {
582       if (UNLIKELY(value_arg > 3)) {
583         ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
584         return false;
585       }
586       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
587       if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
588         return false;
589       }
590       break;
591     }
592     case DexFile::kDexAnnotationMethod: {
593       if (UNLIKELY(value_arg > 3)) {
594         ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
595         return false;
596       }
597       uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
598       if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
599         return false;
600       }
601       break;
602     }
603     case DexFile::kDexAnnotationArray:
604       if (UNLIKELY(value_arg != 0)) {
605         ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
606         return false;
607       }
608       if (!CheckEncodedArray()) {
609         return false;
610       }
611       break;
612     case DexFile::kDexAnnotationAnnotation:
613       if (UNLIKELY(value_arg != 0)) {
614         ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
615         return false;
616       }
617       if (!CheckEncodedAnnotation()) {
618         return false;
619       }
620       break;
621     case DexFile::kDexAnnotationNull:
622       if (UNLIKELY(value_arg != 0)) {
623         ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
624         return false;
625       }
626       break;
627     case DexFile::kDexAnnotationBoolean:
628       if (UNLIKELY(value_arg > 1)) {
629         ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
630         return false;
631       }
632       break;
633     default:
634       ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
635       return false;
636   }
637 
638   return true;
639 }
640 
CheckEncodedArray()641 bool DexFileVerifier::CheckEncodedArray() {
642   uint32_t size = DecodeUnsignedLeb128(&ptr_);
643 
644   while (size--) {
645     if (!CheckEncodedValue()) {
646       failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
647       return false;
648     }
649   }
650   return true;
651 }
652 
CheckEncodedAnnotation()653 bool DexFileVerifier::CheckEncodedAnnotation() {
654   uint32_t idx = DecodeUnsignedLeb128(&ptr_);
655   if (!CheckIndex(idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
656     return false;
657   }
658 
659   uint32_t size = DecodeUnsignedLeb128(&ptr_);
660   uint32_t last_idx = 0;
661 
662   for (uint32_t i = 0; i < size; i++) {
663     idx = DecodeUnsignedLeb128(&ptr_);
664     if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
665       return false;
666     }
667 
668     if (UNLIKELY(last_idx >= idx && i != 0)) {
669       ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
670                         last_idx, idx);
671       return false;
672     }
673 
674     if (!CheckEncodedValue()) {
675       return false;
676     }
677 
678     last_idx = idx;
679   }
680   return true;
681 }
682 
CheckIntraClassDataItem()683 bool DexFileVerifier::CheckIntraClassDataItem() {
684   ClassDataItemIterator it(*dex_file_, ptr_);
685 
686   // These calls use the raw access flags to check whether the whole dex field is valid.
687 
688   for (; it.HasNextStaticField(); it.Next()) {
689     if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), true)) {
690       return false;
691     }
692   }
693   for (; it.HasNextInstanceField(); it.Next()) {
694     if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), false)) {
695       return false;
696     }
697   }
698   for (; it.HasNextDirectMethod(); it.Next()) {
699     if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
700         it.GetMethodCodeItemOffset(), true)) {
701       return false;
702     }
703   }
704   for (; it.HasNextVirtualMethod(); it.Next()) {
705     if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
706         it.GetMethodCodeItemOffset(), false)) {
707       return false;
708     }
709   }
710 
711   ptr_ = it.EndDataPointer();
712   return true;
713 }
714 
CheckIntraCodeItem()715 bool DexFileVerifier::CheckIntraCodeItem() {
716   const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
717   if (!CheckListSize(code_item, 1, sizeof(DexFile::CodeItem), "code")) {
718     return false;
719   }
720 
721   if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
722     ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
723                       code_item->ins_size_, code_item->registers_size_);
724     return false;
725   }
726 
727   if (UNLIKELY((code_item->outs_size_ > 5) &&
728                (code_item->outs_size_ > code_item->registers_size_))) {
729     /*
730      * outs_size can be up to 5, even if registers_size is smaller, since the
731      * short forms of method invocation allow repetitions of a register multiple
732      * times within a single parameter list. However, longer parameter lists
733      * need to be represented in-order in the register file.
734      */
735     ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
736                       code_item->outs_size_, code_item->registers_size_);
737     return false;
738   }
739 
740   const uint16_t* insns = code_item->insns_;
741   uint32_t insns_size = code_item->insns_size_in_code_units_;
742   if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
743     return false;
744   }
745 
746   // Grab the end of the insns if there are no try_items.
747   uint32_t try_items_size = code_item->tries_size_;
748   if (try_items_size == 0) {
749     ptr_ = reinterpret_cast<const byte*>(&insns[insns_size]);
750     return true;
751   }
752 
753   // try_items are 4-byte aligned. Verify the spacer is 0.
754   if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
755     ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
756     return false;
757   }
758 
759   const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
760   ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
761   uint32_t handlers_size = DecodeUnsignedLeb128(&ptr_);
762 
763   if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
764     return false;
765   }
766 
767   if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
768     ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
769     return false;
770   }
771 
772   std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
773   if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
774     return false;
775   }
776 
777   uint32_t last_addr = 0;
778   while (try_items_size--) {
779     if (UNLIKELY(try_items->start_addr_ < last_addr)) {
780       ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
781       return false;
782     }
783 
784     if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
785       ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
786       return false;
787     }
788 
789     uint32_t i;
790     for (i = 0; i < handlers_size; i++) {
791       if (try_items->handler_off_ == handler_offsets[i]) {
792         break;
793       }
794     }
795 
796     if (UNLIKELY(i == handlers_size)) {
797       ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
798       return false;
799     }
800 
801     last_addr = try_items->start_addr_ + try_items->insn_count_;
802     if (UNLIKELY(last_addr > insns_size)) {
803       ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
804       return false;
805     }
806 
807     try_items++;
808   }
809 
810   return true;
811 }
812 
CheckIntraStringDataItem()813 bool DexFileVerifier::CheckIntraStringDataItem() {
814   uint32_t size = DecodeUnsignedLeb128(&ptr_);
815   const byte* file_end = begin_ + size_;
816 
817   for (uint32_t i = 0; i < size; i++) {
818     CHECK_LT(i, size);  // b/15014252 Prevents hitting the impossible case below
819     if (UNLIKELY(ptr_ >= file_end)) {
820       ErrorStringPrintf("String data would go beyond end-of-file");
821       return false;
822     }
823 
824     uint8_t byte = *(ptr_++);
825 
826     // Switch on the high 4 bits.
827     switch (byte >> 4) {
828       case 0x00:
829         // Special case of bit pattern 0xxx.
830         if (UNLIKELY(byte == 0)) {
831           CHECK_LT(i, size);  // b/15014252 Actually hit this impossible case with clang
832           ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
833           return false;
834         }
835         break;
836       case 0x01:
837       case 0x02:
838       case 0x03:
839       case 0x04:
840       case 0x05:
841       case 0x06:
842       case 0x07:
843         // No extra checks necessary for bit pattern 0xxx.
844         break;
845       case 0x08:
846       case 0x09:
847       case 0x0a:
848       case 0x0b:
849       case 0x0f:
850         // Illegal bit patterns 10xx or 1111.
851         // Note: 1111 is valid for normal UTF-8, but not here.
852         ErrorStringPrintf("Illegal start byte %x in string data", byte);
853         return false;
854       case 0x0c:
855       case 0x0d: {
856         // Bit pattern 110x has an additional byte.
857         uint8_t byte2 = *(ptr_++);
858         if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
859           ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
860           return false;
861         }
862         uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
863         if (UNLIKELY((value != 0) && (value < 0x80))) {
864           ErrorStringPrintf("Illegal representation for value %x in string data", value);
865           return false;
866         }
867         break;
868       }
869       case 0x0e: {
870         // Bit pattern 1110 has 2 additional bytes.
871         uint8_t byte2 = *(ptr_++);
872         if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
873           ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
874           return false;
875         }
876         uint8_t byte3 = *(ptr_++);
877         if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
878           ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
879           return false;
880         }
881         uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
882         if (UNLIKELY(value < 0x800)) {
883           ErrorStringPrintf("Illegal representation for value %x in string data", value);
884           return false;
885         }
886         break;
887       }
888     }
889   }
890 
891   if (UNLIKELY(*(ptr_++) != '\0')) {
892     ErrorStringPrintf("String longer than indicated size %x", size);
893     return false;
894   }
895 
896   return true;
897 }
898 
CheckIntraDebugInfoItem()899 bool DexFileVerifier::CheckIntraDebugInfoItem() {
900   DecodeUnsignedLeb128(&ptr_);
901   uint32_t parameters_size = DecodeUnsignedLeb128(&ptr_);
902   if (UNLIKELY(parameters_size > 65536)) {
903     ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
904     return false;
905   }
906 
907   for (uint32_t j = 0; j < parameters_size; j++) {
908     uint32_t parameter_name = DecodeUnsignedLeb128(&ptr_);
909     if (parameter_name != 0) {
910       parameter_name--;
911       if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
912         return false;
913       }
914     }
915   }
916 
917   while (true) {
918     uint8_t opcode = *(ptr_++);
919     switch (opcode) {
920       case DexFile::DBG_END_SEQUENCE: {
921         return true;
922       }
923       case DexFile::DBG_ADVANCE_PC: {
924         DecodeUnsignedLeb128(&ptr_);
925         break;
926       }
927       case DexFile::DBG_ADVANCE_LINE: {
928         DecodeSignedLeb128(&ptr_);
929         break;
930       }
931       case DexFile::DBG_START_LOCAL: {
932         uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
933         if (UNLIKELY(reg_num >= 65536)) {
934           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
935           return false;
936         }
937         uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
938         if (name_idx != 0) {
939           name_idx--;
940           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
941             return false;
942           }
943         }
944         uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
945         if (type_idx != 0) {
946           type_idx--;
947           if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL type_idx")) {
948             return false;
949           }
950         }
951         break;
952       }
953       case DexFile::DBG_END_LOCAL:
954       case DexFile::DBG_RESTART_LOCAL: {
955         uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
956         if (UNLIKELY(reg_num >= 65536)) {
957           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
958           return false;
959         }
960         break;
961       }
962       case DexFile::DBG_START_LOCAL_EXTENDED: {
963         uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
964         if (UNLIKELY(reg_num >= 65536)) {
965           ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
966           return false;
967         }
968         uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
969         if (name_idx != 0) {
970           name_idx--;
971           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
972             return false;
973           }
974         }
975         uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
976         if (type_idx != 0) {
977           type_idx--;
978           if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
979             return false;
980           }
981         }
982         uint32_t sig_idx = DecodeUnsignedLeb128(&ptr_);
983         if (sig_idx != 0) {
984           sig_idx--;
985           if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
986             return false;
987           }
988         }
989         break;
990       }
991       case DexFile::DBG_SET_FILE: {
992         uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
993         if (name_idx != 0) {
994           name_idx--;
995           if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
996             return false;
997           }
998         }
999         break;
1000       }
1001     }
1002   }
1003 }
1004 
CheckIntraAnnotationItem()1005 bool DexFileVerifier::CheckIntraAnnotationItem() {
1006   if (!CheckListSize(ptr_, 1, sizeof(byte), "annotation visibility")) {
1007     return false;
1008   }
1009 
1010   // Check visibility
1011   switch (*(ptr_++)) {
1012     case DexFile::kDexVisibilityBuild:
1013     case DexFile::kDexVisibilityRuntime:
1014     case DexFile::kDexVisibilitySystem:
1015       break;
1016     default:
1017       ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
1018       return false;
1019   }
1020 
1021   if (!CheckEncodedAnnotation()) {
1022     return false;
1023   }
1024 
1025   return true;
1026 }
1027 
CheckIntraAnnotationsDirectoryItem()1028 bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1029   const DexFile::AnnotationsDirectoryItem* item =
1030       reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
1031   if (!CheckListSize(item, 1, sizeof(DexFile::AnnotationsDirectoryItem), "annotations_directory")) {
1032     return false;
1033   }
1034 
1035   // Field annotations follow immediately after the annotations directory.
1036   const DexFile::FieldAnnotationsItem* field_item =
1037       reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1038   uint32_t field_count = item->fields_size_;
1039   if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
1040     return false;
1041   }
1042 
1043   uint32_t last_idx = 0;
1044   for (uint32_t i = 0; i < field_count; i++) {
1045     if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1046       ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
1047       return false;
1048     }
1049     last_idx = field_item->field_idx_;
1050     field_item++;
1051   }
1052 
1053   // Method annotations follow immediately after field annotations.
1054   const DexFile::MethodAnnotationsItem* method_item =
1055       reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1056   uint32_t method_count = item->methods_size_;
1057   if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1058     return false;
1059   }
1060 
1061   last_idx = 0;
1062   for (uint32_t i = 0; i < method_count; i++) {
1063     if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1064       ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1065                        last_idx, method_item->method_idx_);
1066       return false;
1067     }
1068     last_idx = method_item->method_idx_;
1069     method_item++;
1070   }
1071 
1072   // Parameter annotations follow immediately after method annotations.
1073   const DexFile::ParameterAnnotationsItem* parameter_item =
1074       reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1075   uint32_t parameter_count = item->parameters_size_;
1076   if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
1077                      "parameter_annotations list")) {
1078     return false;
1079   }
1080 
1081   last_idx = 0;
1082   for (uint32_t i = 0; i < parameter_count; i++) {
1083     if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1084       ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1085                         last_idx, parameter_item->method_idx_);
1086       return false;
1087     }
1088     last_idx = parameter_item->method_idx_;
1089     parameter_item++;
1090   }
1091 
1092   // Return a pointer to the end of the annotations.
1093   ptr_ = reinterpret_cast<const byte*>(parameter_item);
1094   return true;
1095 }
1096 
CheckIntraSectionIterate(size_t offset,uint32_t section_count,uint16_t type)1097 bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
1098                                                uint16_t type) {
1099   // Get the right alignment mask for the type of section.
1100   size_t alignment_mask;
1101   switch (type) {
1102     case DexFile::kDexTypeClassDataItem:
1103     case DexFile::kDexTypeStringDataItem:
1104     case DexFile::kDexTypeDebugInfoItem:
1105     case DexFile::kDexTypeAnnotationItem:
1106     case DexFile::kDexTypeEncodedArrayItem:
1107       alignment_mask = sizeof(uint8_t) - 1;
1108       break;
1109     default:
1110       alignment_mask = sizeof(uint32_t) - 1;
1111       break;
1112   }
1113 
1114   // Iterate through the items in the section.
1115   for (uint32_t i = 0; i < section_count; i++) {
1116     size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
1117 
1118     // Check the padding between items.
1119     if (!CheckPadding(offset, aligned_offset)) {
1120       return false;
1121     }
1122 
1123     // Check depending on the section type.
1124     switch (type) {
1125       case DexFile::kDexTypeStringIdItem: {
1126         if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
1127           return false;
1128         }
1129         ptr_ += sizeof(DexFile::StringId);
1130         break;
1131       }
1132       case DexFile::kDexTypeTypeIdItem: {
1133         if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
1134           return false;
1135         }
1136         ptr_ += sizeof(DexFile::TypeId);
1137         break;
1138       }
1139       case DexFile::kDexTypeProtoIdItem: {
1140         if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
1141           return false;
1142         }
1143         ptr_ += sizeof(DexFile::ProtoId);
1144         break;
1145       }
1146       case DexFile::kDexTypeFieldIdItem: {
1147         if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
1148           return false;
1149         }
1150         ptr_ += sizeof(DexFile::FieldId);
1151         break;
1152       }
1153       case DexFile::kDexTypeMethodIdItem: {
1154         if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
1155           return false;
1156         }
1157         ptr_ += sizeof(DexFile::MethodId);
1158         break;
1159       }
1160       case DexFile::kDexTypeClassDefItem: {
1161         if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
1162           return false;
1163         }
1164         ptr_ += sizeof(DexFile::ClassDef);
1165         break;
1166       }
1167       case DexFile::kDexTypeTypeList: {
1168         if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
1169           return false;
1170         }
1171         break;
1172       }
1173       case DexFile::kDexTypeAnnotationSetRefList: {
1174         if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
1175           return false;
1176         }
1177         break;
1178       }
1179       case DexFile::kDexTypeAnnotationSetItem: {
1180         if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
1181           return false;
1182         }
1183         break;
1184       }
1185       case DexFile::kDexTypeClassDataItem: {
1186         if (!CheckIntraClassDataItem()) {
1187           return false;
1188         }
1189         break;
1190       }
1191       case DexFile::kDexTypeCodeItem: {
1192         if (!CheckIntraCodeItem()) {
1193           return false;
1194         }
1195         break;
1196       }
1197       case DexFile::kDexTypeStringDataItem: {
1198         if (!CheckIntraStringDataItem()) {
1199           return false;
1200         }
1201         break;
1202       }
1203       case DexFile::kDexTypeDebugInfoItem: {
1204         if (!CheckIntraDebugInfoItem()) {
1205           return false;
1206         }
1207         break;
1208       }
1209       case DexFile::kDexTypeAnnotationItem: {
1210         if (!CheckIntraAnnotationItem()) {
1211           return false;
1212         }
1213         break;
1214       }
1215       case DexFile::kDexTypeEncodedArrayItem: {
1216         if (!CheckEncodedArray()) {
1217           return false;
1218         }
1219         break;
1220       }
1221       case DexFile::kDexTypeAnnotationsDirectoryItem: {
1222         if (!CheckIntraAnnotationsDirectoryItem()) {
1223           return false;
1224         }
1225         break;
1226       }
1227       default:
1228         ErrorStringPrintf("Unknown map item type %x", type);
1229         return false;
1230     }
1231 
1232     if (IsDataSectionType(type)) {
1233       offset_to_type_map_.Put(aligned_offset, type);
1234     }
1235 
1236     aligned_offset = ptr_ - begin_;
1237     if (UNLIKELY(aligned_offset > size_)) {
1238       ErrorStringPrintf("Item %d at ends out of bounds", i);
1239       return false;
1240     }
1241 
1242     offset = aligned_offset;
1243   }
1244 
1245   return true;
1246 }
1247 
CheckIntraIdSection(size_t offset,uint32_t count,uint16_t type)1248 bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
1249   uint32_t expected_offset;
1250   uint32_t expected_size;
1251 
1252   // Get the expected offset and size from the header.
1253   switch (type) {
1254     case DexFile::kDexTypeStringIdItem:
1255       expected_offset = header_->string_ids_off_;
1256       expected_size = header_->string_ids_size_;
1257       break;
1258     case DexFile::kDexTypeTypeIdItem:
1259       expected_offset = header_->type_ids_off_;
1260       expected_size = header_->type_ids_size_;
1261       break;
1262     case DexFile::kDexTypeProtoIdItem:
1263       expected_offset = header_->proto_ids_off_;
1264       expected_size = header_->proto_ids_size_;
1265       break;
1266     case DexFile::kDexTypeFieldIdItem:
1267       expected_offset = header_->field_ids_off_;
1268       expected_size = header_->field_ids_size_;
1269       break;
1270     case DexFile::kDexTypeMethodIdItem:
1271       expected_offset = header_->method_ids_off_;
1272       expected_size = header_->method_ids_size_;
1273       break;
1274     case DexFile::kDexTypeClassDefItem:
1275       expected_offset = header_->class_defs_off_;
1276       expected_size = header_->class_defs_size_;
1277       break;
1278     default:
1279       ErrorStringPrintf("Bad type for id section: %x", type);
1280       return false;
1281   }
1282 
1283   // Check that the offset and size are what were expected from the header.
1284   if (UNLIKELY(offset != expected_offset)) {
1285     ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
1286     return false;
1287   }
1288   if (UNLIKELY(count != expected_size)) {
1289     ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
1290     return false;
1291   }
1292 
1293   return CheckIntraSectionIterate(offset, count, type);
1294 }
1295 
CheckIntraDataSection(size_t offset,uint32_t count,uint16_t type)1296 bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
1297   size_t data_start = header_->data_off_;
1298   size_t data_end = data_start + header_->data_size_;
1299 
1300   // Sanity check the offset of the section.
1301   if (UNLIKELY((offset < data_start) || (offset > data_end))) {
1302     ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
1303     return false;
1304   }
1305 
1306   if (!CheckIntraSectionIterate(offset, count, type)) {
1307     return false;
1308   }
1309 
1310   size_t next_offset = ptr_ - begin_;
1311   if (next_offset > data_end) {
1312     ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset);
1313     return false;
1314   }
1315 
1316   return true;
1317 }
1318 
CheckIntraSection()1319 bool DexFileVerifier::CheckIntraSection() {
1320   const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
1321   const DexFile::MapItem* item = map->list_;
1322 
1323   uint32_t count = map->size_;
1324   size_t offset = 0;
1325   ptr_ = begin_;
1326 
1327   // Check the items listed in the map.
1328   while (count--) {
1329     uint32_t section_offset = item->offset_;
1330     uint32_t section_count = item->size_;
1331     uint16_t type = item->type_;
1332 
1333     // Check for padding and overlap between items.
1334     if (!CheckPadding(offset, section_offset)) {
1335       return false;
1336     } else if (UNLIKELY(offset > section_offset)) {
1337       ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
1338       return false;
1339     }
1340 
1341     // Check each item based on its type.
1342     switch (type) {
1343       case DexFile::kDexTypeHeaderItem:
1344         if (UNLIKELY(section_count != 1)) {
1345           ErrorStringPrintf("Multiple header items");
1346           return false;
1347         }
1348         if (UNLIKELY(section_offset != 0)) {
1349           ErrorStringPrintf("Header at %x, not at start of file", section_offset);
1350           return false;
1351         }
1352         ptr_ = begin_ + header_->header_size_;
1353         offset = header_->header_size_;
1354         break;
1355       case DexFile::kDexTypeStringIdItem:
1356       case DexFile::kDexTypeTypeIdItem:
1357       case DexFile::kDexTypeProtoIdItem:
1358       case DexFile::kDexTypeFieldIdItem:
1359       case DexFile::kDexTypeMethodIdItem:
1360       case DexFile::kDexTypeClassDefItem:
1361         if (!CheckIntraIdSection(section_offset, section_count, type)) {
1362           return false;
1363         }
1364         offset = ptr_ - begin_;
1365         break;
1366       case DexFile::kDexTypeMapList:
1367         if (UNLIKELY(section_count != 1)) {
1368           ErrorStringPrintf("Multiple map list items");
1369           return false;
1370         }
1371         if (UNLIKELY(section_offset != header_->map_off_)) {
1372           ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1373                             section_offset, header_->map_off_);
1374           return false;
1375         }
1376         ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1377         offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1378         break;
1379       case DexFile::kDexTypeTypeList:
1380       case DexFile::kDexTypeAnnotationSetRefList:
1381       case DexFile::kDexTypeAnnotationSetItem:
1382       case DexFile::kDexTypeClassDataItem:
1383       case DexFile::kDexTypeCodeItem:
1384       case DexFile::kDexTypeStringDataItem:
1385       case DexFile::kDexTypeDebugInfoItem:
1386       case DexFile::kDexTypeAnnotationItem:
1387       case DexFile::kDexTypeEncodedArrayItem:
1388       case DexFile::kDexTypeAnnotationsDirectoryItem:
1389         if (!CheckIntraDataSection(section_offset, section_count, type)) {
1390           return false;
1391         }
1392         offset = ptr_ - begin_;
1393         break;
1394       default:
1395         ErrorStringPrintf("Unknown map item type %x", type);
1396         return false;
1397     }
1398 
1399     item++;
1400   }
1401 
1402   return true;
1403 }
1404 
CheckOffsetToTypeMap(size_t offset,uint16_t type)1405 bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
1406   auto it = offset_to_type_map_.find(offset);
1407   if (UNLIKELY(it == offset_to_type_map_.end())) {
1408     ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
1409     return false;
1410   }
1411   if (UNLIKELY(it->second != type)) {
1412     ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
1413                       offset, type, it->second);
1414     return false;
1415   }
1416   return true;
1417 }
1418 
FindFirstClassDataDefiner(const byte * ptr,bool * success)1419 uint16_t DexFileVerifier::FindFirstClassDataDefiner(const byte* ptr, bool* success) {
1420   ClassDataItemIterator it(*dex_file_, ptr);
1421   *success = true;
1422 
1423   if (it.HasNextStaticField() || it.HasNextInstanceField()) {
1424     LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
1425                *success = false; return DexFile::kDexNoIndex16)
1426     return field->class_idx_;
1427   }
1428 
1429   if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
1430     LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
1431                 *success = false; return DexFile::kDexNoIndex16)
1432     return method->class_idx_;
1433   }
1434 
1435   return DexFile::kDexNoIndex16;
1436 }
1437 
FindFirstAnnotationsDirectoryDefiner(const byte * ptr,bool * success)1438 uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const byte* ptr, bool* success) {
1439   const DexFile::AnnotationsDirectoryItem* item =
1440       reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
1441   *success = true;
1442 
1443   if (item->fields_size_ != 0) {
1444     DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
1445     LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
1446                *success = false; return DexFile::kDexNoIndex16)
1447     return field->class_idx_;
1448   }
1449 
1450   if (item->methods_size_ != 0) {
1451     DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
1452     LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
1453                 *success = false; return DexFile::kDexNoIndex16)
1454     return method->class_idx_;
1455   }
1456 
1457   if (item->parameters_size_ != 0) {
1458     DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
1459     LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
1460                 *success = false; return DexFile::kDexNoIndex16)
1461     return method->class_idx_;
1462   }
1463 
1464   return DexFile::kDexNoIndex16;
1465 }
1466 
CheckInterStringIdItem()1467 bool DexFileVerifier::CheckInterStringIdItem() {
1468   const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
1469 
1470   // Check the map to make sure it has the right offset->type.
1471   if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
1472     return false;
1473   }
1474 
1475   // Check ordering between items.
1476   if (previous_item_ != NULL) {
1477     const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
1478     const char* prev_str = dex_file_->GetStringData(*prev_item);
1479     const char* str = dex_file_->GetStringData(*item);
1480     if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
1481       ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
1482       return false;
1483     }
1484   }
1485 
1486   ptr_ += sizeof(DexFile::StringId);
1487   return true;
1488 }
1489 
CheckInterTypeIdItem()1490 bool DexFileVerifier::CheckInterTypeIdItem() {
1491   const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
1492 
1493   LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
1494 
1495   // Check that the descriptor is a valid type.
1496   if (UNLIKELY(!IsValidDescriptor(descriptor))) {
1497     ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
1498     return false;
1499   }
1500 
1501   // Check ordering between items.
1502   if (previous_item_ != NULL) {
1503     const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
1504     if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
1505       ErrorStringPrintf("Out-of-order type_ids: %x then %x",
1506                         prev_item->descriptor_idx_, item->descriptor_idx_);
1507       return false;
1508     }
1509   }
1510 
1511   ptr_ += sizeof(DexFile::TypeId);
1512   return true;
1513 }
1514 
CheckInterProtoIdItem()1515 bool DexFileVerifier::CheckInterProtoIdItem() {
1516   const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
1517 
1518   LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
1519 
1520   if (item->parameters_off_ != 0 &&
1521       !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
1522     return false;
1523   }
1524 
1525   // Check the return type and advance the shorty.
1526   LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
1527   if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
1528     return false;
1529   }
1530   shorty++;
1531 
1532   DexFileParameterIterator it(*dex_file_, *item);
1533   while (it.HasNext() && *shorty != '\0') {
1534     if (!CheckIndex(it.GetTypeIdx(), dex_file_->NumTypeIds(),
1535                     "inter_proto_id_item shorty type_idx")) {
1536       return false;
1537     }
1538     const char* descriptor = it.GetDescriptor();
1539     if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
1540       return false;
1541     }
1542     it.Next();
1543     shorty++;
1544   }
1545   if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
1546     ErrorStringPrintf("Mismatched length for parameters and shorty");
1547     return false;
1548   }
1549 
1550   // Check ordering between items. This relies on type_ids being in order.
1551   if (previous_item_ != NULL) {
1552     const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
1553     if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
1554       ErrorStringPrintf("Out-of-order proto_id return types");
1555       return false;
1556     } else if (prev->return_type_idx_ == item->return_type_idx_) {
1557       DexFileParameterIterator curr_it(*dex_file_, *item);
1558       DexFileParameterIterator prev_it(*dex_file_, *prev);
1559 
1560       while (curr_it.HasNext() && prev_it.HasNext()) {
1561         uint16_t prev_idx = prev_it.GetTypeIdx();
1562         uint16_t curr_idx = curr_it.GetTypeIdx();
1563         if (prev_idx == DexFile::kDexNoIndex16) {
1564           break;
1565         }
1566         if (UNLIKELY(curr_idx == DexFile::kDexNoIndex16)) {
1567           ErrorStringPrintf("Out-of-order proto_id arguments");
1568           return false;
1569         }
1570 
1571         if (prev_idx < curr_idx) {
1572           break;
1573         } else if (UNLIKELY(prev_idx > curr_idx)) {
1574           ErrorStringPrintf("Out-of-order proto_id arguments");
1575           return false;
1576         }
1577 
1578         prev_it.Next();
1579         curr_it.Next();
1580       }
1581     }
1582   }
1583 
1584   ptr_ += sizeof(DexFile::ProtoId);
1585   return true;
1586 }
1587 
CheckInterFieldIdItem()1588 bool DexFileVerifier::CheckInterFieldIdItem() {
1589   const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
1590 
1591   // Check that the class descriptor is valid.
1592   LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
1593   if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1594     ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
1595     return false;
1596   }
1597 
1598   // Check that the type descriptor is a valid field name.
1599   LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
1600   if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
1601     ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
1602     return false;
1603   }
1604 
1605   // Check that the name is valid.
1606   LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
1607   if (UNLIKELY(!IsValidMemberName(descriptor))) {
1608     ErrorStringPrintf("Invalid field name: '%s'", descriptor);
1609     return false;
1610   }
1611 
1612   // Check ordering between items. This relies on the other sections being in order.
1613   if (previous_item_ != NULL) {
1614     const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
1615     if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1616       ErrorStringPrintf("Out-of-order field_ids");
1617       return false;
1618     } else if (prev_item->class_idx_ == item->class_idx_) {
1619       if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1620         ErrorStringPrintf("Out-of-order field_ids");
1621         return false;
1622       } else if (prev_item->name_idx_ == item->name_idx_) {
1623         if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
1624           ErrorStringPrintf("Out-of-order field_ids");
1625           return false;
1626         }
1627       }
1628     }
1629   }
1630 
1631   ptr_ += sizeof(DexFile::FieldId);
1632   return true;
1633 }
1634 
CheckInterMethodIdItem()1635 bool DexFileVerifier::CheckInterMethodIdItem() {
1636   const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
1637 
1638   // Check that the class descriptor is a valid reference name.
1639   LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
1640   if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
1641                                                         class_descriptor[0] != '['))) {
1642     ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
1643     return false;
1644   }
1645 
1646   // Check that the name is valid.
1647   LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
1648   if (UNLIKELY(!IsValidMemberName(descriptor))) {
1649     ErrorStringPrintf("Invalid method name: '%s'", descriptor);
1650     return false;
1651   }
1652 
1653   // Check that the proto id is valid.
1654   if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
1655                            "inter_method_id_item proto_idx"))) {
1656     return false;
1657   }
1658 
1659   // Check ordering between items. This relies on the other sections being in order.
1660   if (previous_item_ != NULL) {
1661     const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
1662     if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1663       ErrorStringPrintf("Out-of-order method_ids");
1664       return false;
1665     } else if (prev_item->class_idx_ == item->class_idx_) {
1666       if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1667         ErrorStringPrintf("Out-of-order method_ids");
1668         return false;
1669       } else if (prev_item->name_idx_ == item->name_idx_) {
1670         if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
1671           ErrorStringPrintf("Out-of-order method_ids");
1672           return false;
1673         }
1674       }
1675     }
1676   }
1677 
1678   ptr_ += sizeof(DexFile::MethodId);
1679   return true;
1680 }
1681 
CheckInterClassDefItem()1682 bool DexFileVerifier::CheckInterClassDefItem() {
1683   const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
1684 
1685   // Check for duplicate class def.
1686   if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
1687     ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_);
1688     return false;
1689   }
1690   defined_classes_.insert(item->class_idx_);
1691 
1692   LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
1693   if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1694     ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
1695     return false;
1696   }
1697 
1698   // Only allow non-runtime modifiers.
1699   if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
1700     ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
1701     return false;
1702   }
1703 
1704   if (item->interfaces_off_ != 0 &&
1705       !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
1706     return false;
1707   }
1708   if (item->annotations_off_ != 0 &&
1709       !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
1710     return false;
1711   }
1712   if (item->class_data_off_ != 0 &&
1713       !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
1714     return false;
1715   }
1716   if (item->static_values_off_ != 0 &&
1717       !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
1718     return false;
1719   }
1720 
1721   if (item->superclass_idx_ != DexFile::kDexNoIndex16) {
1722     LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
1723                         "inter_class_def_item superclass_idx")
1724     if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
1725       ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
1726       return false;
1727     }
1728   }
1729 
1730   const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
1731   if (interfaces != NULL) {
1732     uint32_t size = interfaces->Size();
1733 
1734     // Ensure that all interfaces refer to classes (not arrays or primitives).
1735     for (uint32_t i = 0; i < size; i++) {
1736       LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
1737                           "inter_class_def_item interface type_idx")
1738       if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
1739         ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
1740         return false;
1741       }
1742     }
1743 
1744     /*
1745      * Ensure that there are no duplicates. This is an O(N^2) test, but in
1746      * practice the number of interfaces implemented by any given class is low.
1747      */
1748     for (uint32_t i = 1; i < size; i++) {
1749       uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_;
1750       for (uint32_t j =0; j < i; j++) {
1751         uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_;
1752         if (UNLIKELY(idx1 == idx2)) {
1753           ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
1754           return false;
1755         }
1756       }
1757     }
1758   }
1759 
1760   // Check that references in class_data_item are to the right class.
1761   if (item->class_data_off_ != 0) {
1762     const byte* data = begin_ + item->class_data_off_;
1763     bool success;
1764     uint16_t data_definer = FindFirstClassDataDefiner(data, &success);
1765     if (!success) {
1766       return false;
1767     }
1768     if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) {
1769       ErrorStringPrintf("Invalid class_data_item");
1770       return false;
1771     }
1772   }
1773 
1774   // Check that references in annotations_directory_item are to right class.
1775   if (item->annotations_off_ != 0) {
1776     const byte* data = begin_ + item->annotations_off_;
1777     bool success;
1778     uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
1779     if (!success) {
1780       return false;
1781     }
1782     if (UNLIKELY((annotations_definer != item->class_idx_) &&
1783                  (annotations_definer != DexFile::kDexNoIndex16))) {
1784       ErrorStringPrintf("Invalid annotations_directory_item");
1785       return false;
1786     }
1787   }
1788 
1789   ptr_ += sizeof(DexFile::ClassDef);
1790   return true;
1791 }
1792 
CheckInterAnnotationSetRefList()1793 bool DexFileVerifier::CheckInterAnnotationSetRefList() {
1794   const DexFile::AnnotationSetRefList* list =
1795       reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
1796   const DexFile::AnnotationSetRefItem* item = list->list_;
1797   uint32_t count = list->size_;
1798 
1799   while (count--) {
1800     if (item->annotations_off_ != 0 &&
1801         !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1802       return false;
1803     }
1804     item++;
1805   }
1806 
1807   ptr_ = reinterpret_cast<const byte*>(item);
1808   return true;
1809 }
1810 
CheckInterAnnotationSetItem()1811 bool DexFileVerifier::CheckInterAnnotationSetItem() {
1812   const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
1813   const uint32_t* offsets = set->entries_;
1814   uint32_t count = set->size_;
1815   uint32_t last_idx = 0;
1816 
1817   for (uint32_t i = 0; i < count; i++) {
1818     if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
1819       return false;
1820     }
1821 
1822     // Get the annotation from the offset and the type index for the annotation.
1823     const DexFile::AnnotationItem* annotation =
1824         reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
1825     const uint8_t* data = annotation->annotation_;
1826     uint32_t idx = DecodeUnsignedLeb128(&data);
1827 
1828     if (UNLIKELY(last_idx >= idx && i != 0)) {
1829       ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
1830       return false;
1831     }
1832 
1833     last_idx = idx;
1834     offsets++;
1835   }
1836 
1837   ptr_ = reinterpret_cast<const byte*>(offsets);
1838   return true;
1839 }
1840 
CheckInterClassDataItem()1841 bool DexFileVerifier::CheckInterClassDataItem() {
1842   ClassDataItemIterator it(*dex_file_, ptr_);
1843   bool success;
1844   uint16_t defining_class = FindFirstClassDataDefiner(ptr_, &success);
1845   if (!success) {
1846     return false;
1847   }
1848 
1849   for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
1850     LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
1851     if (UNLIKELY(field->class_idx_ != defining_class)) {
1852       ErrorStringPrintf("Mismatched defining class for class_data_item field");
1853       return false;
1854     }
1855   }
1856   for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) {
1857     uint32_t code_off = it.GetMethodCodeItemOffset();
1858     if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
1859       return false;
1860     }
1861     LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
1862     if (UNLIKELY(method->class_idx_ != defining_class)) {
1863       ErrorStringPrintf("Mismatched defining class for class_data_item method");
1864       return false;
1865     }
1866   }
1867 
1868   ptr_ = it.EndDataPointer();
1869   return true;
1870 }
1871 
CheckInterAnnotationsDirectoryItem()1872 bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
1873   const DexFile::AnnotationsDirectoryItem* item =
1874       reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
1875   bool success;
1876   uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
1877   if (!success) {
1878     return false;
1879   }
1880 
1881   if (item->class_annotations_off_ != 0 &&
1882       !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1883     return false;
1884   }
1885 
1886   // Field annotations follow immediately after the annotations directory.
1887   const DexFile::FieldAnnotationsItem* field_item =
1888       reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1889   uint32_t field_count = item->fields_size_;
1890   for (uint32_t i = 0; i < field_count; i++) {
1891     LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
1892                return false)
1893     if (UNLIKELY(field->class_idx_ != defining_class)) {
1894       ErrorStringPrintf("Mismatched defining class for field_annotation");
1895       return false;
1896     }
1897     if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1898       return false;
1899     }
1900     field_item++;
1901   }
1902 
1903   // Method annotations follow immediately after field annotations.
1904   const DexFile::MethodAnnotationsItem* method_item =
1905       reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1906   uint32_t method_count = item->methods_size_;
1907   for (uint32_t i = 0; i < method_count; i++) {
1908     LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
1909                 return false)
1910     if (UNLIKELY(method->class_idx_ != defining_class)) {
1911       ErrorStringPrintf("Mismatched defining class for method_annotation");
1912       return false;
1913     }
1914     if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1915       return false;
1916     }
1917     method_item++;
1918   }
1919 
1920   // Parameter annotations follow immediately after method annotations.
1921   const DexFile::ParameterAnnotationsItem* parameter_item =
1922       reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1923   uint32_t parameter_count = item->parameters_size_;
1924   for (uint32_t i = 0; i < parameter_count; i++) {
1925     LOAD_METHOD(parameter_method, parameter_item->method_idx_,
1926                 "inter_annotations_directory_item parameter method_id", return false)
1927     if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
1928       ErrorStringPrintf("Mismatched defining class for parameter_annotation");
1929       return false;
1930     }
1931     if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
1932         DexFile::kDexTypeAnnotationSetRefList)) {
1933       return false;
1934     }
1935     parameter_item++;
1936   }
1937 
1938   ptr_ = reinterpret_cast<const byte*>(parameter_item);
1939   return true;
1940 }
1941 
CheckInterSectionIterate(size_t offset,uint32_t count,uint16_t type)1942 bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
1943   // Get the right alignment mask for the type of section.
1944   size_t alignment_mask;
1945   switch (type) {
1946     case DexFile::kDexTypeClassDataItem:
1947       alignment_mask = sizeof(uint8_t) - 1;
1948       break;
1949     default:
1950       alignment_mask = sizeof(uint32_t) - 1;
1951       break;
1952   }
1953 
1954   // Iterate through the items in the section.
1955   previous_item_ = NULL;
1956   for (uint32_t i = 0; i < count; i++) {
1957     uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
1958     ptr_ = begin_ + new_offset;
1959     const byte* prev_ptr = ptr_;
1960 
1961     // Check depending on the section type.
1962     switch (type) {
1963       case DexFile::kDexTypeStringIdItem: {
1964         if (!CheckInterStringIdItem()) {
1965           return false;
1966         }
1967         break;
1968       }
1969       case DexFile::kDexTypeTypeIdItem: {
1970         if (!CheckInterTypeIdItem()) {
1971           return false;
1972         }
1973         break;
1974       }
1975       case DexFile::kDexTypeProtoIdItem: {
1976         if (!CheckInterProtoIdItem()) {
1977           return false;
1978         }
1979         break;
1980       }
1981       case DexFile::kDexTypeFieldIdItem: {
1982         if (!CheckInterFieldIdItem()) {
1983           return false;
1984         }
1985         break;
1986       }
1987       case DexFile::kDexTypeMethodIdItem: {
1988         if (!CheckInterMethodIdItem()) {
1989           return false;
1990         }
1991         break;
1992       }
1993       case DexFile::kDexTypeClassDefItem: {
1994         if (!CheckInterClassDefItem()) {
1995           return false;
1996         }
1997         break;
1998       }
1999       case DexFile::kDexTypeAnnotationSetRefList: {
2000         if (!CheckInterAnnotationSetRefList()) {
2001           return false;
2002         }
2003         break;
2004       }
2005       case DexFile::kDexTypeAnnotationSetItem: {
2006         if (!CheckInterAnnotationSetItem()) {
2007           return false;
2008         }
2009         break;
2010       }
2011       case DexFile::kDexTypeClassDataItem: {
2012         if (!CheckInterClassDataItem()) {
2013           return false;
2014         }
2015         break;
2016       }
2017       case DexFile::kDexTypeAnnotationsDirectoryItem: {
2018         if (!CheckInterAnnotationsDirectoryItem()) {
2019           return false;
2020         }
2021         break;
2022       }
2023       default:
2024         ErrorStringPrintf("Unknown map item type %x", type);
2025         return false;
2026     }
2027 
2028     previous_item_ = prev_ptr;
2029     offset = ptr_ - begin_;
2030   }
2031 
2032   return true;
2033 }
2034 
CheckInterSection()2035 bool DexFileVerifier::CheckInterSection() {
2036   const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
2037   const DexFile::MapItem* item = map->list_;
2038   uint32_t count = map->size_;
2039 
2040   // Cross check the items listed in the map.
2041   while (count--) {
2042     uint32_t section_offset = item->offset_;
2043     uint32_t section_count = item->size_;
2044     uint16_t type = item->type_;
2045 
2046     switch (type) {
2047       case DexFile::kDexTypeHeaderItem:
2048       case DexFile::kDexTypeMapList:
2049       case DexFile::kDexTypeTypeList:
2050       case DexFile::kDexTypeCodeItem:
2051       case DexFile::kDexTypeStringDataItem:
2052       case DexFile::kDexTypeDebugInfoItem:
2053       case DexFile::kDexTypeAnnotationItem:
2054       case DexFile::kDexTypeEncodedArrayItem:
2055         break;
2056       case DexFile::kDexTypeStringIdItem:
2057       case DexFile::kDexTypeTypeIdItem:
2058       case DexFile::kDexTypeProtoIdItem:
2059       case DexFile::kDexTypeFieldIdItem:
2060       case DexFile::kDexTypeMethodIdItem:
2061       case DexFile::kDexTypeClassDefItem:
2062       case DexFile::kDexTypeAnnotationSetRefList:
2063       case DexFile::kDexTypeAnnotationSetItem:
2064       case DexFile::kDexTypeClassDataItem:
2065       case DexFile::kDexTypeAnnotationsDirectoryItem: {
2066         if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2067           return false;
2068         }
2069         break;
2070       }
2071       default:
2072         ErrorStringPrintf("Unknown map item type %x", type);
2073         return false;
2074     }
2075 
2076     item++;
2077   }
2078 
2079   return true;
2080 }
2081 
Verify()2082 bool DexFileVerifier::Verify() {
2083   // Check the header.
2084   if (!CheckHeader()) {
2085     return false;
2086   }
2087 
2088   // Check the map section.
2089   if (!CheckMap()) {
2090     return false;
2091   }
2092 
2093   // Check structure within remaining sections.
2094   if (!CheckIntraSection()) {
2095     return false;
2096   }
2097 
2098   // Check references from one section to another.
2099   if (!CheckInterSection()) {
2100     return false;
2101   }
2102 
2103   return true;
2104 }
2105 
ErrorStringPrintf(const char * fmt,...)2106 void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2107   va_list ap;
2108   va_start(ap, fmt);
2109   DCHECK(failure_reason_.empty()) << failure_reason_;
2110   failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2111   StringAppendV(&failure_reason_, fmt, ap);
2112   va_end(ap);
2113 }
2114 
2115 }  // namespace art
2116