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