Home | History | Annotate | Download | only in runtime
      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 
     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 
     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 
     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 
    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 
    108 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 
    122 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 
    128 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 
    136 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 
    168 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 
    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 
    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 
    325 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 
    347 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   1315 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 
   1331 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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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