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