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