1 /* 2 * Copyright (C) 2016 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 "verifier_deps.h" 18 19 #include <cstring> 20 #include <sstream> 21 22 #include "art_field-inl.h" 23 #include "art_method-inl.h" 24 #include "base/indenter.h" 25 #include "base/leb128.h" 26 #include "base/mutex-inl.h" 27 #include "compiler_callbacks.h" 28 #include "dex/class_accessor-inl.h" 29 #include "dex/dex_file-inl.h" 30 #include "mirror/class-inl.h" 31 #include "mirror/class_loader.h" 32 #include "oat_file.h" 33 #include "obj_ptr-inl.h" 34 #include "runtime.h" 35 36 namespace art { 37 namespace verifier { 38 39 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only) 40 : output_only_(output_only) { 41 for (const DexFile* dex_file : dex_files) { 42 DCHECK(GetDexFileDeps(*dex_file) == nullptr); 43 std::unique_ptr<DexFileDeps> deps(new DexFileDeps(dex_file->NumClassDefs())); 44 dex_deps_.emplace(dex_file, std::move(deps)); 45 } 46 } 47 48 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files) 49 : VerifierDeps(dex_files, /*output_only=*/ true) {} 50 51 // Perform logical OR on two bit vectors and assign back to LHS, i.e. `to_update |= other`. 52 // Size of the two vectors must be equal. 53 // Size of `other` must be equal to size of `to_update`. 54 static inline void BitVectorOr(std::vector<bool>& to_update, const std::vector<bool>& other) { 55 DCHECK_EQ(to_update.size(), other.size()); 56 std::transform(other.begin(), 57 other.end(), 58 to_update.begin(), 59 to_update.begin(), 60 std::logical_or<bool>()); 61 } 62 63 void VerifierDeps::MergeWith(std::unique_ptr<VerifierDeps> other, 64 const std::vector<const DexFile*>& dex_files) { 65 DCHECK(other != nullptr); 66 DCHECK_EQ(dex_deps_.size(), other->dex_deps_.size()); 67 for (const DexFile* dex_file : dex_files) { 68 DexFileDeps* my_deps = GetDexFileDeps(*dex_file); 69 DexFileDeps& other_deps = *other->GetDexFileDeps(*dex_file); 70 // We currently collect extra strings only on the main `VerifierDeps`, 71 // which should be the one passed as `this` in this method. 72 DCHECK(other_deps.strings_.empty()); 73 my_deps->assignable_types_.merge(other_deps.assignable_types_); 74 my_deps->unassignable_types_.merge(other_deps.unassignable_types_); 75 my_deps->classes_.merge(other_deps.classes_); 76 my_deps->fields_.merge(other_deps.fields_); 77 my_deps->methods_.merge(other_deps.methods_); 78 BitVectorOr(my_deps->verified_classes_, other_deps.verified_classes_); 79 BitVectorOr(my_deps->redefined_classes_, other_deps.redefined_classes_); 80 } 81 } 82 83 VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) { 84 auto it = dex_deps_.find(&dex_file); 85 return (it == dex_deps_.end()) ? nullptr : it->second.get(); 86 } 87 88 const VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const { 89 auto it = dex_deps_.find(&dex_file); 90 return (it == dex_deps_.end()) ? nullptr : it->second.get(); 91 } 92 93 // Access flags that impact vdex verification. 94 static constexpr uint32_t kAccVdexAccessFlags = 95 kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface; 96 97 template <typename Ptr> 98 uint16_t VerifierDeps::GetAccessFlags(Ptr element) { 99 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 100 if (element == nullptr) { 101 return VerifierDeps::kUnresolvedMarker; 102 } else { 103 uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags; 104 CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker); 105 return access_flags; 106 } 107 } 108 109 dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file, 110 ObjPtr<mirror::Class> klass) { 111 DCHECK(klass != nullptr); 112 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); 113 // Array and proxy classes do not have a dex cache. 114 if (!klass->IsArrayClass() && !klass->IsProxyClass()) { 115 DCHECK(dex_cache != nullptr) << klass->PrettyClass(); 116 if (dex_cache->GetDexFile() == &dex_file) { 117 // FindStringId is slow, try to go through the class def if we have one. 118 const dex::ClassDef* class_def = klass->GetClassDef(); 119 DCHECK(class_def != nullptr) << klass->PrettyClass(); 120 const dex::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_); 121 if (kIsDebugBuild) { 122 std::string temp; 123 CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_); 124 } 125 return type_id.descriptor_idx_; 126 } 127 } 128 std::string temp; 129 return GetIdFromString(dex_file, klass->GetDescriptor(&temp)); 130 } 131 132 // Try to find the string descriptor of the class. type_idx is a best guess of a matching string id. 133 static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file, 134 dex::TypeIndex type_idx, 135 ObjPtr<mirror::Class> klass) 136 REQUIRES_SHARED(Locks::mutator_lock_) { 137 if (!klass->IsArrayClass()) { 138 const dex::TypeId& type_id = dex_file.GetTypeId(type_idx); 139 const DexFile& klass_dex = klass->GetDexFile(); 140 const dex::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_); 141 if (strcmp(dex_file.GetTypeDescriptor(type_id), 142 klass_dex.GetTypeDescriptor(klass_type_id)) == 0) { 143 return type_id.descriptor_idx_; 144 } 145 } 146 return dex::StringIndex::Invalid(); 147 } 148 149 dex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file, 150 uint32_t dex_method_index, 151 ArtMethod* method) { 152 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 153 if (method == nullptr) { 154 return dex::StringIndex(VerifierDeps::kUnresolvedMarker); 155 } 156 const dex::StringIndex string_id = TryGetClassDescriptorStringId( 157 dex_file, 158 dex_file.GetMethodId(dex_method_index).class_idx_, 159 method->GetDeclaringClass()); 160 if (string_id.IsValid()) { 161 // Got lucky using the original dex file, return based on the input dex file. 162 DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id); 163 return string_id; 164 } 165 return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()); 166 } 167 168 dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file, 169 uint32_t dex_field_idx, 170 ArtField* field) { 171 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 172 if (field == nullptr) { 173 return dex::StringIndex(VerifierDeps::kUnresolvedMarker); 174 } 175 const dex::StringIndex string_id = TryGetClassDescriptorStringId( 176 dex_file, 177 dex_file.GetFieldId(dex_field_idx).class_idx_, 178 field->GetDeclaringClass()); 179 if (string_id.IsValid()) { 180 // Got lucky using the original dex file, return based on the input dex file. 181 DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id); 182 return string_id; 183 } 184 return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()); 185 } 186 187 static inline VerifierDeps* GetMainVerifierDeps() { 188 // The main VerifierDeps is the one set in the compiler callbacks, which at the 189 // end of verification will have all the per-thread VerifierDeps merged into it. 190 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks(); 191 if (callbacks == nullptr) { 192 return nullptr; 193 } 194 return callbacks->GetVerifierDeps(); 195 } 196 197 static inline VerifierDeps* GetThreadLocalVerifierDeps() { 198 // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end 199 // of full verification, these VerifierDeps will be merged into the main one. 200 if (!Runtime::Current()->IsAotCompiler()) { 201 return nullptr; 202 } 203 return Thread::Current()->GetVerifierDeps(); 204 } 205 206 static bool FindExistingStringId(const std::vector<std::string>& strings, 207 const std::string& str, 208 uint32_t* found_id) { 209 uint32_t num_extra_ids = strings.size(); 210 for (size_t i = 0; i < num_extra_ids; ++i) { 211 if (strings[i] == str) { 212 *found_id = i; 213 return true; 214 } 215 } 216 return false; 217 } 218 219 dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) { 220 const dex::StringId* string_id = dex_file.FindStringId(str.c_str()); 221 if (string_id != nullptr) { 222 // String is in the DEX file. Return its ID. 223 return dex_file.GetIndexForStringId(*string_id); 224 } 225 226 // String is not in the DEX file. Assign a new ID to it which is higher than 227 // the number of strings in the DEX file. 228 229 // We use the main `VerifierDeps` for adding new strings to simplify 230 // synchronization/merging of these entries between threads. 231 VerifierDeps* singleton = GetMainVerifierDeps(); 232 DexFileDeps* deps = singleton->GetDexFileDeps(dex_file); 233 DCHECK(deps != nullptr); 234 235 uint32_t num_ids_in_dex = dex_file.NumStringIds(); 236 uint32_t found_id; 237 238 { 239 ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); 240 if (FindExistingStringId(deps->strings_, str, &found_id)) { 241 return dex::StringIndex(num_ids_in_dex + found_id); 242 } 243 } 244 { 245 WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); 246 if (FindExistingStringId(deps->strings_, str, &found_id)) { 247 return dex::StringIndex(num_ids_in_dex + found_id); 248 } 249 deps->strings_.push_back(str); 250 dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1); 251 CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows 252 DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id)); 253 return new_id; 254 } 255 } 256 257 std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) 258 const { 259 uint32_t num_ids_in_dex = dex_file.NumStringIds(); 260 if (string_id.index_ < num_ids_in_dex) { 261 return std::string(dex_file.StringDataByIdx(string_id)); 262 } else { 263 const DexFileDeps* deps = GetDexFileDeps(dex_file); 264 DCHECK(deps != nullptr); 265 string_id.index_ -= num_ids_in_dex; 266 CHECK_LT(string_id.index_, deps->strings_.size()); 267 return deps->strings_[string_id.index_]; 268 } 269 } 270 271 bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const { 272 DCHECK(klass != nullptr); 273 274 // For array types, we return whether the non-array component type 275 // is in the classpath. 276 while (klass->IsArrayClass()) { 277 klass = klass->GetComponentType(); 278 } 279 280 if (klass->IsPrimitive()) { 281 return true; 282 } 283 284 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); 285 DCHECK(dex_cache != nullptr); 286 const DexFile* dex_file = dex_cache->GetDexFile(); 287 DCHECK(dex_file != nullptr); 288 289 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex 290 // file was not registered as being compiled and we assume `klass` is in the 291 // classpath. 292 return (GetDexFileDeps(*dex_file) == nullptr); 293 } 294 295 void VerifierDeps::AddClassResolution(const DexFile& dex_file, 296 dex::TypeIndex type_idx, 297 ObjPtr<mirror::Class> klass) { 298 DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 299 if (dex_deps == nullptr) { 300 // This invocation is from verification of a dex file which is not being compiled. 301 return; 302 } 303 304 if (klass != nullptr && !IsInClassPath(klass)) { 305 // Class resolved into one of the DEX files which are being compiled. 306 // This is not a classpath dependency. 307 return; 308 } 309 310 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass))); 311 } 312 313 void VerifierDeps::AddFieldResolution(const DexFile& dex_file, 314 uint32_t field_idx, 315 ArtField* field) { 316 DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 317 if (dex_deps == nullptr) { 318 // This invocation is from verification of a dex file which is not being compiled. 319 return; 320 } 321 322 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) { 323 // Field resolved into one of the DEX files which are being compiled. 324 // This is not a classpath dependency. 325 return; 326 } 327 328 dex_deps->fields_.emplace(FieldResolution(field_idx, 329 GetAccessFlags(field), 330 GetFieldDeclaringClassStringId(dex_file, 331 field_idx, 332 field))); 333 } 334 335 void VerifierDeps::AddMethodResolution(const DexFile& dex_file, 336 uint32_t method_idx, 337 ArtMethod* method) { 338 DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 339 if (dex_deps == nullptr) { 340 // This invocation is from verification of a dex file which is not being compiled. 341 return; 342 } 343 344 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) { 345 // Method resolved into one of the DEX files which are being compiled. 346 // This is not a classpath dependency. 347 return; 348 } 349 350 MethodResolution method_tuple(method_idx, 351 GetAccessFlags(method), 352 GetMethodDeclaringClassStringId(dex_file, method_idx, method)); 353 dex_deps->methods_.insert(method_tuple); 354 } 355 356 ObjPtr<mirror::Class> VerifierDeps::FindOneClassPathBoundaryForInterface( 357 ObjPtr<mirror::Class> destination, 358 ObjPtr<mirror::Class> source) const { 359 DCHECK(destination->IsInterface()); 360 DCHECK(IsInClassPath(destination)); 361 Thread* thread = Thread::Current(); 362 ObjPtr<mirror::Class> current = source; 363 // Record the classes that are at the boundary between the compiled DEX files and 364 // the classpath. We will check those classes later to find one class that inherits 365 // `destination`. 366 std::vector<ObjPtr<mirror::Class>> boundaries; 367 // If the destination is a direct interface of a class defined in the DEX files being 368 // compiled, no need to record it. 369 while (!IsInClassPath(current)) { 370 for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) { 371 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i); 372 if (direct == destination) { 373 return nullptr; 374 } else if (IsInClassPath(direct)) { 375 boundaries.push_back(direct); 376 } 377 } 378 current = current->GetSuperClass(); 379 } 380 DCHECK(current != nullptr); 381 boundaries.push_back(current); 382 383 // Check if we have an interface defined in the DEX files being compiled, direclty 384 // inheriting `destination`. 385 int32_t iftable_count = source->GetIfTableCount(); 386 ObjPtr<mirror::IfTable> iftable = source->GetIfTable(); 387 for (int32_t i = 0; i < iftable_count; ++i) { 388 ObjPtr<mirror::Class> itf = iftable->GetInterface(i); 389 if (!IsInClassPath(itf)) { 390 for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) { 391 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j); 392 if (direct == destination) { 393 return nullptr; 394 } else if (IsInClassPath(direct)) { 395 boundaries.push_back(direct); 396 } 397 } 398 } 399 } 400 401 // Find a boundary making `source` inherit from `destination`. We must find one. 402 for (const ObjPtr<mirror::Class>& boundary : boundaries) { 403 if (destination->IsAssignableFrom(boundary)) { 404 return boundary; 405 } 406 } 407 LOG(FATAL) << "Should have found a classpath boundary"; 408 UNREACHABLE(); 409 } 410 411 void VerifierDeps::AddAssignability(const DexFile& dex_file, 412 ObjPtr<mirror::Class> destination, 413 ObjPtr<mirror::Class> source, 414 bool is_strict, 415 bool is_assignable) { 416 // Test that the method is only called on reference types. 417 // Note that concurrent verification of `destination` and `source` may have 418 // set their status to erroneous. However, the tests performed below rely 419 // merely on no issues with linking (valid access flags, superclass and 420 // implemented interfaces). If the class at any point reached the IsResolved 421 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass. 422 DCHECK(destination != nullptr); 423 DCHECK(source != nullptr); 424 425 if (destination->IsPrimitive() || source->IsPrimitive()) { 426 // Primitive types are trivially non-assignable to anything else. 427 // We do not need to record trivial assignability, as it will 428 // not change across releases. 429 return; 430 } 431 432 if (source->IsObjectClass() && !is_assignable) { 433 // j.l.Object is trivially non-assignable to other types, don't 434 // record it. 435 return; 436 } 437 438 if (destination == source || 439 destination->IsObjectClass() || 440 (!is_strict && destination->IsInterface())) { 441 // Cases when `destination` is trivially assignable from `source`. 442 DCHECK(is_assignable); 443 return; 444 } 445 446 if (destination->IsArrayClass() && source->IsArrayClass()) { 447 // Both types are arrays. Break down to component types and add recursively. 448 // This helps filter out destinations from compiled DEX files (see below) 449 // and deduplicate entries with the same canonical component type. 450 ObjPtr<mirror::Class> destination_component = destination->GetComponentType(); 451 ObjPtr<mirror::Class> source_component = source->GetComponentType(); 452 453 // Only perform the optimization if both types are resolved which guarantees 454 // that they linked successfully, as required at the top of this method. 455 if (destination_component->IsResolved() && source_component->IsResolved()) { 456 AddAssignability(dex_file, 457 destination_component, 458 source_component, 459 /* is_strict= */ true, 460 is_assignable); 461 return; 462 } 463 } else { 464 // We only do this check for non-array types, as arrays might have erroneous 465 // component types which makes the IsAssignableFrom check unreliable. 466 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source)); 467 } 468 469 DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 470 if (dex_deps == nullptr) { 471 // This invocation is from verification of a DEX file which is not being compiled. 472 return; 473 } 474 475 if (!IsInClassPath(destination) && !IsInClassPath(source)) { 476 // Both `destination` and `source` are defined in the compiled DEX files. 477 // No need to record a dependency. 478 return; 479 } 480 481 if (!IsInClassPath(source)) { 482 if (!destination->IsInterface() && !source->IsInterface()) { 483 // Find the super class at the classpath boundary. Only that class 484 // can change the assignability. 485 do { 486 source = source->GetSuperClass(); 487 } while (!IsInClassPath(source)); 488 489 // If that class is the actual destination, no need to record it. 490 if (source == destination) { 491 return; 492 } 493 } else if (is_assignable) { 494 source = FindOneClassPathBoundaryForInterface(destination, source); 495 if (source == nullptr) { 496 // There was no classpath boundary, no need to record. 497 return; 498 } 499 DCHECK(IsInClassPath(source)); 500 } 501 } 502 503 504 // Get string IDs for both descriptors and store in the appropriate set. 505 dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination); 506 dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source); 507 508 if (is_assignable) { 509 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id)); 510 } else { 511 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id)); 512 } 513 } 514 515 void VerifierDeps::MaybeRecordClassRedefinition(const DexFile& dex_file, 516 const dex::ClassDef& class_def) { 517 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 518 if (thread_deps != nullptr) { 519 DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file); 520 DCHECK_EQ(dex_deps->redefined_classes_.size(), dex_file.NumClassDefs()); 521 dex_deps->redefined_classes_[dex_file.GetIndexForClassDef(class_def)] = true; 522 } 523 } 524 525 void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, 526 const dex::ClassDef& class_def, 527 FailureKind failure_kind) { 528 // The `verified_classes_` bit vector is initialized to `false`. 529 // Only continue if we are about to write `true`. 530 if (failure_kind == FailureKind::kNoFailure) { 531 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 532 if (thread_deps != nullptr) { 533 thread_deps->RecordClassVerified(dex_file, class_def); 534 } 535 } 536 } 537 538 void VerifierDeps::RecordClassVerified(const DexFile& dex_file, const dex::ClassDef& class_def) { 539 DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 540 DCHECK_EQ(dex_deps->verified_classes_.size(), dex_file.NumClassDefs()); 541 dex_deps->verified_classes_[dex_file.GetIndexForClassDef(class_def)] = true; 542 } 543 544 void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file, 545 dex::TypeIndex type_idx, 546 ObjPtr<mirror::Class> klass) { 547 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 548 if (thread_deps != nullptr) { 549 thread_deps->AddClassResolution(dex_file, type_idx, klass); 550 } 551 } 552 553 void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file, 554 uint32_t field_idx, 555 ArtField* field) { 556 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 557 if (thread_deps != nullptr) { 558 thread_deps->AddFieldResolution(dex_file, field_idx, field); 559 } 560 } 561 562 void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file, 563 uint32_t method_idx, 564 ArtMethod* method) { 565 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 566 if (thread_deps != nullptr) { 567 thread_deps->AddMethodResolution(dex_file, method_idx, method); 568 } 569 } 570 571 void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file, 572 ObjPtr<mirror::Class> destination, 573 ObjPtr<mirror::Class> source, 574 bool is_strict, 575 bool is_assignable) { 576 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 577 if (thread_deps != nullptr) { 578 thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable); 579 } 580 } 581 582 namespace { 583 584 static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) { 585 CHECK_LT(*in, end); 586 return DecodeUnsignedLeb128(in); 587 } 588 589 template<typename T> inline uint32_t Encode(T in); 590 591 template<> inline uint32_t Encode<uint16_t>(uint16_t in) { 592 return in; 593 } 594 template<> inline uint32_t Encode<uint32_t>(uint32_t in) { 595 return in; 596 } 597 template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) { 598 return in.index_; 599 } 600 template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) { 601 return in.index_; 602 } 603 604 template<typename T> inline T Decode(uint32_t in); 605 606 template<> inline uint16_t Decode<uint16_t>(uint32_t in) { 607 return dchecked_integral_cast<uint16_t>(in); 608 } 609 template<> inline uint32_t Decode<uint32_t>(uint32_t in) { 610 return in; 611 } 612 template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) { 613 return dex::TypeIndex(in); 614 } 615 template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) { 616 return dex::StringIndex(in); 617 } 618 619 template<typename T1, typename T2> 620 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) { 621 EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); 622 EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); 623 } 624 625 template<typename T1, typename T2> 626 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) { 627 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); 628 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); 629 *t = std::make_tuple(v1, v2); 630 } 631 632 template<typename T1, typename T2, typename T3> 633 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) { 634 EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); 635 EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); 636 EncodeUnsignedLeb128(out, Encode(std::get<2>(t))); 637 } 638 639 template<typename T1, typename T2, typename T3> 640 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) { 641 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); 642 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); 643 T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end)); 644 *t = std::make_tuple(v1, v2, v3); 645 } 646 647 template<typename T> 648 static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) { 649 EncodeUnsignedLeb128(out, set.size()); 650 for (const T& entry : set) { 651 EncodeTuple(out, entry); 652 } 653 } 654 655 template<typename T> 656 static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) { 657 DCHECK(set->empty()); 658 size_t num_entries = DecodeUint32WithOverflowCheck(in, end); 659 for (size_t i = 0; i < num_entries; ++i) { 660 T tuple; 661 DecodeTuple(in, end, &tuple); 662 set->emplace(tuple); 663 } 664 } 665 666 static inline void EncodeUint16SparseBitVector(std::vector<uint8_t>* out, 667 const std::vector<bool>& vector, 668 bool sparse_value) { 669 DCHECK(IsUint<16>(vector.size())); 670 EncodeUnsignedLeb128(out, std::count(vector.begin(), vector.end(), sparse_value)); 671 for (uint16_t idx = 0; idx < vector.size(); ++idx) { 672 if (vector[idx] == sparse_value) { 673 EncodeUnsignedLeb128(out, Encode(idx)); 674 } 675 } 676 } 677 678 static inline void DecodeUint16SparseBitVector(const uint8_t** in, 679 const uint8_t* end, 680 std::vector<bool>* vector, 681 bool sparse_value) { 682 DCHECK(IsUint<16>(vector->size())); 683 std::fill(vector->begin(), vector->end(), !sparse_value); 684 size_t num_entries = DecodeUint32WithOverflowCheck(in, end); 685 for (size_t i = 0; i < num_entries; ++i) { 686 uint16_t idx = Decode<uint16_t>(DecodeUint32WithOverflowCheck(in, end)); 687 DCHECK_LT(idx, vector->size()); 688 (*vector)[idx] = sparse_value; 689 } 690 } 691 692 static inline void EncodeStringVector(std::vector<uint8_t>* out, 693 const std::vector<std::string>& strings) { 694 EncodeUnsignedLeb128(out, strings.size()); 695 for (const std::string& str : strings) { 696 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str()); 697 size_t length = str.length() + 1; 698 out->insert(out->end(), data, data + length); 699 DCHECK_EQ(0u, out->back()); 700 } 701 } 702 703 static inline void DecodeStringVector(const uint8_t** in, 704 const uint8_t* end, 705 std::vector<std::string>* strings) { 706 DCHECK(strings->empty()); 707 size_t num_strings = DecodeUint32WithOverflowCheck(in, end); 708 strings->reserve(num_strings); 709 for (size_t i = 0; i < num_strings; ++i) { 710 CHECK_LT(*in, end); 711 const char* string_start = reinterpret_cast<const char*>(*in); 712 strings->emplace_back(std::string(string_start)); 713 *in += strings->back().length() + 1; 714 } 715 } 716 717 static inline std::string ToHex(uint32_t value) { 718 std::stringstream ss; 719 ss << std::hex << value << std::dec; 720 return ss.str(); 721 } 722 723 } // namespace 724 725 void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files, 726 std::vector<uint8_t>* buffer) const { 727 for (const DexFile* dex_file : dex_files) { 728 const DexFileDeps& deps = *GetDexFileDeps(*dex_file); 729 EncodeStringVector(buffer, deps.strings_); 730 EncodeSet(buffer, deps.assignable_types_); 731 EncodeSet(buffer, deps.unassignable_types_); 732 EncodeSet(buffer, deps.classes_); 733 EncodeSet(buffer, deps.fields_); 734 EncodeSet(buffer, deps.methods_); 735 EncodeUint16SparseBitVector(buffer, deps.verified_classes_, /* sparse_value= */ false); 736 EncodeUint16SparseBitVector(buffer, deps.redefined_classes_, /* sparse_value= */ true); 737 } 738 } 739 740 void VerifierDeps::DecodeDexFileDeps(DexFileDeps& deps, 741 const uint8_t** data_start, 742 const uint8_t* data_end) { 743 DecodeStringVector(data_start, data_end, &deps.strings_); 744 DecodeSet(data_start, data_end, &deps.assignable_types_); 745 DecodeSet(data_start, data_end, &deps.unassignable_types_); 746 DecodeSet(data_start, data_end, &deps.classes_); 747 DecodeSet(data_start, data_end, &deps.fields_); 748 DecodeSet(data_start, data_end, &deps.methods_); 749 DecodeUint16SparseBitVector(data_start, 750 data_end, 751 &deps.verified_classes_, 752 /* sparse_value= */ false); 753 DecodeUint16SparseBitVector(data_start, 754 data_end, 755 &deps.redefined_classes_, 756 /* sparse_value= */ true); 757 } 758 759 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, 760 ArrayRef<const uint8_t> data) 761 : VerifierDeps(dex_files, /*output_only=*/ false) { 762 if (data.empty()) { 763 // Return eagerly, as the first thing we expect from VerifierDeps data is 764 // the number of created strings, even if there is no dependency. 765 // Currently, only the boot image does not have any VerifierDeps data. 766 return; 767 } 768 const uint8_t* data_start = data.data(); 769 const uint8_t* data_end = data_start + data.size(); 770 for (const DexFile* dex_file : dex_files) { 771 DexFileDeps* deps = GetDexFileDeps(*dex_file); 772 DecodeDexFileDeps(*deps, &data_start, data_end); 773 } 774 CHECK_LE(data_start, data_end); 775 } 776 777 std::vector<std::vector<bool>> VerifierDeps::ParseVerifiedClasses( 778 const std::vector<const DexFile*>& dex_files, 779 ArrayRef<const uint8_t> data) { 780 DCHECK(!data.empty()); 781 DCHECK(!dex_files.empty()); 782 783 std::vector<std::vector<bool>> verified_classes_per_dex; 784 verified_classes_per_dex.reserve(dex_files.size()); 785 786 const uint8_t* data_start = data.data(); 787 const uint8_t* data_end = data_start + data.size(); 788 for (const DexFile* dex_file : dex_files) { 789 DexFileDeps deps(dex_file->NumClassDefs()); 790 DecodeDexFileDeps(deps, &data_start, data_end); 791 verified_classes_per_dex.push_back(std::move(deps.verified_classes_)); 792 } 793 return verified_classes_per_dex; 794 } 795 796 bool VerifierDeps::Equals(const VerifierDeps& rhs) const { 797 if (dex_deps_.size() != rhs.dex_deps_.size()) { 798 return false; 799 } 800 801 auto lhs_it = dex_deps_.begin(); 802 auto rhs_it = rhs.dex_deps_.begin(); 803 804 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) { 805 const DexFile* lhs_dex_file = lhs_it->first; 806 const DexFile* rhs_dex_file = rhs_it->first; 807 if (lhs_dex_file != rhs_dex_file) { 808 return false; 809 } 810 811 DexFileDeps* lhs_deps = lhs_it->second.get(); 812 DexFileDeps* rhs_deps = rhs_it->second.get(); 813 if (!lhs_deps->Equals(*rhs_deps)) { 814 return false; 815 } 816 } 817 818 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end())); 819 return true; 820 } 821 822 bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const { 823 return (strings_ == rhs.strings_) && 824 (assignable_types_ == rhs.assignable_types_) && 825 (unassignable_types_ == rhs.unassignable_types_) && 826 (classes_ == rhs.classes_) && 827 (fields_ == rhs.fields_) && 828 (methods_ == rhs.methods_) && 829 (verified_classes_ == rhs.verified_classes_); 830 } 831 832 void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const { 833 for (const auto& dep : dex_deps_) { 834 const DexFile& dex_file = *dep.first; 835 vios->Stream() 836 << "Dependencies of " 837 << dex_file.GetLocation() 838 << ":\n"; 839 840 ScopedIndentation indent(vios); 841 842 for (const std::string& str : dep.second->strings_) { 843 vios->Stream() << "Extra string: " << str << "\n"; 844 } 845 846 for (const TypeAssignability& entry : dep.second->assignable_types_) { 847 vios->Stream() 848 << GetStringFromId(dex_file, entry.GetSource()) 849 << " must be assignable to " 850 << GetStringFromId(dex_file, entry.GetDestination()) 851 << "\n"; 852 } 853 854 for (const TypeAssignability& entry : dep.second->unassignable_types_) { 855 vios->Stream() 856 << GetStringFromId(dex_file, entry.GetSource()) 857 << " must not be assignable to " 858 << GetStringFromId(dex_file, entry.GetDestination()) 859 << "\n"; 860 } 861 862 for (const ClassResolution& entry : dep.second->classes_) { 863 vios->Stream() 864 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex()) 865 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ") 866 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec 867 << "\n"; 868 } 869 870 for (const FieldResolution& entry : dep.second->fields_) { 871 const dex::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex()); 872 vios->Stream() 873 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->" 874 << dex_file.GetFieldName(field_id) << ":" 875 << dex_file.GetFieldTypeDescriptor(field_id) 876 << " is expected to be "; 877 if (!entry.IsResolved()) { 878 vios->Stream() << "unresolved\n"; 879 } else { 880 vios->Stream() 881 << "in class " 882 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 883 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec 884 << "\n"; 885 } 886 } 887 888 for (const MethodResolution& method : dep.second->methods_) { 889 const dex::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex()); 890 vios->Stream() 891 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->" 892 << dex_file.GetMethodName(method_id) 893 << dex_file.GetMethodSignature(method_id).ToString() 894 << " is expected to be "; 895 if (!method.IsResolved()) { 896 vios->Stream() << "unresolved\n"; 897 } else { 898 vios->Stream() 899 << "in class " 900 << GetStringFromId(dex_file, method.GetDeclaringClassIndex()) 901 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec 902 << "\n"; 903 } 904 } 905 906 for (size_t idx = 0; idx < dep.second->verified_classes_.size(); idx++) { 907 if (!dep.second->verified_classes_[idx]) { 908 vios->Stream() 909 << dex_file.GetClassDescriptor(dex_file.GetClassDef(idx)) 910 << " will be verified at runtime\n"; 911 } 912 } 913 } 914 } 915 916 bool VerifierDeps::ValidateDependencies(Thread* self, 917 Handle<mirror::ClassLoader> class_loader, 918 const std::vector<const DexFile*>& classpath, 919 /* out */ std::string* error_msg) const { 920 for (const auto& entry : dex_deps_) { 921 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, classpath, self, error_msg)) { 922 return false; 923 } 924 } 925 return true; 926 } 927 928 // TODO: share that helper with other parts of the compiler that have 929 // the same lookup pattern. 930 static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker, 931 Thread* self, 932 const std::string& name, 933 Handle<mirror::ClassLoader> class_loader) 934 REQUIRES_SHARED(Locks::mutator_lock_) { 935 ObjPtr<mirror::Class> result = class_linker->FindClass(self, name.c_str(), class_loader); 936 if (result == nullptr) { 937 DCHECK(self->IsExceptionPending()); 938 self->ClearException(); 939 } 940 return result; 941 } 942 943 bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader, 944 const DexFile& dex_file, 945 const std::set<TypeAssignability>& assignables, 946 bool expected_assignability, 947 Thread* self, 948 /* out */ std::string* error_msg) const { 949 StackHandleScope<2> hs(self); 950 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 951 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr)); 952 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr)); 953 954 for (const auto& entry : assignables) { 955 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination()); 956 destination.Assign( 957 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader)); 958 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource()); 959 source.Assign( 960 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader)); 961 962 if (destination == nullptr) { 963 *error_msg = "Could not resolve class " + destination_desc; 964 return false; 965 } 966 967 if (source == nullptr) { 968 *error_msg = "Could not resolve class " + source_desc; 969 return false; 970 } 971 972 DCHECK(destination->IsResolved() && source->IsResolved()); 973 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) { 974 *error_msg = "Class " + destination_desc + (expected_assignability ? " not " : " ") + 975 "assignable from " + source_desc; 976 return false; 977 } 978 } 979 return true; 980 } 981 982 bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader, 983 const DexFile& dex_file, 984 const std::set<ClassResolution>& classes, 985 Thread* self, 986 /* out */ std::string* error_msg) const { 987 StackHandleScope<1> hs(self); 988 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 989 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr)); 990 for (const auto& entry : classes) { 991 std::string descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex()); 992 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader)); 993 994 if (entry.IsResolved()) { 995 if (cls == nullptr) { 996 *error_msg = "Could not resolve class " + descriptor; 997 return false; 998 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) { 999 *error_msg = "Unexpected access flags on class " + descriptor 1000 + " (expected=" + ToHex(entry.GetAccessFlags()) 1001 + ", actual=" + ToHex(GetAccessFlags(cls.Get())) + ")"; 1002 return false; 1003 } 1004 } else if (cls != nullptr) { 1005 *error_msg = "Unexpected successful resolution of class " + descriptor; 1006 return false; 1007 } 1008 } 1009 return true; 1010 } 1011 1012 static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) { 1013 const dex::FieldId& field_id = dex_file.GetFieldId(index); 1014 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id)) 1015 + "->" 1016 + dex_file.GetFieldName(field_id) 1017 + ":" 1018 + dex_file.GetFieldTypeDescriptor(field_id); 1019 } 1020 1021 bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader, 1022 const DexFile& dex_file, 1023 const std::set<FieldResolution>& fields, 1024 Thread* self, 1025 /* out */ std::string* error_msg) const { 1026 // Check recorded fields are resolved the same way, have the same recorded class, 1027 // and have the same recorded flags. 1028 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1029 for (const auto& entry : fields) { 1030 const dex::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex()); 1031 std::string_view name(dex_file.StringDataByIdx(field_id.name_idx_)); 1032 std::string_view type( 1033 dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_)); 1034 // Only use field_id.class_idx_ when the entry is unresolved, which is rare. 1035 // Otherwise, we might end up resolving an application class, which is expensive. 1036 std::string expected_decl_klass = entry.IsResolved() 1037 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 1038 : dex_file.StringByTypeIdx(field_id.class_idx_); 1039 ObjPtr<mirror::Class> cls = FindClassAndClearException( 1040 class_linker, self, expected_decl_klass.c_str(), class_loader); 1041 if (cls == nullptr) { 1042 *error_msg = "Could not resolve class " + expected_decl_klass; 1043 return false; 1044 } 1045 DCHECK(cls->IsResolved()); 1046 1047 ArtField* field = mirror::Class::FindField(self, cls, name, type); 1048 if (entry.IsResolved()) { 1049 std::string temp; 1050 if (field == nullptr) { 1051 *error_msg = "Could not resolve field " + 1052 GetFieldDescription(dex_file, entry.GetDexFieldIndex()); 1053 return false; 1054 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) { 1055 *error_msg = "Unexpected declaring class for field resolution " 1056 + GetFieldDescription(dex_file, entry.GetDexFieldIndex()) 1057 + " (expected=" + expected_decl_klass 1058 + ", actual=" + field->GetDeclaringClass()->GetDescriptor(&temp) + ")"; 1059 return false; 1060 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) { 1061 *error_msg = "Unexpected access flags for resolved field " 1062 + GetFieldDescription(dex_file, entry.GetDexFieldIndex()) 1063 + " (expected=" + ToHex(entry.GetAccessFlags()) 1064 + ", actual=" + ToHex(GetAccessFlags(field)) + ")"; 1065 return false; 1066 } 1067 } else if (field != nullptr) { 1068 *error_msg = "Unexpected successful resolution of field " 1069 + GetFieldDescription(dex_file, entry.GetDexFieldIndex()); 1070 return false; 1071 } 1072 } 1073 return true; 1074 } 1075 1076 static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) { 1077 const dex::MethodId& method_id = dex_file.GetMethodId(index); 1078 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id)) 1079 + "->" 1080 + dex_file.GetMethodName(method_id) 1081 + dex_file.GetMethodSignature(method_id).ToString(); 1082 } 1083 1084 bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader, 1085 const DexFile& dex_file, 1086 const std::set<MethodResolution>& methods, 1087 Thread* self, 1088 /* out */ std::string* error_msg) const { 1089 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1090 PointerSize pointer_size = class_linker->GetImagePointerSize(); 1091 1092 for (const auto& entry : methods) { 1093 const dex::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex()); 1094 1095 const char* name = dex_file.GetMethodName(method_id); 1096 const Signature signature = dex_file.GetMethodSignature(method_id); 1097 // Only use method_id.class_idx_ when the entry is unresolved, which is rare. 1098 // Otherwise, we might end up resolving an application class, which is expensive. 1099 std::string expected_decl_klass = entry.IsResolved() 1100 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 1101 : dex_file.StringByTypeIdx(method_id.class_idx_); 1102 1103 ObjPtr<mirror::Class> cls = FindClassAndClearException( 1104 class_linker, self, expected_decl_klass.c_str(), class_loader); 1105 if (cls == nullptr) { 1106 *error_msg = "Could not resolve class " + expected_decl_klass; 1107 return false; 1108 } 1109 DCHECK(cls->IsResolved()); 1110 ArtMethod* method = nullptr; 1111 if (cls->IsInterface()) { 1112 method = cls->FindInterfaceMethod(name, signature, pointer_size); 1113 } else { 1114 method = cls->FindClassMethod(name, signature, pointer_size); 1115 } 1116 1117 if (entry.IsResolved()) { 1118 std::string temp; 1119 if (method == nullptr) { 1120 *error_msg = "Could not resolve method " 1121 + GetMethodDescription(dex_file, entry.GetDexMethodIndex()); 1122 return false; 1123 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) { 1124 *error_msg = "Unexpected declaring class for method resolution " 1125 + GetMethodDescription(dex_file, entry.GetDexMethodIndex()) 1126 + " (expected=" + expected_decl_klass 1127 + ", actual=" + method->GetDeclaringClass()->GetDescriptor(&temp) + ")"; 1128 return false; 1129 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) { 1130 *error_msg = "Unexpected access flags for resolved method resolution " 1131 + GetMethodDescription(dex_file, entry.GetDexMethodIndex()) 1132 + " (expected=" + ToHex(entry.GetAccessFlags()) 1133 + ", actual=" + ToHex(GetAccessFlags(method)) + ")"; 1134 return false; 1135 } 1136 } else if (method != nullptr) { 1137 *error_msg = "Unexpected successful resolution of method " 1138 + GetMethodDescription(dex_file, entry.GetDexMethodIndex()); 1139 return false; 1140 } 1141 } 1142 return true; 1143 } 1144 1145 bool VerifierDeps::IsInDexFiles(const char* descriptor, 1146 size_t hash, 1147 const std::vector<const DexFile*>& dex_files, 1148 /* out */ const DexFile** out_dex_file) const { 1149 for (const DexFile* dex_file : dex_files) { 1150 if (OatDexFile::FindClassDef(*dex_file, descriptor, hash) != nullptr) { 1151 *out_dex_file = dex_file; 1152 return true; 1153 } 1154 } 1155 return false; 1156 } 1157 1158 bool VerifierDeps::VerifyInternalClasses(const DexFile& dex_file, 1159 const std::vector<const DexFile*>& classpath, 1160 const std::vector<bool>& verified_classes, 1161 const std::vector<bool>& redefined_classes, 1162 /* out */ std::string* error_msg) const { 1163 const std::vector<const DexFile*>& boot_classpath = 1164 Runtime::Current()->GetClassLinker()->GetBootClassPath(); 1165 1166 for (ClassAccessor accessor : dex_file.GetClasses()) { 1167 const char* descriptor = accessor.GetDescriptor(); 1168 1169 const uint16_t class_def_index = accessor.GetClassDefIndex(); 1170 if (redefined_classes[class_def_index]) { 1171 if (verified_classes[class_def_index]) { 1172 *error_msg = std::string("Class ") + descriptor + " marked both verified and redefined"; 1173 return false; 1174 } 1175 1176 // Class was not verified under these dependencies. No need to check it further. 1177 continue; 1178 } 1179 1180 // Check that the class resolved into the same dex file. Otherwise there is 1181 // a different class with the same descriptor somewhere in one of the parent 1182 // class loaders. 1183 const size_t hash = ComputeModifiedUtf8Hash(descriptor); 1184 const DexFile* cp_dex_file = nullptr; 1185 if (IsInDexFiles(descriptor, hash, boot_classpath, &cp_dex_file) || 1186 IsInDexFiles(descriptor, hash, classpath, &cp_dex_file)) { 1187 *error_msg = std::string("Class ") + descriptor 1188 + " redefines a class in the classpath " 1189 + "(dexFile expected=" + dex_file.GetLocation() 1190 + ", actual=" + cp_dex_file->GetLocation() + ")"; 1191 return false; 1192 } 1193 } 1194 1195 return true; 1196 } 1197 1198 bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader, 1199 const DexFile& dex_file, 1200 const DexFileDeps& deps, 1201 const std::vector<const DexFile*>& classpath, 1202 Thread* self, 1203 /* out */ std::string* error_msg) const { 1204 return VerifyInternalClasses(dex_file, 1205 classpath, 1206 deps.verified_classes_, 1207 deps.redefined_classes_, 1208 error_msg) && 1209 VerifyAssignability(class_loader, 1210 dex_file, 1211 deps.assignable_types_, 1212 /* expected_assignability= */ true, 1213 self, 1214 error_msg) && 1215 VerifyAssignability(class_loader, 1216 dex_file, 1217 deps.unassignable_types_, 1218 /* expected_assignability= */ false, 1219 self, 1220 error_msg) && 1221 VerifyClasses(class_loader, dex_file, deps.classes_, self, error_msg) && 1222 VerifyFields(class_loader, dex_file, deps.fields_, self, error_msg) && 1223 VerifyMethods(class_loader, dex_file, deps.methods_, self, error_msg); 1224 } 1225 1226 } // namespace verifier 1227 } // namespace art 1228