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