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