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