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
28namespace art {
29
30static 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
54static 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
68static 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
103bool 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
108bool 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
122bool 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
128bool 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
136bool 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
168bool 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
264uint32_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
277bool 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
325bool 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
347bool 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
384bool 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
401bool 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
521bool 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
533bool 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
563bool 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
593bool 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
691bool 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
775bool 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
881bool 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
904bool 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
973bool 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
1144bool 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
1192bool 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
1215bool 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
1301bool 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
1315uint16_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
1331uint16_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
1355bool 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
1378bool 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
1402bool 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
1468bool 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
1515bool 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
1555bool 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
1643bool 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
1661bool 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
1691bool 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
1718bool 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
1781bool 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
1874bool 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
1921bool 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