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