dex_file_verifier.cc revision 507dfdd147c97bfbadebfd63584d094b6a4e7b47
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 21#include "base/stringprintf.h" 22#include "dex_file-inl.h" 23#include "leb128.h" 24#include "safe_map.h" 25#include "UniquePtrCompat.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 UniquePtr<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 UniquePtr<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 if (UNLIKELY(ptr_ >= file_end)) { 702 ErrorStringPrintf("String data would go beyond end-of-file"); 703 return false; 704 } 705 706 uint8_t byte = *(ptr_++); 707 708 // Switch on the high 4 bits. 709 switch (byte >> 4) { 710 case 0x00: 711 // Special case of bit pattern 0xxx. 712 if (UNLIKELY(byte == 0)) { 713 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size); 714 return false; 715 } 716 break; 717 case 0x01: 718 case 0x02: 719 case 0x03: 720 case 0x04: 721 case 0x05: 722 case 0x06: 723 case 0x07: 724 // No extra checks necessary for bit pattern 0xxx. 725 break; 726 case 0x08: 727 case 0x09: 728 case 0x0a: 729 case 0x0b: 730 case 0x0f: 731 // Illegal bit patterns 10xx or 1111. 732 // Note: 1111 is valid for normal UTF-8, but not here. 733 ErrorStringPrintf("Illegal start byte %x in string data", byte); 734 return false; 735 case 0x0c: 736 case 0x0d: { 737 // Bit pattern 110x has an additional byte. 738 uint8_t byte2 = *(ptr_++); 739 if (UNLIKELY((byte2 & 0xc0) != 0x80)) { 740 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2); 741 return false; 742 } 743 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f); 744 if (UNLIKELY((value != 0) && (value < 0x80))) { 745 ErrorStringPrintf("Illegal representation for value %x in string data", value); 746 return false; 747 } 748 break; 749 } 750 case 0x0e: { 751 // Bit pattern 1110 has 2 additional bytes. 752 uint8_t byte2 = *(ptr_++); 753 if (UNLIKELY((byte2 & 0xc0) != 0x80)) { 754 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2); 755 return false; 756 } 757 uint8_t byte3 = *(ptr_++); 758 if (UNLIKELY((byte3 & 0xc0) != 0x80)) { 759 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3); 760 return false; 761 } 762 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f); 763 if (UNLIKELY(value < 0x800)) { 764 ErrorStringPrintf("Illegal representation for value %x in string data", value); 765 return false; 766 } 767 break; 768 } 769 } 770 } 771 772 if (UNLIKELY(*(ptr_++) != '\0')) { 773 ErrorStringPrintf("String longer than indicated size %x", size); 774 return false; 775 } 776 777 return true; 778} 779 780bool DexFileVerifier::CheckIntraDebugInfoItem() { 781 DecodeUnsignedLeb128(&ptr_); 782 uint32_t parameters_size = DecodeUnsignedLeb128(&ptr_); 783 if (UNLIKELY(parameters_size > 65536)) { 784 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size); 785 return false; 786 } 787 788 for (uint32_t j = 0; j < parameters_size; j++) { 789 uint32_t parameter_name = DecodeUnsignedLeb128(&ptr_); 790 if (parameter_name != 0) { 791 parameter_name--; 792 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) { 793 return false; 794 } 795 } 796 } 797 798 while (true) { 799 uint8_t opcode = *(ptr_++); 800 switch (opcode) { 801 case DexFile::DBG_END_SEQUENCE: { 802 return true; 803 } 804 case DexFile::DBG_ADVANCE_PC: { 805 DecodeUnsignedLeb128(&ptr_); 806 break; 807 } 808 case DexFile::DBG_ADVANCE_LINE: { 809 DecodeSignedLeb128(&ptr_); 810 break; 811 } 812 case DexFile::DBG_START_LOCAL: { 813 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_); 814 if (UNLIKELY(reg_num >= 65536)) { 815 ErrorStringPrintf("Bad reg_num for opcode %x", opcode); 816 return false; 817 } 818 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_); 819 if (name_idx != 0) { 820 name_idx--; 821 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) { 822 return false; 823 } 824 } 825 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_); 826 if (type_idx != 0) { 827 type_idx--; 828 if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL type_idx")) { 829 return false; 830 } 831 } 832 break; 833 } 834 case DexFile::DBG_END_LOCAL: 835 case DexFile::DBG_RESTART_LOCAL: { 836 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_); 837 if (UNLIKELY(reg_num >= 65536)) { 838 ErrorStringPrintf("Bad reg_num for opcode %x", opcode); 839 return false; 840 } 841 break; 842 } 843 case DexFile::DBG_START_LOCAL_EXTENDED: { 844 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_); 845 if (UNLIKELY(reg_num >= 65536)) { 846 ErrorStringPrintf("Bad reg_num for opcode %x", opcode); 847 return false; 848 } 849 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_); 850 if (name_idx != 0) { 851 name_idx--; 852 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) { 853 return false; 854 } 855 } 856 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_); 857 if (type_idx != 0) { 858 type_idx--; 859 if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) { 860 return false; 861 } 862 } 863 uint32_t sig_idx = DecodeUnsignedLeb128(&ptr_); 864 if (sig_idx != 0) { 865 sig_idx--; 866 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) { 867 return false; 868 } 869 } 870 break; 871 } 872 case DexFile::DBG_SET_FILE: { 873 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_); 874 if (name_idx != 0) { 875 name_idx--; 876 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) { 877 return false; 878 } 879 } 880 break; 881 } 882 } 883 } 884} 885 886bool DexFileVerifier::CheckIntraAnnotationItem() { 887 if (!CheckPointerRange(ptr_, ptr_ + 1, "annotation visibility")) { 888 return false; 889 } 890 891 // Check visibility 892 switch (*(ptr_++)) { 893 case DexFile::kDexVisibilityBuild: 894 case DexFile::kDexVisibilityRuntime: 895 case DexFile::kDexVisibilitySystem: 896 break; 897 default: 898 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_); 899 return false; 900 } 901 902 if (!CheckEncodedAnnotation()) { 903 return false; 904 } 905 906 return true; 907} 908 909bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() { 910 const DexFile::AnnotationsDirectoryItem* item = 911 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_); 912 if (!CheckPointerRange(item, item + 1, "annotations_directory")) { 913 return false; 914 } 915 916 // Field annotations follow immediately after the annotations directory. 917 const DexFile::FieldAnnotationsItem* field_item = 918 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1); 919 uint32_t field_count = item->fields_size_; 920 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) { 921 return false; 922 } 923 924 uint32_t last_idx = 0; 925 for (uint32_t i = 0; i < field_count; i++) { 926 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) { 927 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_); 928 return false; 929 } 930 last_idx = field_item->field_idx_; 931 field_item++; 932 } 933 934 // Method annotations follow immediately after field annotations. 935 const DexFile::MethodAnnotationsItem* method_item = 936 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item); 937 uint32_t method_count = item->methods_size_; 938 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) { 939 return false; 940 } 941 942 last_idx = 0; 943 for (uint32_t i = 0; i < method_count; i++) { 944 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) { 945 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x", 946 last_idx, method_item->method_idx_); 947 return false; 948 } 949 last_idx = method_item->method_idx_; 950 method_item++; 951 } 952 953 // Parameter annotations follow immediately after method annotations. 954 const DexFile::ParameterAnnotationsItem* parameter_item = 955 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item); 956 uint32_t parameter_count = item->parameters_size_; 957 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem), 958 "parameter_annotations list")) { 959 return false; 960 } 961 962 last_idx = 0; 963 for (uint32_t i = 0; i < parameter_count; i++) { 964 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) { 965 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x", 966 last_idx, parameter_item->method_idx_); 967 return false; 968 } 969 last_idx = parameter_item->method_idx_; 970 parameter_item++; 971 } 972 973 // Return a pointer to the end of the annotations. 974 ptr_ = reinterpret_cast<const byte*>(parameter_item); 975 return true; 976} 977 978bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t count, uint16_t type) { 979 // Get the right alignment mask for the type of section. 980 size_t alignment_mask; 981 switch (type) { 982 case DexFile::kDexTypeClassDataItem: 983 case DexFile::kDexTypeStringDataItem: 984 case DexFile::kDexTypeDebugInfoItem: 985 case DexFile::kDexTypeAnnotationItem: 986 case DexFile::kDexTypeEncodedArrayItem: 987 alignment_mask = sizeof(uint8_t) - 1; 988 break; 989 default: 990 alignment_mask = sizeof(uint32_t) - 1; 991 break; 992 } 993 994 // Iterate through the items in the section. 995 for (uint32_t i = 0; i < count; i++) { 996 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask; 997 998 // Check the padding between items. 999 if (!CheckPadding(offset, aligned_offset)) { 1000 return false; 1001 } 1002 1003 // Check depending on the section type. 1004 switch (type) { 1005 case DexFile::kDexTypeStringIdItem: { 1006 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::StringId), "string_ids")) { 1007 return false; 1008 } 1009 ptr_ += sizeof(DexFile::StringId); 1010 break; 1011 } 1012 case DexFile::kDexTypeTypeIdItem: { 1013 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::TypeId), "type_ids")) { 1014 return false; 1015 } 1016 ptr_ += sizeof(DexFile::TypeId); 1017 break; 1018 } 1019 case DexFile::kDexTypeProtoIdItem: { 1020 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::ProtoId), "proto_ids")) { 1021 return false; 1022 } 1023 ptr_ += sizeof(DexFile::ProtoId); 1024 break; 1025 } 1026 case DexFile::kDexTypeFieldIdItem: { 1027 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::FieldId), "field_ids")) { 1028 return false; 1029 } 1030 ptr_ += sizeof(DexFile::FieldId); 1031 break; 1032 } 1033 case DexFile::kDexTypeMethodIdItem: { 1034 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::MethodId), "method_ids")) { 1035 return false; 1036 } 1037 ptr_ += sizeof(DexFile::MethodId); 1038 break; 1039 } 1040 case DexFile::kDexTypeClassDefItem: { 1041 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::ClassDef), "class_defs")) { 1042 return false; 1043 } 1044 ptr_ += sizeof(DexFile::ClassDef); 1045 break; 1046 } 1047 case DexFile::kDexTypeTypeList: { 1048 const DexFile::TypeList* list = reinterpret_cast<const DexFile::TypeList*>(ptr_); 1049 const DexFile::TypeItem* item = &list->GetTypeItem(0); 1050 uint32_t count = list->Size(); 1051 1052 if (!CheckPointerRange(list, list + 1, "type_list") || 1053 !CheckListSize(item, count, sizeof(DexFile::TypeItem), "type_list size")) { 1054 return false; 1055 } 1056 ptr_ = reinterpret_cast<const byte*>(item + count); 1057 break; 1058 } 1059 case DexFile::kDexTypeAnnotationSetRefList: { 1060 const DexFile::AnnotationSetRefList* list = 1061 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_); 1062 const DexFile::AnnotationSetRefItem* item = list->list_; 1063 uint32_t count = list->size_; 1064 1065 if (!CheckPointerRange(list, list + 1, "annotation_set_ref_list") || 1066 !CheckListSize(item, count, sizeof(DexFile::AnnotationSetRefItem), 1067 "annotation_set_ref_list size")) { 1068 return false; 1069 } 1070 ptr_ = reinterpret_cast<const byte*>(item + count); 1071 break; 1072 } 1073 case DexFile::kDexTypeAnnotationSetItem: { 1074 const DexFile::AnnotationSetItem* set = 1075 reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_); 1076 const uint32_t* item = set->entries_; 1077 uint32_t count = set->size_; 1078 1079 if (!CheckPointerRange(set, set + 1, "annotation_set_item") || 1080 !CheckListSize(item, count, sizeof(uint32_t), "annotation_set_item size")) { 1081 return false; 1082 } 1083 ptr_ = reinterpret_cast<const byte*>(item + count); 1084 break; 1085 } 1086 case DexFile::kDexTypeClassDataItem: { 1087 if (!CheckIntraClassDataItem()) { 1088 return false; 1089 } 1090 break; 1091 } 1092 case DexFile::kDexTypeCodeItem: { 1093 if (!CheckIntraCodeItem()) { 1094 return false; 1095 } 1096 break; 1097 } 1098 case DexFile::kDexTypeStringDataItem: { 1099 if (!CheckIntraStringDataItem()) { 1100 return false; 1101 } 1102 break; 1103 } 1104 case DexFile::kDexTypeDebugInfoItem: { 1105 if (!CheckIntraDebugInfoItem()) { 1106 return false; 1107 } 1108 break; 1109 } 1110 case DexFile::kDexTypeAnnotationItem: { 1111 if (!CheckIntraAnnotationItem()) { 1112 return false; 1113 } 1114 break; 1115 } 1116 case DexFile::kDexTypeEncodedArrayItem: { 1117 if (!CheckEncodedArray()) { 1118 return false; 1119 } 1120 break; 1121 } 1122 case DexFile::kDexTypeAnnotationsDirectoryItem: { 1123 if (!CheckIntraAnnotationsDirectoryItem()) { 1124 return false; 1125 } 1126 break; 1127 } 1128 default: 1129 ErrorStringPrintf("Unknown map item type %x", type); 1130 return false; 1131 } 1132 1133 if (IsDataSectionType(type)) { 1134 offset_to_type_map_.Put(aligned_offset, type); 1135 } 1136 1137 aligned_offset = ptr_ - begin_; 1138 if (UNLIKELY(aligned_offset > size_)) { 1139 ErrorStringPrintf("Item %d at ends out of bounds", i); 1140 return false; 1141 } 1142 1143 offset = aligned_offset; 1144 } 1145 1146 return true; 1147} 1148 1149bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) { 1150 uint32_t expected_offset; 1151 uint32_t expected_size; 1152 1153 // Get the expected offset and size from the header. 1154 switch (type) { 1155 case DexFile::kDexTypeStringIdItem: 1156 expected_offset = header_->string_ids_off_; 1157 expected_size = header_->string_ids_size_; 1158 break; 1159 case DexFile::kDexTypeTypeIdItem: 1160 expected_offset = header_->type_ids_off_; 1161 expected_size = header_->type_ids_size_; 1162 break; 1163 case DexFile::kDexTypeProtoIdItem: 1164 expected_offset = header_->proto_ids_off_; 1165 expected_size = header_->proto_ids_size_; 1166 break; 1167 case DexFile::kDexTypeFieldIdItem: 1168 expected_offset = header_->field_ids_off_; 1169 expected_size = header_->field_ids_size_; 1170 break; 1171 case DexFile::kDexTypeMethodIdItem: 1172 expected_offset = header_->method_ids_off_; 1173 expected_size = header_->method_ids_size_; 1174 break; 1175 case DexFile::kDexTypeClassDefItem: 1176 expected_offset = header_->class_defs_off_; 1177 expected_size = header_->class_defs_size_; 1178 break; 1179 default: 1180 ErrorStringPrintf("Bad type for id section: %x", type); 1181 return false; 1182 } 1183 1184 // Check that the offset and size are what were expected from the header. 1185 if (UNLIKELY(offset != expected_offset)) { 1186 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset); 1187 return false; 1188 } 1189 if (UNLIKELY(count != expected_size)) { 1190 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size); 1191 return false; 1192 } 1193 1194 return CheckIntraSectionIterate(offset, count, type); 1195} 1196 1197bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) { 1198 size_t data_start = header_->data_off_; 1199 size_t data_end = data_start + header_->data_size_; 1200 1201 // Sanity check the offset of the section. 1202 if (UNLIKELY((offset < data_start) || (offset > data_end))) { 1203 ErrorStringPrintf("Bad offset for data subsection: %zx", offset); 1204 return false; 1205 } 1206 1207 if (!CheckIntraSectionIterate(offset, count, type)) { 1208 return false; 1209 } 1210 1211 size_t next_offset = ptr_ - begin_; 1212 if (next_offset > data_end) { 1213 ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset); 1214 return false; 1215 } 1216 1217 return true; 1218} 1219 1220bool DexFileVerifier::CheckIntraSection() { 1221 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_); 1222 const DexFile::MapItem* item = map->list_; 1223 1224 uint32_t count = map->size_; 1225 size_t offset = 0; 1226 ptr_ = begin_; 1227 1228 // Check the items listed in the map. 1229 while (count--) { 1230 uint32_t section_offset = item->offset_; 1231 uint32_t section_count = item->size_; 1232 uint16_t type = item->type_; 1233 1234 // Check for padding and overlap between items. 1235 if (!CheckPadding(offset, section_offset)) { 1236 return false; 1237 } else if (UNLIKELY(offset > section_offset)) { 1238 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset); 1239 return false; 1240 } 1241 1242 // Check each item based on its type. 1243 switch (type) { 1244 case DexFile::kDexTypeHeaderItem: 1245 if (UNLIKELY(section_count != 1)) { 1246 ErrorStringPrintf("Multiple header items"); 1247 return false; 1248 } 1249 if (UNLIKELY(section_offset != 0)) { 1250 ErrorStringPrintf("Header at %x, not at start of file", section_offset); 1251 return false; 1252 } 1253 ptr_ = begin_ + header_->header_size_; 1254 offset = header_->header_size_; 1255 break; 1256 case DexFile::kDexTypeStringIdItem: 1257 case DexFile::kDexTypeTypeIdItem: 1258 case DexFile::kDexTypeProtoIdItem: 1259 case DexFile::kDexTypeFieldIdItem: 1260 case DexFile::kDexTypeMethodIdItem: 1261 case DexFile::kDexTypeClassDefItem: 1262 if (!CheckIntraIdSection(section_offset, section_count, type)) { 1263 return false; 1264 } 1265 offset = ptr_ - begin_; 1266 break; 1267 case DexFile::kDexTypeMapList: 1268 if (UNLIKELY(section_count != 1)) { 1269 ErrorStringPrintf("Multiple map list items"); 1270 return false; 1271 } 1272 if (UNLIKELY(section_offset != header_->map_off_)) { 1273 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x", 1274 section_offset, header_->map_off_); 1275 return false; 1276 } 1277 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem)); 1278 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem)); 1279 break; 1280 case DexFile::kDexTypeTypeList: 1281 case DexFile::kDexTypeAnnotationSetRefList: 1282 case DexFile::kDexTypeAnnotationSetItem: 1283 case DexFile::kDexTypeClassDataItem: 1284 case DexFile::kDexTypeCodeItem: 1285 case DexFile::kDexTypeStringDataItem: 1286 case DexFile::kDexTypeDebugInfoItem: 1287 case DexFile::kDexTypeAnnotationItem: 1288 case DexFile::kDexTypeEncodedArrayItem: 1289 case DexFile::kDexTypeAnnotationsDirectoryItem: 1290 if (!CheckIntraDataSection(section_offset, section_count, type)) { 1291 return false; 1292 } 1293 offset = ptr_ - begin_; 1294 break; 1295 default: 1296 ErrorStringPrintf("Unknown map item type %x", type); 1297 return false; 1298 } 1299 1300 item++; 1301 } 1302 1303 return true; 1304} 1305 1306bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) { 1307 auto it = offset_to_type_map_.find(offset); 1308 if (UNLIKELY(it == offset_to_type_map_.end())) { 1309 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type); 1310 return false; 1311 } 1312 if (UNLIKELY(it->second != type)) { 1313 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x", 1314 offset, type, it->second); 1315 return false; 1316 } 1317 return true; 1318} 1319 1320uint16_t DexFileVerifier::FindFirstClassDataDefiner(const byte* ptr) const { 1321 ClassDataItemIterator it(*dex_file_, ptr); 1322 1323 if (it.HasNextStaticField() || it.HasNextInstanceField()) { 1324 const DexFile::FieldId& field = dex_file_->GetFieldId(it.GetMemberIndex()); 1325 return field.class_idx_; 1326 } 1327 1328 if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) { 1329 const DexFile::MethodId& method = dex_file_->GetMethodId(it.GetMemberIndex()); 1330 return method.class_idx_; 1331 } 1332 1333 return DexFile::kDexNoIndex16; 1334} 1335 1336uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const byte* ptr) const { 1337 const DexFile::AnnotationsDirectoryItem* item = 1338 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr); 1339 if (item->fields_size_ != 0) { 1340 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1); 1341 const DexFile::FieldId& field = dex_file_->GetFieldId(field_items[0].field_idx_); 1342 return field.class_idx_; 1343 } 1344 1345 if (item->methods_size_ != 0) { 1346 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1); 1347 const DexFile::MethodId& method = dex_file_->GetMethodId(method_items[0].method_idx_); 1348 return method.class_idx_; 1349 } 1350 1351 if (item->parameters_size_ != 0) { 1352 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1); 1353 const DexFile::MethodId& method = dex_file_->GetMethodId(parameter_items[0].method_idx_); 1354 return method.class_idx_; 1355 } 1356 1357 return DexFile::kDexNoIndex16; 1358} 1359 1360bool DexFileVerifier::CheckInterStringIdItem() { 1361 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_); 1362 1363 // Check the map to make sure it has the right offset->type. 1364 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) { 1365 return false; 1366 } 1367 1368 // Check ordering between items. 1369 if (previous_item_ != NULL) { 1370 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_); 1371 const char* prev_str = dex_file_->GetStringData(*prev_item); 1372 const char* str = dex_file_->GetStringData(*item); 1373 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) { 1374 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str); 1375 return false; 1376 } 1377 } 1378 1379 ptr_ += sizeof(DexFile::StringId); 1380 return true; 1381} 1382 1383bool DexFileVerifier::CheckInterTypeIdItem() { 1384 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_); 1385 const char* descriptor = dex_file_->StringDataByIdx(item->descriptor_idx_); 1386 1387 // Check that the descriptor is a valid type. 1388 if (UNLIKELY(!IsValidDescriptor(descriptor))) { 1389 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor); 1390 return false; 1391 } 1392 1393 // Check ordering between items. 1394 if (previous_item_ != NULL) { 1395 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_); 1396 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) { 1397 ErrorStringPrintf("Out-of-order type_ids: %x then %x", 1398 prev_item->descriptor_idx_, item->descriptor_idx_); 1399 return false; 1400 } 1401 } 1402 1403 ptr_ += sizeof(DexFile::TypeId); 1404 return true; 1405} 1406 1407bool DexFileVerifier::CheckInterProtoIdItem() { 1408 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_); 1409 const char* shorty = dex_file_->StringDataByIdx(item->shorty_idx_); 1410 if (item->parameters_off_ != 0 && 1411 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) { 1412 return false; 1413 } 1414 1415 // Check the return type and advance the shorty. 1416 if (!CheckShortyDescriptorMatch(*shorty, dex_file_->StringByTypeIdx(item->return_type_idx_), true)) { 1417 return false; 1418 } 1419 shorty++; 1420 1421 DexFileParameterIterator it(*dex_file_, *item); 1422 while (it.HasNext() && *shorty != '\0') { 1423 const char* descriptor = it.GetDescriptor(); 1424 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) { 1425 return false; 1426 } 1427 it.Next(); 1428 shorty++; 1429 } 1430 if (UNLIKELY(it.HasNext() || *shorty != '\0')) { 1431 ErrorStringPrintf("Mismatched length for parameters and shorty"); 1432 return false; 1433 } 1434 1435 // Check ordering between items. This relies on type_ids being in order. 1436 if (previous_item_ != NULL) { 1437 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_); 1438 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) { 1439 ErrorStringPrintf("Out-of-order proto_id return types"); 1440 return false; 1441 } else if (prev->return_type_idx_ == item->return_type_idx_) { 1442 DexFileParameterIterator curr_it(*dex_file_, *item); 1443 DexFileParameterIterator prev_it(*dex_file_, *prev); 1444 1445 while (curr_it.HasNext() && prev_it.HasNext()) { 1446 uint16_t prev_idx = prev_it.GetTypeIdx(); 1447 uint16_t curr_idx = curr_it.GetTypeIdx(); 1448 if (prev_idx == DexFile::kDexNoIndex16) { 1449 break; 1450 } 1451 if (UNLIKELY(curr_idx == DexFile::kDexNoIndex16)) { 1452 ErrorStringPrintf("Out-of-order proto_id arguments"); 1453 return false; 1454 } 1455 1456 if (prev_idx < curr_idx) { 1457 break; 1458 } else if (UNLIKELY(prev_idx > curr_idx)) { 1459 ErrorStringPrintf("Out-of-order proto_id arguments"); 1460 return false; 1461 } 1462 1463 prev_it.Next(); 1464 curr_it.Next(); 1465 } 1466 } 1467 } 1468 1469 ptr_ += sizeof(DexFile::ProtoId); 1470 return true; 1471} 1472 1473bool DexFileVerifier::CheckInterFieldIdItem() { 1474 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_); 1475 1476 // Check that the class descriptor is valid. 1477 const char* descriptor = dex_file_->StringByTypeIdx(item->class_idx_); 1478 if (UNLIKELY(!IsValidDescriptor(descriptor) || descriptor[0] != 'L')) { 1479 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", descriptor); 1480 return false; 1481 } 1482 1483 // Check that the type descriptor is a valid field name. 1484 descriptor = dex_file_->StringByTypeIdx(item->type_idx_); 1485 if (UNLIKELY(!IsValidDescriptor(descriptor) || descriptor[0] == 'V')) { 1486 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", descriptor); 1487 return false; 1488 } 1489 1490 // Check that the name is valid. 1491 descriptor = dex_file_->StringDataByIdx(item->name_idx_); 1492 if (UNLIKELY(!IsValidMemberName(descriptor))) { 1493 ErrorStringPrintf("Invalid field name: '%s'", descriptor); 1494 return false; 1495 } 1496 1497 // Check ordering between items. This relies on the other sections being in order. 1498 if (previous_item_ != NULL) { 1499 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_); 1500 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) { 1501 ErrorStringPrintf("Out-of-order field_ids"); 1502 return false; 1503 } else if (prev_item->class_idx_ == item->class_idx_) { 1504 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) { 1505 ErrorStringPrintf("Out-of-order field_ids"); 1506 return false; 1507 } else if (prev_item->name_idx_ == item->name_idx_) { 1508 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) { 1509 ErrorStringPrintf("Out-of-order field_ids"); 1510 return false; 1511 } 1512 } 1513 } 1514 } 1515 1516 ptr_ += sizeof(DexFile::FieldId); 1517 return true; 1518} 1519 1520bool DexFileVerifier::CheckInterMethodIdItem() { 1521 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_); 1522 1523 // Check that the class descriptor is a valid reference name. 1524 const char* descriptor = dex_file_->StringByTypeIdx(item->class_idx_); 1525 if (UNLIKELY(!IsValidDescriptor(descriptor) || (descriptor[0] != 'L' && descriptor[0] != '['))) { 1526 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", descriptor); 1527 return false; 1528 } 1529 1530 // Check that the name is valid. 1531 descriptor = dex_file_->StringDataByIdx(item->name_idx_); 1532 if (UNLIKELY(!IsValidMemberName(descriptor))) { 1533 ErrorStringPrintf("Invalid method name: '%s'", descriptor); 1534 return false; 1535 } 1536 1537 // Check ordering between items. This relies on the other sections being in order. 1538 if (previous_item_ != NULL) { 1539 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_); 1540 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) { 1541 ErrorStringPrintf("Out-of-order method_ids"); 1542 return false; 1543 } else if (prev_item->class_idx_ == item->class_idx_) { 1544 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) { 1545 ErrorStringPrintf("Out-of-order method_ids"); 1546 return false; 1547 } else if (prev_item->name_idx_ == item->name_idx_) { 1548 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) { 1549 ErrorStringPrintf("Out-of-order method_ids"); 1550 return false; 1551 } 1552 } 1553 } 1554 } 1555 1556 ptr_ += sizeof(DexFile::MethodId); 1557 return true; 1558} 1559 1560bool DexFileVerifier::CheckInterClassDefItem() { 1561 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_); 1562 uint32_t class_idx = item->class_idx_; 1563 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 1564 1565 if (UNLIKELY(!IsValidDescriptor(descriptor) || descriptor[0] != 'L')) { 1566 ErrorStringPrintf("Invalid class descriptor: '%s'", descriptor); 1567 return false; 1568 } 1569 1570 if (item->interfaces_off_ != 0 && 1571 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) { 1572 return false; 1573 } 1574 if (item->annotations_off_ != 0 && 1575 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) { 1576 return false; 1577 } 1578 if (item->class_data_off_ != 0 && 1579 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) { 1580 return false; 1581 } 1582 if (item->static_values_off_ != 0 && 1583 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) { 1584 return false; 1585 } 1586 1587 if (item->superclass_idx_ != DexFile::kDexNoIndex16) { 1588 descriptor = dex_file_->StringByTypeIdx(item->superclass_idx_); 1589 if (UNLIKELY(!IsValidDescriptor(descriptor) || descriptor[0] != 'L')) { 1590 ErrorStringPrintf("Invalid superclass: '%s'", descriptor); 1591 return false; 1592 } 1593 } 1594 1595 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item); 1596 if (interfaces != NULL) { 1597 uint32_t size = interfaces->Size(); 1598 1599 // Ensure that all interfaces refer to classes (not arrays or primitives). 1600 for (uint32_t i = 0; i < size; i++) { 1601 descriptor = dex_file_->StringByTypeIdx(interfaces->GetTypeItem(i).type_idx_); 1602 if (UNLIKELY(!IsValidDescriptor(descriptor) || descriptor[0] != 'L')) { 1603 ErrorStringPrintf("Invalid interface: '%s'", descriptor); 1604 return false; 1605 } 1606 } 1607 1608 /* 1609 * Ensure that there are no duplicates. This is an O(N^2) test, but in 1610 * practice the number of interfaces implemented by any given class is low. 1611 */ 1612 for (uint32_t i = 1; i < size; i++) { 1613 uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_; 1614 for (uint32_t j =0; j < i; j++) { 1615 uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_; 1616 if (UNLIKELY(idx1 == idx2)) { 1617 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1)); 1618 return false; 1619 } 1620 } 1621 } 1622 } 1623 1624 // Check that references in class_data_item are to the right class. 1625 if (item->class_data_off_ != 0) { 1626 const byte* data = begin_ + item->class_data_off_; 1627 uint16_t data_definer = FindFirstClassDataDefiner(data); 1628 if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) { 1629 ErrorStringPrintf("Invalid class_data_item"); 1630 return false; 1631 } 1632 } 1633 1634 // Check that references in annotations_directory_item are to right class. 1635 if (item->annotations_off_ != 0) { 1636 const byte* data = begin_ + item->annotations_off_; 1637 uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data); 1638 if (UNLIKELY((annotations_definer != item->class_idx_) && 1639 (annotations_definer != DexFile::kDexNoIndex16))) { 1640 ErrorStringPrintf("Invalid annotations_directory_item"); 1641 return false; 1642 } 1643 } 1644 1645 ptr_ += sizeof(DexFile::ClassDef); 1646 return true; 1647} 1648 1649bool DexFileVerifier::CheckInterAnnotationSetRefList() { 1650 const DexFile::AnnotationSetRefList* list = 1651 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_); 1652 const DexFile::AnnotationSetRefItem* item = list->list_; 1653 uint32_t count = list->size_; 1654 1655 while (count--) { 1656 if (item->annotations_off_ != 0 && 1657 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) { 1658 return false; 1659 } 1660 item++; 1661 } 1662 1663 ptr_ = reinterpret_cast<const byte*>(item); 1664 return true; 1665} 1666 1667bool DexFileVerifier::CheckInterAnnotationSetItem() { 1668 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_); 1669 const uint32_t* offsets = set->entries_; 1670 uint32_t count = set->size_; 1671 uint32_t last_idx = 0; 1672 1673 for (uint32_t i = 0; i < count; i++) { 1674 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) { 1675 return false; 1676 } 1677 1678 // Get the annotation from the offset and the type index for the annotation. 1679 const DexFile::AnnotationItem* annotation = 1680 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets); 1681 const uint8_t* data = annotation->annotation_; 1682 uint32_t idx = DecodeUnsignedLeb128(&data); 1683 1684 if (UNLIKELY(last_idx >= idx && i != 0)) { 1685 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx); 1686 return false; 1687 } 1688 1689 last_idx = idx; 1690 offsets++; 1691 } 1692 1693 ptr_ = reinterpret_cast<const byte*>(offsets); 1694 return true; 1695} 1696 1697bool DexFileVerifier::CheckInterClassDataItem() { 1698 ClassDataItemIterator it(*dex_file_, ptr_); 1699 uint16_t defining_class = FindFirstClassDataDefiner(ptr_); 1700 1701 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) { 1702 const DexFile::FieldId& field = dex_file_->GetFieldId(it.GetMemberIndex()); 1703 if (UNLIKELY(field.class_idx_ != defining_class)) { 1704 ErrorStringPrintf("Mismatched defining class for class_data_item field"); 1705 return false; 1706 } 1707 } 1708 for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) { 1709 uint32_t code_off = it.GetMethodCodeItemOffset(); 1710 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) { 1711 return false; 1712 } 1713 const DexFile::MethodId& method = dex_file_->GetMethodId(it.GetMemberIndex()); 1714 if (UNLIKELY(method.class_idx_ != defining_class)) { 1715 ErrorStringPrintf("Mismatched defining class for class_data_item method"); 1716 return false; 1717 } 1718 } 1719 1720 ptr_ = it.EndDataPointer(); 1721 return true; 1722} 1723 1724bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() { 1725 const DexFile::AnnotationsDirectoryItem* item = 1726 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_); 1727 uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_); 1728 1729 if (item->class_annotations_off_ != 0 && 1730 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) { 1731 return false; 1732 } 1733 1734 // Field annotations follow immediately after the annotations directory. 1735 const DexFile::FieldAnnotationsItem* field_item = 1736 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1); 1737 uint32_t field_count = item->fields_size_; 1738 for (uint32_t i = 0; i < field_count; i++) { 1739 const DexFile::FieldId& field = dex_file_->GetFieldId(field_item->field_idx_); 1740 if (UNLIKELY(field.class_idx_ != defining_class)) { 1741 ErrorStringPrintf("Mismatched defining class for field_annotation"); 1742 return false; 1743 } 1744 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) { 1745 return false; 1746 } 1747 field_item++; 1748 } 1749 1750 // Method annotations follow immediately after field annotations. 1751 const DexFile::MethodAnnotationsItem* method_item = 1752 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item); 1753 uint32_t method_count = item->methods_size_; 1754 for (uint32_t i = 0; i < method_count; i++) { 1755 const DexFile::MethodId& method = dex_file_->GetMethodId(method_item->method_idx_); 1756 if (UNLIKELY(method.class_idx_ != defining_class)) { 1757 ErrorStringPrintf("Mismatched defining class for method_annotation"); 1758 return false; 1759 } 1760 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) { 1761 return false; 1762 } 1763 method_item++; 1764 } 1765 1766 // Parameter annotations follow immediately after method annotations. 1767 const DexFile::ParameterAnnotationsItem* parameter_item = 1768 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item); 1769 uint32_t parameter_count = item->parameters_size_; 1770 for (uint32_t i = 0; i < parameter_count; i++) { 1771 const DexFile::MethodId& parameter_method = dex_file_->GetMethodId(parameter_item->method_idx_); 1772 if (UNLIKELY(parameter_method.class_idx_ != defining_class)) { 1773 ErrorStringPrintf("Mismatched defining class for parameter_annotation"); 1774 return false; 1775 } 1776 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_, 1777 DexFile::kDexTypeAnnotationSetRefList)) { 1778 return false; 1779 } 1780 parameter_item++; 1781 } 1782 1783 ptr_ = reinterpret_cast<const byte*>(parameter_item); 1784 return true; 1785} 1786 1787bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) { 1788 // Get the right alignment mask for the type of section. 1789 size_t alignment_mask; 1790 switch (type) { 1791 case DexFile::kDexTypeClassDataItem: 1792 alignment_mask = sizeof(uint8_t) - 1; 1793 break; 1794 default: 1795 alignment_mask = sizeof(uint32_t) - 1; 1796 break; 1797 } 1798 1799 // Iterate through the items in the section. 1800 previous_item_ = NULL; 1801 for (uint32_t i = 0; i < count; i++) { 1802 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask; 1803 ptr_ = begin_ + new_offset; 1804 const byte* prev_ptr = ptr_; 1805 1806 // Check depending on the section type. 1807 switch (type) { 1808 case DexFile::kDexTypeStringIdItem: { 1809 if (!CheckInterStringIdItem()) { 1810 return false; 1811 } 1812 break; 1813 } 1814 case DexFile::kDexTypeTypeIdItem: { 1815 if (!CheckInterTypeIdItem()) { 1816 return false; 1817 } 1818 break; 1819 } 1820 case DexFile::kDexTypeProtoIdItem: { 1821 if (!CheckInterProtoIdItem()) { 1822 return false; 1823 } 1824 break; 1825 } 1826 case DexFile::kDexTypeFieldIdItem: { 1827 if (!CheckInterFieldIdItem()) { 1828 return false; 1829 } 1830 break; 1831 } 1832 case DexFile::kDexTypeMethodIdItem: { 1833 if (!CheckInterMethodIdItem()) { 1834 return false; 1835 } 1836 break; 1837 } 1838 case DexFile::kDexTypeClassDefItem: { 1839 if (!CheckInterClassDefItem()) { 1840 return false; 1841 } 1842 break; 1843 } 1844 case DexFile::kDexTypeAnnotationSetRefList: { 1845 if (!CheckInterAnnotationSetRefList()) { 1846 return false; 1847 } 1848 break; 1849 } 1850 case DexFile::kDexTypeAnnotationSetItem: { 1851 if (!CheckInterAnnotationSetItem()) { 1852 return false; 1853 } 1854 break; 1855 } 1856 case DexFile::kDexTypeClassDataItem: { 1857 if (!CheckInterClassDataItem()) { 1858 return false; 1859 } 1860 break; 1861 } 1862 case DexFile::kDexTypeAnnotationsDirectoryItem: { 1863 if (!CheckInterAnnotationsDirectoryItem()) { 1864 return false; 1865 } 1866 break; 1867 } 1868 default: 1869 ErrorStringPrintf("Unknown map item type %x", type); 1870 return false; 1871 } 1872 1873 previous_item_ = prev_ptr; 1874 offset = ptr_ - begin_; 1875 } 1876 1877 return true; 1878} 1879 1880bool DexFileVerifier::CheckInterSection() { 1881 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_); 1882 const DexFile::MapItem* item = map->list_; 1883 uint32_t count = map->size_; 1884 1885 // Cross check the items listed in the map. 1886 while (count--) { 1887 uint32_t section_offset = item->offset_; 1888 uint32_t section_count = item->size_; 1889 uint16_t type = item->type_; 1890 1891 switch (type) { 1892 case DexFile::kDexTypeHeaderItem: 1893 case DexFile::kDexTypeMapList: 1894 case DexFile::kDexTypeTypeList: 1895 case DexFile::kDexTypeCodeItem: 1896 case DexFile::kDexTypeStringDataItem: 1897 case DexFile::kDexTypeDebugInfoItem: 1898 case DexFile::kDexTypeAnnotationItem: 1899 case DexFile::kDexTypeEncodedArrayItem: 1900 break; 1901 case DexFile::kDexTypeStringIdItem: 1902 case DexFile::kDexTypeTypeIdItem: 1903 case DexFile::kDexTypeProtoIdItem: 1904 case DexFile::kDexTypeFieldIdItem: 1905 case DexFile::kDexTypeMethodIdItem: 1906 case DexFile::kDexTypeClassDefItem: 1907 case DexFile::kDexTypeAnnotationSetRefList: 1908 case DexFile::kDexTypeAnnotationSetItem: 1909 case DexFile::kDexTypeClassDataItem: 1910 case DexFile::kDexTypeAnnotationsDirectoryItem: { 1911 if (!CheckInterSectionIterate(section_offset, section_count, type)) { 1912 return false; 1913 } 1914 break; 1915 } 1916 default: 1917 ErrorStringPrintf("Unknown map item type %x", type); 1918 return false; 1919 } 1920 1921 item++; 1922 } 1923 1924 return true; 1925} 1926 1927bool DexFileVerifier::Verify() { 1928 // Check the header. 1929 if (!CheckHeader()) { 1930 return false; 1931 } 1932 1933 // Check the map section. 1934 if (!CheckMap()) { 1935 return false; 1936 } 1937 1938 // Check structure within remaining sections. 1939 if (!CheckIntraSection()) { 1940 return false; 1941 } 1942 1943 // Check references from one section to another. 1944 if (!CheckInterSection()) { 1945 return false; 1946 } 1947 1948 return true; 1949} 1950 1951void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) { 1952 va_list ap; 1953 va_start(ap, fmt); 1954 DCHECK(failure_reason_.empty()) << failure_reason_; 1955 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_); 1956 StringAppendV(&failure_reason_, fmt, ap); 1957 va_end(ap); 1958} 1959 1960} // namespace art 1961