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