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