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