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 "method_verifier-inl.h" 18 19 #include <ostream> 20 21 #include "android-base/stringprintf.h" 22 23 #include "art_field-inl.h" 24 #include "art_method-inl.h" 25 #include "base/aborting.h" 26 #include "base/enums.h" 27 #include "base/leb128.h" 28 #include "base/indenter.h" 29 #include "base/logging.h" // For VLOG. 30 #include "base/mutex-inl.h" 31 #include "base/sdk_version.h" 32 #include "base/stl_util.h" 33 #include "base/systrace.h" 34 #include "base/time_utils.h" 35 #include "base/utils.h" 36 #include "class_linker.h" 37 #include "class_root.h" 38 #include "compiler_callbacks.h" 39 #include "dex/class_accessor-inl.h" 40 #include "dex/descriptors_names.h" 41 #include "dex/dex_file-inl.h" 42 #include "dex/dex_file_exception_helpers.h" 43 #include "dex/dex_instruction-inl.h" 44 #include "dex/dex_instruction_utils.h" 45 #include "experimental_flags.h" 46 #include "gc/accounting/card_table-inl.h" 47 #include "handle_scope-inl.h" 48 #include "intern_table.h" 49 #include "mirror/class-inl.h" 50 #include "mirror/class.h" 51 #include "mirror/class_loader.h" 52 #include "mirror/dex_cache-inl.h" 53 #include "mirror/method_handle_impl.h" 54 #include "mirror/method_type.h" 55 #include "mirror/object-inl.h" 56 #include "mirror/object_array-inl.h" 57 #include "mirror/var_handle.h" 58 #include "obj_ptr-inl.h" 59 #include "reg_type-inl.h" 60 #include "register_line-inl.h" 61 #include "runtime.h" 62 #include "scoped_newline.h" 63 #include "scoped_thread_state_change-inl.h" 64 #include "stack.h" 65 #include "vdex_file.h" 66 #include "verifier_compiler_binding.h" 67 #include "verifier_deps.h" 68 69 namespace art { 70 namespace verifier { 71 72 using android::base::StringPrintf; 73 74 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild; 75 76 PcToRegisterLineTable::PcToRegisterLineTable(ScopedArenaAllocator& allocator) 77 : register_lines_(allocator.Adapter(kArenaAllocVerifier)) {} 78 79 void PcToRegisterLineTable::Init(RegisterTrackingMode mode, 80 InstructionFlags* flags, 81 uint32_t insns_size, 82 uint16_t registers_size, 83 ScopedArenaAllocator& allocator, 84 RegTypeCache* reg_types) { 85 DCHECK_GT(insns_size, 0U); 86 register_lines_.resize(insns_size); 87 for (uint32_t i = 0; i < insns_size; i++) { 88 bool interesting = false; 89 switch (mode) { 90 case kTrackRegsAll: 91 interesting = flags[i].IsOpcode(); 92 break; 93 case kTrackCompilerInterestPoints: 94 interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget(); 95 break; 96 case kTrackRegsBranches: 97 interesting = flags[i].IsBranchTarget(); 98 break; 99 default: 100 break; 101 } 102 if (interesting) { 103 register_lines_[i].reset(RegisterLine::Create(registers_size, allocator, reg_types)); 104 } 105 } 106 } 107 108 PcToRegisterLineTable::~PcToRegisterLineTable() {} 109 110 namespace impl { 111 namespace { 112 113 enum class CheckAccess { 114 kYes, 115 kNo, 116 }; 117 118 enum class FieldAccessType { 119 kAccGet, 120 kAccPut 121 }; 122 123 template <bool kVerifierDebug> 124 class MethodVerifier final : public ::art::verifier::MethodVerifier { 125 public: 126 bool IsInstanceConstructor() const { 127 return IsConstructor() && !IsStatic(); 128 } 129 130 const RegType& ResolveCheckedClass(dex::TypeIndex class_idx) override 131 REQUIRES_SHARED(Locks::mutator_lock_) { 132 DCHECK(!HasFailures()); 133 const RegType& result = ResolveClass<CheckAccess::kYes>(class_idx); 134 DCHECK(!HasFailures()); 135 return result; 136 } 137 138 void FindLocksAtDexPc() REQUIRES_SHARED(Locks::mutator_lock_); 139 140 private: 141 MethodVerifier(Thread* self, 142 const DexFile* dex_file, 143 Handle<mirror::DexCache> dex_cache, 144 Handle<mirror::ClassLoader> class_loader, 145 const dex::ClassDef& class_def, 146 const dex::CodeItem* code_item, 147 uint32_t method_idx, 148 ArtMethod* method, 149 uint32_t access_flags, 150 bool can_load_classes, 151 bool allow_soft_failures, 152 bool need_precise_constants, 153 bool verify_to_dump, 154 bool allow_thread_suspension, 155 uint32_t api_level) 156 REQUIRES_SHARED(Locks::mutator_lock_); 157 158 void UninstantiableError(const char* descriptor) { 159 Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for " 160 << "non-instantiable klass " << descriptor; 161 } 162 static bool IsInstantiableOrPrimitive(ObjPtr<mirror::Class> klass) 163 REQUIRES_SHARED(Locks::mutator_lock_) { 164 return klass->IsInstantiable() || klass->IsPrimitive(); 165 } 166 167 // Is the method being verified a constructor? See the comment on the field. 168 bool IsConstructor() const { 169 return is_constructor_; 170 } 171 172 // Is the method verified static? 173 bool IsStatic() const { 174 return (method_access_flags_ & kAccStatic) != 0; 175 } 176 177 // Adds the given string to the beginning of the last failure message. 178 void PrependToLastFailMessage(std::string); 179 180 // Adds the given string to the end of the last failure message. 181 void AppendToLastFailMessage(const std::string& append); 182 183 /* 184 * Compute the width of the instruction at each address in the instruction stream, and store it in 185 * insn_flags_. Addresses that are in the middle of an instruction, or that are part of switch 186 * table data, are not touched (so the caller should probably initialize "insn_flags" to zero). 187 * 188 * The "new_instance_count_" and "monitor_enter_count_" fields in vdata are also set. 189 * 190 * Performs some static checks, notably: 191 * - opcode of first instruction begins at index 0 192 * - only documented instructions may appear 193 * - each instruction follows the last 194 * - last byte of last instruction is at (code_length-1) 195 * 196 * Logs an error and returns "false" on failure. 197 */ 198 bool ComputeWidthsAndCountOps(); 199 200 /* 201 * Set the "in try" flags for all instructions protected by "try" statements. Also sets the 202 * "branch target" flags for exception handlers. 203 * 204 * Call this after widths have been set in "insn_flags". 205 * 206 * Returns "false" if something in the exception table looks fishy, but we're expecting the 207 * exception table to be somewhat sane. 208 */ 209 bool ScanTryCatchBlocks() REQUIRES_SHARED(Locks::mutator_lock_); 210 211 /* 212 * Perform static verification on all instructions in a method. 213 * 214 * Walks through instructions in a method calling VerifyInstruction on each. 215 */ 216 template <bool kAllowRuntimeOnlyInstructions> 217 bool VerifyInstructions(); 218 219 /* 220 * Perform static verification on an instruction. 221 * 222 * As a side effect, this sets the "branch target" flags in InsnFlags. 223 * 224 * "(CF)" items are handled during code-flow analysis. 225 * 226 * v3 4.10.1 227 * - target of each jump and branch instruction must be valid 228 * - targets of switch statements must be valid 229 * - operands referencing constant pool entries must be valid 230 * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid 231 * - (CF) operands of method invocation instructions must be valid 232 * - (CF) only invoke-direct can call a method starting with '<' 233 * - (CF) <clinit> must never be called explicitly 234 * - operands of instanceof, checkcast, new (and variants) must be valid 235 * - new-array[-type] limited to 255 dimensions 236 * - can't use "new" on an array class 237 * - (?) limit dimensions in multi-array creation 238 * - local variable load/store register values must be in valid range 239 * 240 * v3 4.11.1.2 241 * - branches must be within the bounds of the code array 242 * - targets of all control-flow instructions are the start of an instruction 243 * - register accesses fall within range of allocated registers 244 * - (N/A) access to constant pool must be of appropriate type 245 * - code does not end in the middle of an instruction 246 * - execution cannot fall off the end of the code 247 * - (earlier) for each exception handler, the "try" area must begin and 248 * end at the start of an instruction (end can be at the end of the code) 249 * - (earlier) for each exception handler, the handler must start at a valid 250 * instruction 251 */ 252 template <bool kAllowRuntimeOnlyInstructions> 253 bool VerifyInstruction(const Instruction* inst, uint32_t code_offset); 254 255 /* Ensure that the register index is valid for this code item. */ 256 bool CheckRegisterIndex(uint32_t idx); 257 258 /* Ensure that the wide register index is valid for this code item. */ 259 bool CheckWideRegisterIndex(uint32_t idx); 260 261 // Perform static checks on an instruction referencing a CallSite. All we do here is ensure that 262 // the call site index is in the valid range. 263 bool CheckCallSiteIndex(uint32_t idx); 264 265 // Perform static checks on a field Get or set instruction. All we do here is ensure that the 266 // field index is in the valid range. 267 bool CheckFieldIndex(uint32_t idx); 268 269 // Perform static checks on a method invocation instruction. All we do here is ensure that the 270 // method index is in the valid range. 271 bool CheckMethodIndex(uint32_t idx); 272 273 // Perform static checks on an instruction referencing a constant method handle. All we do here 274 // is ensure that the method index is in the valid range. 275 bool CheckMethodHandleIndex(uint32_t idx); 276 277 // Perform static checks on a "new-instance" instruction. Specifically, make sure the class 278 // reference isn't for an array class. 279 bool CheckNewInstance(dex::TypeIndex idx); 280 281 // Perform static checks on a prototype indexing instruction. All we do here is ensure that the 282 // prototype index is in the valid range. 283 bool CheckPrototypeIndex(uint32_t idx); 284 285 /* Ensure that the string index is in the valid range. */ 286 bool CheckStringIndex(uint32_t idx); 287 288 // Perform static checks on an instruction that takes a class constant. Ensure that the class 289 // index is in the valid range. 290 bool CheckTypeIndex(dex::TypeIndex idx); 291 292 // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't 293 // creating an array of arrays that causes the number of dimensions to exceed 255. 294 bool CheckNewArray(dex::TypeIndex idx); 295 296 // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction. 297 bool CheckArrayData(uint32_t cur_offset); 298 299 // Verify that the target of a branch instruction is valid. We don't expect code to jump directly 300 // into an exception handler, but it's valid to do so as long as the target isn't a 301 // "move-exception" instruction. We verify that in a later stage. 302 // The dex format forbids certain instructions from branching to themselves. 303 // Updates "insn_flags_", setting the "branch target" flag. 304 bool CheckBranchTarget(uint32_t cur_offset); 305 306 // Verify a switch table. "cur_offset" is the offset of the switch instruction. 307 // Updates "insn_flags_", setting the "branch target" flag. 308 bool CheckSwitchTargets(uint32_t cur_offset); 309 310 // Check the register indices used in a "vararg" instruction, such as invoke-virtual or 311 // filled-new-array. 312 // - vA holds word count (0-5), args[] have values. 313 // There are some tests we don't do here, e.g. we don't try to verify that invoking a method that 314 // takes a double is done with consecutive registers. This requires parsing the target method 315 // signature, which we will be doing later on during the code flow analysis. 316 bool CheckVarArgRegs(uint32_t vA, uint32_t arg[]); 317 318 // Check the register indices used in a "vararg/range" instruction, such as invoke-virtual/range 319 // or filled-new-array/range. 320 // - vA holds word count, vC holds index of first reg. 321 bool CheckVarArgRangeRegs(uint32_t vA, uint32_t vC); 322 323 // Checks the method matches the expectations required to be signature polymorphic. 324 bool CheckSignaturePolymorphicMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 325 326 // Checks the invoked receiver matches the expectations for signature polymorphic methods. 327 bool CheckSignaturePolymorphicReceiver(const Instruction* inst) REQUIRES_SHARED(Locks::mutator_lock_); 328 329 // Extract the relative offset from a branch instruction. 330 // Returns "false" on failure (e.g. this isn't a branch instruction). 331 bool GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional, 332 bool* selfOkay); 333 334 /* Perform detailed code-flow analysis on a single method. */ 335 bool VerifyCodeFlow() REQUIRES_SHARED(Locks::mutator_lock_); 336 337 // Set the register types for the first instruction in the method based on the method signature. 338 // This has the side-effect of validating the signature. 339 bool SetTypesFromSignature() REQUIRES_SHARED(Locks::mutator_lock_); 340 341 /* 342 * Perform code flow on a method. 343 * 344 * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit on the first 345 * instruction, process it (setting additional "changed" bits), and repeat until there are no 346 * more. 347 * 348 * v3 4.11.1.1 349 * - (N/A) operand stack is always the same size 350 * - operand stack [registers] contain the correct types of values 351 * - local variables [registers] contain the correct types of values 352 * - methods are invoked with the appropriate arguments 353 * - fields are assigned using values of appropriate types 354 * - opcodes have the correct type values in operand registers 355 * - there is never an uninitialized class instance in a local variable in code protected by an 356 * exception handler (operand stack is okay, because the operand stack is discarded when an 357 * exception is thrown) [can't know what's a local var w/o the debug info -- should fall out of 358 * register typing] 359 * 360 * v3 4.11.1.2 361 * - execution cannot fall off the end of the code 362 * 363 * (We also do many of the items described in the "static checks" sections, because it's easier to 364 * do them here.) 365 * 366 * We need an array of RegType values, one per register, for every instruction. If the method uses 367 * monitor-enter, we need extra data for every register, and a stack for every "interesting" 368 * instruction. In theory this could become quite large -- up to several megabytes for a monster 369 * function. 370 * 371 * NOTE: 372 * The spec forbids backward branches when there's an uninitialized reference in a register. The 373 * idea is to prevent something like this: 374 * loop: 375 * move r1, r0 376 * new-instance r0, MyClass 377 * ... 378 * if-eq rN, loop // once 379 * initialize r0 380 * 381 * This leaves us with two different instances, both allocated by the same instruction, but only 382 * one is initialized. The scheme outlined in v3 4.11.1.4 wouldn't catch this, so they work around 383 * it by preventing backward branches. We achieve identical results without restricting code 384 * reordering by specifying that you can't execute the new-instance instruction if a register 385 * contains an uninitialized instance created by that same instruction. 386 */ 387 bool CodeFlowVerifyMethod() REQUIRES_SHARED(Locks::mutator_lock_); 388 389 /* 390 * Perform verification for a single instruction. 391 * 392 * This requires fully decoding the instruction to determine the effect it has on registers. 393 * 394 * Finds zero or more following instructions and sets the "changed" flag if execution at that 395 * point needs to be (re-)evaluated. Register changes are merged into "reg_types_" at the target 396 * addresses. Does not set or clear any other flags in "insn_flags_". 397 */ 398 bool CodeFlowVerifyInstruction(uint32_t* start_guess) 399 REQUIRES_SHARED(Locks::mutator_lock_); 400 401 // Perform verification of a new array instruction 402 void VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) 403 REQUIRES_SHARED(Locks::mutator_lock_); 404 405 // Helper to perform verification on puts of primitive type. 406 void VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type, 407 const uint32_t vregA) REQUIRES_SHARED(Locks::mutator_lock_); 408 409 // Perform verification of an aget instruction. The destination register's type will be set to 410 // be that of component type of the array unless the array type is unknown, in which case a 411 // bottom type inferred from the type of instruction is used. is_primitive is false for an 412 // aget-object. 413 void VerifyAGet(const Instruction* inst, const RegType& insn_type, 414 bool is_primitive) REQUIRES_SHARED(Locks::mutator_lock_); 415 416 // Perform verification of an aput instruction. 417 void VerifyAPut(const Instruction* inst, const RegType& insn_type, 418 bool is_primitive) REQUIRES_SHARED(Locks::mutator_lock_); 419 420 // Lookup instance field and fail for resolution violations 421 ArtField* GetInstanceField(const RegType& obj_type, int field_idx) 422 REQUIRES_SHARED(Locks::mutator_lock_); 423 424 // Lookup static field and fail for resolution violations 425 ArtField* GetStaticField(int field_idx) REQUIRES_SHARED(Locks::mutator_lock_); 426 427 // Perform verification of an iget/sget/iput/sput instruction. 428 template <FieldAccessType kAccType> 429 void VerifyISFieldAccess(const Instruction* inst, const RegType& insn_type, 430 bool is_primitive, bool is_static) 431 REQUIRES_SHARED(Locks::mutator_lock_); 432 433 // Resolves a class based on an index and, if C is kYes, performs access checks to ensure 434 // the referrer can access the resolved class. 435 template <CheckAccess C> 436 const RegType& ResolveClass(dex::TypeIndex class_idx) 437 REQUIRES_SHARED(Locks::mutator_lock_); 438 439 /* 440 * For the "move-exception" instruction at "work_insn_idx_", which must be at an exception handler 441 * address, determine the Join of all exceptions that can land here. Fails if no matching 442 * exception handler can be found or if the Join of exception types fails. 443 */ 444 const RegType& GetCaughtExceptionType() 445 REQUIRES_SHARED(Locks::mutator_lock_); 446 447 /* 448 * Resolves a method based on an index and performs access checks to ensure 449 * the referrer can access the resolved method. 450 * Does not throw exceptions. 451 */ 452 ArtMethod* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type) 453 REQUIRES_SHARED(Locks::mutator_lock_); 454 455 /* 456 * Verify the arguments to a method. We're executing in "method", making 457 * a call to the method reference in vB. 458 * 459 * If this is a "direct" invoke, we allow calls to <init>. For calls to 460 * <init>, the first argument may be an uninitialized reference. Otherwise, 461 * calls to anything starting with '<' will be rejected, as will any 462 * uninitialized reference arguments. 463 * 464 * For non-static method calls, this will verify that the method call is 465 * appropriate for the "this" argument. 466 * 467 * The method reference is in vBBBB. The "is_range" parameter determines 468 * whether we use 0-4 "args" values or a range of registers defined by 469 * vAA and vCCCC. 470 * 471 * Widening conversions on integers and references are allowed, but 472 * narrowing conversions are not. 473 * 474 * Returns the resolved method on success, null on failure (with *failure 475 * set appropriately). 476 */ 477 ArtMethod* VerifyInvocationArgs(const Instruction* inst, MethodType method_type, bool is_range) 478 REQUIRES_SHARED(Locks::mutator_lock_); 479 480 // Similar checks to the above, but on the proto. Will be used when the method cannot be 481 // resolved. 482 void VerifyInvocationArgsUnresolvedMethod(const Instruction* inst, MethodType method_type, 483 bool is_range) 484 REQUIRES_SHARED(Locks::mutator_lock_); 485 486 template <class T> 487 ArtMethod* VerifyInvocationArgsFromIterator(T* it, const Instruction* inst, 488 MethodType method_type, bool is_range, 489 ArtMethod* res_method) 490 REQUIRES_SHARED(Locks::mutator_lock_); 491 492 /* 493 * Verify the arguments present for a call site. Returns "true" if all is well, "false" otherwise. 494 */ 495 bool CheckCallSite(uint32_t call_site_idx); 496 497 /* 498 * Verify that the target instruction is not "move-exception". It's important that the only way 499 * to execute a move-exception is as the first instruction of an exception handler. 500 * Returns "true" if all is well, "false" if the target instruction is move-exception. 501 */ 502 bool CheckNotMoveException(const uint16_t* insns, int insn_idx) { 503 if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) { 504 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception"; 505 return false; 506 } 507 return true; 508 } 509 510 /* 511 * Verify that the target instruction is not "move-result". It is important that we cannot 512 * branch to move-result instructions, but we have to make this a distinct check instead of 513 * adding it to CheckNotMoveException, because it is legal to continue into "move-result" 514 * instructions - as long as the previous instruction was an invoke, which is checked elsewhere. 515 */ 516 bool CheckNotMoveResult(const uint16_t* insns, int insn_idx) { 517 if (((insns[insn_idx] & 0xff) >= Instruction::MOVE_RESULT) && 518 ((insns[insn_idx] & 0xff) <= Instruction::MOVE_RESULT_OBJECT)) { 519 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-result*"; 520 return false; 521 } 522 return true; 523 } 524 525 /* 526 * Verify that the target instruction is not "move-result" or "move-exception". This is to 527 * be used when checking branch and switch instructions, but not instructions that can 528 * continue. 529 */ 530 bool CheckNotMoveExceptionOrMoveResult(const uint16_t* insns, int insn_idx) { 531 return (CheckNotMoveException(insns, insn_idx) && CheckNotMoveResult(insns, insn_idx)); 532 } 533 534 /* 535 * Control can transfer to "next_insn". Merge the registers from merge_line into the table at 536 * next_insn, and set the changed flag on the target address if any of the registers were changed. 537 * In the case of fall-through, update the merge line on a change as its the working line for the 538 * next instruction. 539 * Returns "false" if an error is encountered. 540 */ 541 bool UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line, bool update_merge_line) 542 REQUIRES_SHARED(Locks::mutator_lock_); 543 544 // Return the register type for the method. 545 const RegType& GetMethodReturnType() REQUIRES_SHARED(Locks::mutator_lock_); 546 547 // Get a type representing the declaring class of the method. 548 const RegType& GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_); 549 550 InstructionFlags* CurrentInsnFlags() { 551 return &GetModifiableInstructionFlags(work_insn_idx_); 552 } 553 554 const RegType& DetermineCat1Constant(int32_t value, bool precise) 555 REQUIRES_SHARED(Locks::mutator_lock_); 556 557 // Try to create a register type from the given class. In case a precise type is requested, but 558 // the class is not instantiable, a soft error (of type NO_CLASS) will be enqueued and a 559 // non-precise reference will be returned. 560 // Note: we reuse NO_CLASS as this will throw an exception at runtime, when the failing class is 561 // actually touched. 562 const RegType& FromClass(const char* descriptor, ObjPtr<mirror::Class> klass, bool precise) 563 REQUIRES_SHARED(Locks::mutator_lock_); 564 565 ALWAYS_INLINE bool FailOrAbort(bool condition, const char* error_msg, uint32_t work_insn_idx); 566 567 ALWAYS_INLINE InstructionFlags& GetModifiableInstructionFlags(size_t index) { 568 return insn_flags_[index]; 569 } 570 571 // Returns the method index of an invoke instruction. 572 uint16_t GetMethodIdxOfInvoke(const Instruction* inst) 573 REQUIRES_SHARED(Locks::mutator_lock_); 574 // Returns the field index of a field access instruction. 575 uint16_t GetFieldIdxOfFieldAccess(const Instruction* inst, bool is_static) 576 REQUIRES_SHARED(Locks::mutator_lock_); 577 578 // Run verification on the method. Returns true if verification completes and false if the input 579 // has an irrecoverable corruption. 580 bool Verify() override REQUIRES_SHARED(Locks::mutator_lock_); 581 582 // Dump the failures encountered by the verifier. 583 std::ostream& DumpFailures(std::ostream& os); 584 585 // Dump the state of the verifier, namely each instruction, what flags are set on it, register 586 // information 587 void Dump(std::ostream& os) REQUIRES_SHARED(Locks::mutator_lock_) { 588 VariableIndentationOutputStream vios(&os); 589 Dump(&vios); 590 } 591 void Dump(VariableIndentationOutputStream* vios) REQUIRES_SHARED(Locks::mutator_lock_); 592 593 ArtMethod* method_being_verified_; // Its ArtMethod representation if known. 594 const uint32_t method_access_flags_; // Method's access flags. 595 const RegType* return_type_; // Lazily computed return type of the method. 596 // The dex_cache for the declaring class of the method. 597 Handle<mirror::DexCache> dex_cache_ GUARDED_BY(Locks::mutator_lock_); 598 // The class loader for the declaring class of the method. 599 Handle<mirror::ClassLoader> class_loader_ GUARDED_BY(Locks::mutator_lock_); 600 const dex::ClassDef& class_def_; // The class def of the declaring class of the method. 601 const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class. 602 603 // The dex PC of a FindLocksAtDexPc request, -1 otherwise. 604 uint32_t interesting_dex_pc_; 605 // The container into which FindLocksAtDexPc should write the registers containing held locks, 606 // null if we're not doing FindLocksAtDexPc. 607 std::vector<DexLockInfo>* monitor_enter_dex_pcs_; 608 609 610 // An optimization where instead of generating unique RegTypes for constants we use imprecise 611 // constants that cover a range of constants. This isn't good enough for deoptimization that 612 // avoids loading from registers in the case of a constant as the dex instruction set lost the 613 // notion of whether a value should be in a floating point or general purpose register file. 614 const bool need_precise_constants_; 615 616 // Indicates whether we verify to dump the info. In that case we accept quickened instructions 617 // even though we might detect to be a compiler. Should only be set when running 618 // VerifyMethodAndDump. 619 const bool verify_to_dump_; 620 621 // Whether or not we call AllowThreadSuspension periodically, we want a way to disable this for 622 // thread dumping checkpoints since we may get thread suspension at an inopportune time due to 623 // FindLocksAtDexPC, resulting in deadlocks. 624 const bool allow_thread_suspension_; 625 626 // Whether the method seems to be a constructor. Note that this field exists as we can't trust 627 // the flags in the dex file. Some older code does not mark methods named "<init>" and "<clinit>" 628 // correctly. 629 // 630 // Note: this flag is only valid once Verify() has started. 631 bool is_constructor_; 632 633 // API level, for dependent checks. Note: we do not use '0' for unset here, to simplify checks. 634 // Instead, unset level should correspond to max(). 635 const uint32_t api_level_; 636 637 friend class ::art::verifier::MethodVerifier; 638 639 DISALLOW_COPY_AND_ASSIGN(MethodVerifier); 640 }; 641 642 // Note: returns true on failure. 643 template <bool kVerifierDebug> 644 inline bool MethodVerifier<kVerifierDebug>::FailOrAbort(bool condition, 645 const char* error_msg, 646 uint32_t work_insn_idx) { 647 if (kIsDebugBuild) { 648 // In a debug build, abort if the error condition is wrong. Only warn if 649 // we are already aborting (as this verification is likely run to print 650 // lock information). 651 if (LIKELY(gAborting == 0)) { 652 DCHECK(condition) << error_msg << work_insn_idx << " " 653 << dex_file_->PrettyMethod(dex_method_idx_); 654 } else { 655 if (!condition) { 656 LOG(ERROR) << error_msg << work_insn_idx; 657 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx; 658 return true; 659 } 660 } 661 } else { 662 // In a non-debug build, just fail the class. 663 if (!condition) { 664 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx; 665 return true; 666 } 667 } 668 669 return false; 670 } 671 672 static bool IsLargeMethod(const CodeItemDataAccessor& accessor) { 673 if (!accessor.HasCodeItem()) { 674 return false; 675 } 676 677 uint16_t registers_size = accessor.RegistersSize(); 678 uint32_t insns_size = accessor.InsnsSizeInCodeUnits(); 679 680 return registers_size * insns_size > 4*1024*1024; 681 } 682 683 template <bool kVerifierDebug> 684 MethodVerifier<kVerifierDebug>::MethodVerifier(Thread* self, 685 const DexFile* dex_file, 686 Handle<mirror::DexCache> dex_cache, 687 Handle<mirror::ClassLoader> class_loader, 688 const dex::ClassDef& class_def, 689 const dex::CodeItem* code_item, 690 uint32_t dex_method_idx, 691 ArtMethod* method, 692 uint32_t method_access_flags, 693 bool can_load_classes, 694 bool allow_soft_failures, 695 bool need_precise_constants, 696 bool verify_to_dump, 697 bool allow_thread_suspension, 698 uint32_t api_level) 699 : art::verifier::MethodVerifier(self, 700 dex_file, 701 code_item, 702 dex_method_idx, 703 can_load_classes, 704 allow_thread_suspension, 705 allow_soft_failures), 706 method_being_verified_(method), 707 method_access_flags_(method_access_flags), 708 return_type_(nullptr), 709 dex_cache_(dex_cache), 710 class_loader_(class_loader), 711 class_def_(class_def), 712 declaring_class_(nullptr), 713 interesting_dex_pc_(-1), 714 monitor_enter_dex_pcs_(nullptr), 715 need_precise_constants_(need_precise_constants), 716 verify_to_dump_(verify_to_dump), 717 allow_thread_suspension_(allow_thread_suspension), 718 is_constructor_(false), 719 api_level_(api_level == 0 ? std::numeric_limits<uint32_t>::max() : api_level) { 720 } 721 722 template <bool kVerifierDebug> 723 void MethodVerifier<kVerifierDebug>::FindLocksAtDexPc() { 724 CHECK(monitor_enter_dex_pcs_ != nullptr); 725 CHECK(code_item_accessor_.HasCodeItem()); // This only makes sense for methods with code. 726 727 // Quick check whether there are any monitor_enter instructions before verifying. 728 for (const DexInstructionPcPair& inst : code_item_accessor_) { 729 if (inst->Opcode() == Instruction::MONITOR_ENTER) { 730 // Strictly speaking, we ought to be able to get away with doing a subset of the full method 731 // verification. In practice, the phase we want relies on data structures set up by all the 732 // earlier passes, so we just run the full method verification and bail out early when we've 733 // got what we wanted. 734 Verify(); 735 return; 736 } 737 } 738 } 739 740 template <bool kVerifierDebug> 741 bool MethodVerifier<kVerifierDebug>::Verify() { 742 // Some older code doesn't correctly mark constructors as such. Test for this case by looking at 743 // the name. 744 const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 745 const char* method_name = dex_file_->StringDataByIdx(method_id.name_idx_); 746 bool instance_constructor_by_name = strcmp("<init>", method_name) == 0; 747 bool static_constructor_by_name = strcmp("<clinit>", method_name) == 0; 748 bool constructor_by_name = instance_constructor_by_name || static_constructor_by_name; 749 // Check that only constructors are tagged, and check for bad code that doesn't tag constructors. 750 if ((method_access_flags_ & kAccConstructor) != 0) { 751 if (!constructor_by_name) { 752 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 753 << "method is marked as constructor, but not named accordingly"; 754 return false; 755 } 756 is_constructor_ = true; 757 } else if (constructor_by_name) { 758 LOG(WARNING) << "Method " << dex_file_->PrettyMethod(dex_method_idx_) 759 << " not marked as constructor."; 760 is_constructor_ = true; 761 } 762 // If it's a constructor, check whether IsStatic() matches the name. 763 // This should have been rejected by the dex file verifier. Only do in debug build. 764 if (kIsDebugBuild) { 765 if (IsConstructor()) { 766 if (IsStatic() ^ static_constructor_by_name) { 767 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 768 << "constructor name doesn't match static flag"; 769 return false; 770 } 771 } 772 } 773 774 // Methods may only have one of public/protected/private. 775 // This should have been rejected by the dex file verifier. Only do in debug build. 776 if (kIsDebugBuild) { 777 size_t access_mod_count = 778 (((method_access_flags_ & kAccPublic) == 0) ? 0 : 1) + 779 (((method_access_flags_ & kAccProtected) == 0) ? 0 : 1) + 780 (((method_access_flags_ & kAccPrivate) == 0) ? 0 : 1); 781 if (access_mod_count > 1) { 782 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "method has more than one of public/protected/private"; 783 return false; 784 } 785 } 786 787 // If there aren't any instructions, make sure that's expected, then exit successfully. 788 if (!code_item_accessor_.HasCodeItem()) { 789 // Only native or abstract methods may not have code. 790 if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) { 791 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method"; 792 return false; 793 } 794 795 // This should have been rejected by the dex file verifier. Only do in debug build. 796 // Note: the above will also be rejected in the dex file verifier, starting in dex version 37. 797 if (kIsDebugBuild) { 798 if ((method_access_flags_ & kAccAbstract) != 0) { 799 // Abstract methods are not allowed to have the following flags. 800 static constexpr uint32_t kForbidden = 801 kAccPrivate | 802 kAccStatic | 803 kAccFinal | 804 kAccNative | 805 kAccStrict | 806 kAccSynchronized; 807 if ((method_access_flags_ & kForbidden) != 0) { 808 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 809 << "method can't be abstract and private/static/final/native/strict/synchronized"; 810 return false; 811 } 812 } 813 if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) { 814 // Interface methods must be public and abstract (if default methods are disabled). 815 uint32_t kRequired = kAccPublic; 816 if ((method_access_flags_ & kRequired) != kRequired) { 817 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods must be public"; 818 return false; 819 } 820 // In addition to the above, interface methods must not be protected. 821 static constexpr uint32_t kForbidden = kAccProtected; 822 if ((method_access_flags_ & kForbidden) != 0) { 823 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods can't be protected"; 824 return false; 825 } 826 } 827 // We also don't allow constructors to be abstract or native. 828 if (IsConstructor()) { 829 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be abstract or native"; 830 return false; 831 } 832 } 833 return true; 834 } 835 836 // This should have been rejected by the dex file verifier. Only do in debug build. 837 if (kIsDebugBuild) { 838 // When there's code, the method must not be native or abstract. 839 if ((method_access_flags_ & (kAccNative | kAccAbstract)) != 0) { 840 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "non-zero-length code in abstract or native method"; 841 return false; 842 } 843 844 if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) { 845 // Interfaces may always have static initializers for their fields. If we are running with 846 // default methods enabled we also allow other public, static, non-final methods to have code. 847 // Otherwise that is the only type of method allowed. 848 if (!(IsConstructor() && IsStatic())) { 849 if (IsInstanceConstructor()) { 850 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-static constructor"; 851 return false; 852 } else if (method_access_flags_ & kAccFinal) { 853 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods"; 854 return false; 855 } else { 856 uint32_t access_flag_options = kAccPublic; 857 if (dex_file_->SupportsDefaultMethods()) { 858 access_flag_options |= kAccPrivate; 859 } 860 if (!(method_access_flags_ & access_flag_options)) { 861 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 862 << "interfaces may not have protected or package-private members"; 863 return false; 864 } 865 } 866 } 867 } 868 869 // Instance constructors must not be synchronized. 870 if (IsInstanceConstructor()) { 871 static constexpr uint32_t kForbidden = kAccSynchronized; 872 if ((method_access_flags_ & kForbidden) != 0) { 873 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be synchronized"; 874 return false; 875 } 876 } 877 } 878 879 // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers. 880 if (code_item_accessor_.InsSize() > code_item_accessor_.RegistersSize()) { 881 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins=" 882 << code_item_accessor_.InsSize() 883 << " regs=" << code_item_accessor_.RegistersSize(); 884 return false; 885 } 886 887 // Allocate and initialize an array to hold instruction data. 888 insn_flags_.reset(allocator_.AllocArray<InstructionFlags>( 889 code_item_accessor_.InsnsSizeInCodeUnits())); 890 DCHECK(insn_flags_ != nullptr); 891 std::uninitialized_fill_n(insn_flags_.get(), 892 code_item_accessor_.InsnsSizeInCodeUnits(), 893 InstructionFlags()); 894 // Run through the instructions and see if the width checks out. 895 bool result = ComputeWidthsAndCountOps(); 896 bool allow_runtime_only_instructions = !Runtime::Current()->IsAotCompiler() || verify_to_dump_; 897 // Flag instructions guarded by a "try" block and check exception handlers. 898 result = result && ScanTryCatchBlocks(); 899 // Perform static instruction verification. 900 result = result && (allow_runtime_only_instructions 901 ? VerifyInstructions<true>() 902 : VerifyInstructions<false>()); 903 // Perform code-flow analysis and return. 904 result = result && VerifyCodeFlow(); 905 906 return result; 907 } 908 909 template <bool kVerifierDebug> 910 void MethodVerifier<kVerifierDebug>::PrependToLastFailMessage(std::string prepend) { 911 size_t failure_num = failure_messages_.size(); 912 DCHECK_NE(failure_num, 0U); 913 std::ostringstream* last_fail_message = failure_messages_[failure_num - 1]; 914 prepend += last_fail_message->str(); 915 failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate); 916 delete last_fail_message; 917 } 918 919 template <bool kVerifierDebug> 920 void MethodVerifier<kVerifierDebug>::AppendToLastFailMessage(const std::string& append) { 921 size_t failure_num = failure_messages_.size(); 922 DCHECK_NE(failure_num, 0U); 923 std::ostringstream* last_fail_message = failure_messages_[failure_num - 1]; 924 (*last_fail_message) << append; 925 } 926 927 template <bool kVerifierDebug> 928 bool MethodVerifier<kVerifierDebug>::ComputeWidthsAndCountOps() { 929 // We can't assume the instruction is well formed, handle the case where calculating the size 930 // goes past the end of the code item. 931 SafeDexInstructionIterator it(code_item_accessor_.begin(), code_item_accessor_.end()); 932 for ( ; !it.IsErrorState() && it < code_item_accessor_.end(); ++it) { 933 // In case the instruction goes past the end of the code item, make sure to not process it. 934 SafeDexInstructionIterator next = it; 935 ++next; 936 if (next.IsErrorState()) { 937 break; 938 } 939 Instruction::Code opcode = it->Opcode(); 940 switch (opcode) { 941 case Instruction::APUT_OBJECT: 942 case Instruction::CHECK_CAST: 943 has_check_casts_ = true; 944 break; 945 default: 946 break; 947 } 948 GetModifiableInstructionFlags(it.DexPc()).SetIsOpcode(); 949 } 950 951 if (it != code_item_accessor_.end()) { 952 const size_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits(); 953 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected (" 954 << it.DexPc() << " vs. " << insns_size << ")"; 955 return false; 956 } 957 958 return true; 959 } 960 961 template <bool kVerifierDebug> 962 bool MethodVerifier<kVerifierDebug>::ScanTryCatchBlocks() { 963 const uint32_t tries_size = code_item_accessor_.TriesSize(); 964 if (tries_size == 0) { 965 return true; 966 } 967 const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits(); 968 for (const dex::TryItem& try_item : code_item_accessor_.TryItems()) { 969 const uint32_t start = try_item.start_addr_; 970 const uint32_t end = start + try_item.insn_count_; 971 if ((start >= end) || (start >= insns_size) || (end > insns_size)) { 972 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start 973 << " endAddr=" << end << " (size=" << insns_size << ")"; 974 return false; 975 } 976 if (!GetInstructionFlags(start).IsOpcode()) { 977 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 978 << "'try' block starts inside an instruction (" << start << ")"; 979 return false; 980 } 981 DexInstructionIterator end_it(code_item_accessor_.Insns(), end); 982 for (DexInstructionIterator it(code_item_accessor_.Insns(), start); it < end_it; ++it) { 983 GetModifiableInstructionFlags(it.DexPc()).SetInTry(); 984 } 985 } 986 // Iterate over each of the handlers to verify target addresses. 987 const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData(); 988 const uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 989 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 990 for (uint32_t idx = 0; idx < handlers_size; idx++) { 991 CatchHandlerIterator iterator(handlers_ptr); 992 for (; iterator.HasNext(); iterator.Next()) { 993 uint32_t dex_pc = iterator.GetHandlerAddress(); 994 if (!GetInstructionFlags(dex_pc).IsOpcode()) { 995 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 996 << "exception handler starts at bad address (" << dex_pc << ")"; 997 return false; 998 } 999 if (!CheckNotMoveResult(code_item_accessor_.Insns(), dex_pc)) { 1000 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1001 << "exception handler begins with move-result* (" << dex_pc << ")"; 1002 return false; 1003 } 1004 GetModifiableInstructionFlags(dex_pc).SetBranchTarget(); 1005 // Ensure exception types are resolved so that they don't need resolution to be delivered, 1006 // unresolved exception types will be ignored by exception delivery 1007 if (iterator.GetHandlerTypeIndex().IsValid()) { 1008 ObjPtr<mirror::Class> exception_type = 1009 linker->ResolveType(iterator.GetHandlerTypeIndex(), dex_cache_, class_loader_); 1010 if (exception_type == nullptr) { 1011 DCHECK(self_->IsExceptionPending()); 1012 self_->ClearException(); 1013 } 1014 } 1015 } 1016 handlers_ptr = iterator.EndDataPointer(); 1017 } 1018 return true; 1019 } 1020 1021 template <bool kVerifierDebug> 1022 template <bool kAllowRuntimeOnlyInstructions> 1023 bool MethodVerifier<kVerifierDebug>::VerifyInstructions() { 1024 /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */ 1025 GetModifiableInstructionFlags(0).SetBranchTarget(); 1026 GetModifiableInstructionFlags(0).SetCompileTimeInfoPoint(); 1027 for (const DexInstructionPcPair& inst : code_item_accessor_) { 1028 const uint32_t dex_pc = inst.DexPc(); 1029 if (!VerifyInstruction<kAllowRuntimeOnlyInstructions>(&inst.Inst(), dex_pc)) { 1030 DCHECK_NE(failures_.size(), 0U); 1031 return false; 1032 } 1033 /* Flag instructions that are garbage collection points */ 1034 // All invoke points are marked as "Throw" points already. 1035 // We are relying on this to also count all the invokes as interesting. 1036 if (inst->IsBranch()) { 1037 GetModifiableInstructionFlags(dex_pc).SetCompileTimeInfoPoint(); 1038 // The compiler also needs safepoints for fall-through to loop heads. 1039 // Such a loop head must be a target of a branch. 1040 int32_t offset = 0; 1041 bool cond, self_ok; 1042 bool target_ok = GetBranchOffset(dex_pc, &offset, &cond, &self_ok); 1043 DCHECK(target_ok); 1044 GetModifiableInstructionFlags(dex_pc + offset).SetCompileTimeInfoPoint(); 1045 } else if (inst->IsSwitch() || inst->IsThrow()) { 1046 GetModifiableInstructionFlags(dex_pc).SetCompileTimeInfoPoint(); 1047 } else if (inst->IsReturn()) { 1048 GetModifiableInstructionFlags(dex_pc).SetCompileTimeInfoPointAndReturn(); 1049 } 1050 } 1051 return true; 1052 } 1053 1054 template <bool kVerifierDebug> 1055 template <bool kAllowRuntimeOnlyInstructions> 1056 bool MethodVerifier<kVerifierDebug>::VerifyInstruction(const Instruction* inst, 1057 uint32_t code_offset) { 1058 if (Instruction::kHaveExperimentalInstructions && UNLIKELY(inst->IsExperimental())) { 1059 // Experimental instructions don't yet have verifier support implementation. 1060 // While it is possible to use them by themselves, when we try to use stable instructions 1061 // with a virtual register that was created by an experimental instruction, 1062 // the data flow analysis will fail. 1063 Fail(VERIFY_ERROR_FORCE_INTERPRETER) 1064 << "experimental instruction is not supported by verifier; skipping verification"; 1065 have_pending_experimental_failure_ = true; 1066 return false; 1067 } 1068 1069 bool result = true; 1070 switch (inst->GetVerifyTypeArgumentA()) { 1071 case Instruction::kVerifyRegA: 1072 result = result && CheckRegisterIndex(inst->VRegA()); 1073 break; 1074 case Instruction::kVerifyRegAWide: 1075 result = result && CheckWideRegisterIndex(inst->VRegA()); 1076 break; 1077 } 1078 switch (inst->GetVerifyTypeArgumentB()) { 1079 case Instruction::kVerifyRegB: 1080 result = result && CheckRegisterIndex(inst->VRegB()); 1081 break; 1082 case Instruction::kVerifyRegBField: 1083 result = result && CheckFieldIndex(inst->VRegB()); 1084 break; 1085 case Instruction::kVerifyRegBMethod: 1086 result = result && CheckMethodIndex(inst->VRegB()); 1087 break; 1088 case Instruction::kVerifyRegBNewInstance: 1089 result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB())); 1090 break; 1091 case Instruction::kVerifyRegBString: 1092 result = result && CheckStringIndex(inst->VRegB()); 1093 break; 1094 case Instruction::kVerifyRegBType: 1095 result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB())); 1096 break; 1097 case Instruction::kVerifyRegBWide: 1098 result = result && CheckWideRegisterIndex(inst->VRegB()); 1099 break; 1100 case Instruction::kVerifyRegBCallSite: 1101 result = result && CheckCallSiteIndex(inst->VRegB()); 1102 break; 1103 case Instruction::kVerifyRegBMethodHandle: 1104 result = result && CheckMethodHandleIndex(inst->VRegB()); 1105 break; 1106 case Instruction::kVerifyRegBPrototype: 1107 result = result && CheckPrototypeIndex(inst->VRegB()); 1108 break; 1109 } 1110 switch (inst->GetVerifyTypeArgumentC()) { 1111 case Instruction::kVerifyRegC: 1112 result = result && CheckRegisterIndex(inst->VRegC()); 1113 break; 1114 case Instruction::kVerifyRegCField: 1115 result = result && CheckFieldIndex(inst->VRegC()); 1116 break; 1117 case Instruction::kVerifyRegCNewArray: 1118 result = result && CheckNewArray(dex::TypeIndex(inst->VRegC())); 1119 break; 1120 case Instruction::kVerifyRegCType: 1121 result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC())); 1122 break; 1123 case Instruction::kVerifyRegCWide: 1124 result = result && CheckWideRegisterIndex(inst->VRegC()); 1125 break; 1126 } 1127 switch (inst->GetVerifyTypeArgumentH()) { 1128 case Instruction::kVerifyRegHPrototype: 1129 result = result && CheckPrototypeIndex(inst->VRegH()); 1130 break; 1131 } 1132 switch (inst->GetVerifyExtraFlags()) { 1133 case Instruction::kVerifyArrayData: 1134 result = result && CheckArrayData(code_offset); 1135 break; 1136 case Instruction::kVerifyBranchTarget: 1137 result = result && CheckBranchTarget(code_offset); 1138 break; 1139 case Instruction::kVerifySwitchTargets: 1140 result = result && CheckSwitchTargets(code_offset); 1141 break; 1142 case Instruction::kVerifyVarArgNonZero: 1143 // Fall-through. 1144 case Instruction::kVerifyVarArg: { 1145 // Instructions that can actually return a negative value shouldn't have this flag. 1146 uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA()); 1147 if ((inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && v_a == 0) || 1148 v_a > Instruction::kMaxVarArgRegs) { 1149 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << v_a << ") in " 1150 "non-range invoke"; 1151 return false; 1152 } 1153 1154 uint32_t args[Instruction::kMaxVarArgRegs]; 1155 inst->GetVarArgs(args); 1156 result = result && CheckVarArgRegs(v_a, args); 1157 break; 1158 } 1159 case Instruction::kVerifyVarArgRangeNonZero: 1160 // Fall-through. 1161 case Instruction::kVerifyVarArgRange: 1162 if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero && 1163 inst->VRegA() <= 0) { 1164 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in " 1165 "range invoke"; 1166 return false; 1167 } 1168 result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC()); 1169 break; 1170 case Instruction::kVerifyError: 1171 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name(); 1172 result = false; 1173 break; 1174 } 1175 if (!kAllowRuntimeOnlyInstructions && inst->GetVerifyIsRuntimeOnly()) { 1176 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name(); 1177 result = false; 1178 } 1179 return result; 1180 } 1181 1182 template <bool kVerifierDebug> 1183 inline bool MethodVerifier<kVerifierDebug>::CheckRegisterIndex(uint32_t idx) { 1184 if (UNLIKELY(idx >= code_item_accessor_.RegistersSize())) { 1185 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= " 1186 << code_item_accessor_.RegistersSize() << ")"; 1187 return false; 1188 } 1189 return true; 1190 } 1191 1192 template <bool kVerifierDebug> 1193 inline bool MethodVerifier<kVerifierDebug>::CheckWideRegisterIndex(uint32_t idx) { 1194 if (UNLIKELY(idx + 1 >= code_item_accessor_.RegistersSize())) { 1195 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx 1196 << "+1 >= " << code_item_accessor_.RegistersSize() << ")"; 1197 return false; 1198 } 1199 return true; 1200 } 1201 1202 template <bool kVerifierDebug> 1203 inline bool MethodVerifier<kVerifierDebug>::CheckCallSiteIndex(uint32_t idx) { 1204 uint32_t limit = dex_file_->NumCallSiteIds(); 1205 if (UNLIKELY(idx >= limit)) { 1206 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad call site index " << idx << " (max " 1207 << limit << ")"; 1208 return false; 1209 } 1210 return true; 1211 } 1212 1213 template <bool kVerifierDebug> 1214 inline bool MethodVerifier<kVerifierDebug>::CheckFieldIndex(uint32_t idx) { 1215 if (UNLIKELY(idx >= dex_file_->GetHeader().field_ids_size_)) { 1216 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max " 1217 << dex_file_->GetHeader().field_ids_size_ << ")"; 1218 return false; 1219 } 1220 return true; 1221 } 1222 1223 template <bool kVerifierDebug> 1224 inline bool MethodVerifier<kVerifierDebug>::CheckMethodIndex(uint32_t idx) { 1225 if (UNLIKELY(idx >= dex_file_->GetHeader().method_ids_size_)) { 1226 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max " 1227 << dex_file_->GetHeader().method_ids_size_ << ")"; 1228 return false; 1229 } 1230 return true; 1231 } 1232 1233 template <bool kVerifierDebug> 1234 inline bool MethodVerifier<kVerifierDebug>::CheckMethodHandleIndex(uint32_t idx) { 1235 uint32_t limit = dex_file_->NumMethodHandles(); 1236 if (UNLIKELY(idx >= limit)) { 1237 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method handle index " << idx << " (max " 1238 << limit << ")"; 1239 return false; 1240 } 1241 return true; 1242 } 1243 1244 template <bool kVerifierDebug> 1245 inline bool MethodVerifier<kVerifierDebug>::CheckNewInstance(dex::TypeIndex idx) { 1246 if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) { 1247 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1248 << dex_file_->GetHeader().type_ids_size_ << ")"; 1249 return false; 1250 } 1251 // We don't need the actual class, just a pointer to the class name. 1252 const char* descriptor = dex_file_->StringByTypeIdx(idx); 1253 if (UNLIKELY(descriptor[0] != 'L')) { 1254 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'"; 1255 return false; 1256 } else if (UNLIKELY(strcmp(descriptor, "Ljava/lang/Class;") == 0)) { 1257 // An unlikely new instance on Class is not allowed. Fall back to interpreter to ensure an 1258 // exception is thrown when this statement is executed (compiled code would not do that). 1259 Fail(VERIFY_ERROR_INSTANTIATION); 1260 } 1261 return true; 1262 } 1263 1264 template <bool kVerifierDebug> 1265 inline bool MethodVerifier<kVerifierDebug>::CheckPrototypeIndex(uint32_t idx) { 1266 if (UNLIKELY(idx >= dex_file_->GetHeader().proto_ids_size_)) { 1267 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad prototype index " << idx << " (max " 1268 << dex_file_->GetHeader().proto_ids_size_ << ")"; 1269 return false; 1270 } 1271 return true; 1272 } 1273 1274 template <bool kVerifierDebug> 1275 inline bool MethodVerifier<kVerifierDebug>::CheckStringIndex(uint32_t idx) { 1276 if (UNLIKELY(idx >= dex_file_->GetHeader().string_ids_size_)) { 1277 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max " 1278 << dex_file_->GetHeader().string_ids_size_ << ")"; 1279 return false; 1280 } 1281 return true; 1282 } 1283 1284 template <bool kVerifierDebug> 1285 inline bool MethodVerifier<kVerifierDebug>::CheckTypeIndex(dex::TypeIndex idx) { 1286 if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) { 1287 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1288 << dex_file_->GetHeader().type_ids_size_ << ")"; 1289 return false; 1290 } 1291 return true; 1292 } 1293 1294 template <bool kVerifierDebug> 1295 bool MethodVerifier<kVerifierDebug>::CheckNewArray(dex::TypeIndex idx) { 1296 if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) { 1297 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1298 << dex_file_->GetHeader().type_ids_size_ << ")"; 1299 return false; 1300 } 1301 int bracket_count = 0; 1302 const char* descriptor = dex_file_->StringByTypeIdx(idx); 1303 const char* cp = descriptor; 1304 while (*cp++ == '[') { 1305 bracket_count++; 1306 } 1307 if (UNLIKELY(bracket_count == 0)) { 1308 /* The given class must be an array type. */ 1309 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1310 << "can't new-array class '" << descriptor << "' (not an array)"; 1311 return false; 1312 } else if (UNLIKELY(bracket_count > 255)) { 1313 /* It is illegal to create an array of more than 255 dimensions. */ 1314 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1315 << "can't new-array class '" << descriptor << "' (exceeds limit)"; 1316 return false; 1317 } 1318 return true; 1319 } 1320 1321 template <bool kVerifierDebug> 1322 bool MethodVerifier<kVerifierDebug>::CheckArrayData(uint32_t cur_offset) { 1323 const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits(); 1324 const uint16_t* insns = code_item_accessor_.Insns() + cur_offset; 1325 const uint16_t* array_data; 1326 int32_t array_data_offset; 1327 1328 DCHECK_LT(cur_offset, insn_count); 1329 /* make sure the start of the array data table is in range */ 1330 array_data_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 1331 if (UNLIKELY(static_cast<int32_t>(cur_offset) + array_data_offset < 0 || 1332 cur_offset + array_data_offset + 2 >= insn_count)) { 1333 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset 1334 << ", data offset " << array_data_offset 1335 << ", count " << insn_count; 1336 return false; 1337 } 1338 /* offset to array data table is a relative branch-style offset */ 1339 array_data = insns + array_data_offset; 1340 // Make sure the table is at an even dex pc, that is, 32-bit aligned. 1341 if (UNLIKELY(!IsAligned<4>(array_data))) { 1342 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset 1343 << ", data offset " << array_data_offset; 1344 return false; 1345 } 1346 // Make sure the array-data is marked as an opcode. This ensures that it was reached when 1347 // traversing the code item linearly. It is an approximation for a by-spec padding value. 1348 if (UNLIKELY(!GetInstructionFlags(cur_offset + array_data_offset).IsOpcode())) { 1349 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array data table at " << cur_offset 1350 << ", data offset " << array_data_offset 1351 << " not correctly visited, probably bad padding."; 1352 return false; 1353 } 1354 1355 uint32_t value_width = array_data[1]; 1356 uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]); 1357 uint32_t table_size = 4 + (value_width * value_count + 1) / 2; 1358 /* make sure the end of the switch is in range */ 1359 if (UNLIKELY(cur_offset + array_data_offset + table_size > insn_count)) { 1360 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset 1361 << ", data offset " << array_data_offset << ", end " 1362 << cur_offset + array_data_offset + table_size 1363 << ", count " << insn_count; 1364 return false; 1365 } 1366 return true; 1367 } 1368 1369 template <bool kVerifierDebug> 1370 bool MethodVerifier<kVerifierDebug>::CheckBranchTarget(uint32_t cur_offset) { 1371 int32_t offset; 1372 bool isConditional, selfOkay; 1373 if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) { 1374 return false; 1375 } 1376 if (UNLIKELY(!selfOkay && offset == 0)) { 1377 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at" 1378 << reinterpret_cast<void*>(cur_offset); 1379 return false; 1380 } 1381 // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime 1382 // to have identical "wrap-around" behavior, but it's unwise to depend on that. 1383 if (UNLIKELY(((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset))) { 1384 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow " 1385 << reinterpret_cast<void*>(cur_offset) << " +" << offset; 1386 return false; 1387 } 1388 int32_t abs_offset = cur_offset + offset; 1389 if (UNLIKELY(abs_offset < 0 || 1390 (uint32_t) abs_offset >= code_item_accessor_.InsnsSizeInCodeUnits() || 1391 !GetInstructionFlags(abs_offset).IsOpcode())) { 1392 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> " 1393 << reinterpret_cast<void*>(abs_offset) << ") at " 1394 << reinterpret_cast<void*>(cur_offset); 1395 return false; 1396 } 1397 GetModifiableInstructionFlags(abs_offset).SetBranchTarget(); 1398 return true; 1399 } 1400 1401 template <bool kVerifierDebug> 1402 bool MethodVerifier<kVerifierDebug>::GetBranchOffset(uint32_t cur_offset, 1403 int32_t* pOffset, 1404 bool* pConditional, 1405 bool* selfOkay) { 1406 const uint16_t* insns = code_item_accessor_.Insns() + cur_offset; 1407 *pConditional = false; 1408 *selfOkay = false; 1409 switch (*insns & 0xff) { 1410 case Instruction::GOTO: 1411 *pOffset = ((int16_t) *insns) >> 8; 1412 break; 1413 case Instruction::GOTO_32: 1414 *pOffset = insns[1] | (((uint32_t) insns[2]) << 16); 1415 *selfOkay = true; 1416 break; 1417 case Instruction::GOTO_16: 1418 *pOffset = (int16_t) insns[1]; 1419 break; 1420 case Instruction::IF_EQ: 1421 case Instruction::IF_NE: 1422 case Instruction::IF_LT: 1423 case Instruction::IF_GE: 1424 case Instruction::IF_GT: 1425 case Instruction::IF_LE: 1426 case Instruction::IF_EQZ: 1427 case Instruction::IF_NEZ: 1428 case Instruction::IF_LTZ: 1429 case Instruction::IF_GEZ: 1430 case Instruction::IF_GTZ: 1431 case Instruction::IF_LEZ: 1432 *pOffset = (int16_t) insns[1]; 1433 *pConditional = true; 1434 break; 1435 default: 1436 return false; 1437 } 1438 return true; 1439 } 1440 1441 template <bool kVerifierDebug> 1442 bool MethodVerifier<kVerifierDebug>::CheckSwitchTargets(uint32_t cur_offset) { 1443 const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits(); 1444 DCHECK_LT(cur_offset, insn_count); 1445 const uint16_t* insns = code_item_accessor_.Insns() + cur_offset; 1446 /* make sure the start of the switch is in range */ 1447 int32_t switch_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 1448 if (UNLIKELY(static_cast<int32_t>(cur_offset) + switch_offset < 0 || 1449 cur_offset + switch_offset + 2 > insn_count)) { 1450 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset 1451 << ", switch offset " << switch_offset 1452 << ", count " << insn_count; 1453 return false; 1454 } 1455 /* offset to switch table is a relative branch-style offset */ 1456 const uint16_t* switch_insns = insns + switch_offset; 1457 // Make sure the table is at an even dex pc, that is, 32-bit aligned. 1458 if (UNLIKELY(!IsAligned<4>(switch_insns))) { 1459 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset 1460 << ", switch offset " << switch_offset; 1461 return false; 1462 } 1463 // Make sure the switch data is marked as an opcode. This ensures that it was reached when 1464 // traversing the code item linearly. It is an approximation for a by-spec padding value. 1465 if (UNLIKELY(!GetInstructionFlags(cur_offset + switch_offset).IsOpcode())) { 1466 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "switch table at " << cur_offset 1467 << ", switch offset " << switch_offset 1468 << " not correctly visited, probably bad padding."; 1469 return false; 1470 } 1471 1472 bool is_packed_switch = (*insns & 0xff) == Instruction::PACKED_SWITCH; 1473 1474 uint32_t switch_count = switch_insns[1]; 1475 int32_t targets_offset; 1476 uint16_t expected_signature; 1477 if (is_packed_switch) { 1478 /* 0=sig, 1=count, 2/3=firstKey */ 1479 targets_offset = 4; 1480 expected_signature = Instruction::kPackedSwitchSignature; 1481 } else { 1482 /* 0=sig, 1=count, 2..count*2 = keys */ 1483 targets_offset = 2 + 2 * switch_count; 1484 expected_signature = Instruction::kSparseSwitchSignature; 1485 } 1486 uint32_t table_size = targets_offset + switch_count * 2; 1487 if (UNLIKELY(switch_insns[0] != expected_signature)) { 1488 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1489 << StringPrintf("wrong signature for switch table (%x, wanted %x)", 1490 switch_insns[0], expected_signature); 1491 return false; 1492 } 1493 /* make sure the end of the switch is in range */ 1494 if (UNLIKELY(cur_offset + switch_offset + table_size > (uint32_t) insn_count)) { 1495 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset 1496 << ", switch offset " << switch_offset 1497 << ", end " << (cur_offset + switch_offset + table_size) 1498 << ", count " << insn_count; 1499 return false; 1500 } 1501 1502 constexpr int32_t keys_offset = 2; 1503 if (switch_count > 1) { 1504 if (is_packed_switch) { 1505 /* for a packed switch, verify that keys do not overflow int32 */ 1506 int32_t first_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16); 1507 int32_t max_first_key = 1508 std::numeric_limits<int32_t>::max() - (static_cast<int32_t>(switch_count) - 1); 1509 if (UNLIKELY(first_key > max_first_key)) { 1510 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: first_key=" << first_key 1511 << ", switch_count=" << switch_count; 1512 return false; 1513 } 1514 } else { 1515 /* for a sparse switch, verify the keys are in ascending order */ 1516 int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16); 1517 for (uint32_t targ = 1; targ < switch_count; targ++) { 1518 int32_t key = 1519 static_cast<int32_t>(switch_insns[keys_offset + targ * 2]) | 1520 static_cast<int32_t>(switch_insns[keys_offset + targ * 2 + 1] << 16); 1521 if (UNLIKELY(key <= last_key)) { 1522 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid sparse switch: last key=" << last_key 1523 << ", this=" << key; 1524 return false; 1525 } 1526 last_key = key; 1527 } 1528 } 1529 } 1530 /* verify each switch target */ 1531 for (uint32_t targ = 0; targ < switch_count; targ++) { 1532 int32_t offset = static_cast<int32_t>(switch_insns[targets_offset + targ * 2]) | 1533 static_cast<int32_t>(switch_insns[targets_offset + targ * 2 + 1] << 16); 1534 int32_t abs_offset = cur_offset + offset; 1535 if (UNLIKELY(abs_offset < 0 || 1536 abs_offset >= static_cast<int32_t>(insn_count) || 1537 !GetInstructionFlags(abs_offset).IsOpcode())) { 1538 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset 1539 << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at " 1540 << reinterpret_cast<void*>(cur_offset) 1541 << "[" << targ << "]"; 1542 return false; 1543 } 1544 GetModifiableInstructionFlags(abs_offset).SetBranchTarget(); 1545 } 1546 return true; 1547 } 1548 1549 template <bool kVerifierDebug> 1550 bool MethodVerifier<kVerifierDebug>::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) { 1551 uint16_t registers_size = code_item_accessor_.RegistersSize(); 1552 for (uint32_t idx = 0; idx < vA; idx++) { 1553 if (UNLIKELY(arg[idx] >= registers_size)) { 1554 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx] 1555 << ") in non-range invoke (>= " << registers_size << ")"; 1556 return false; 1557 } 1558 } 1559 1560 return true; 1561 } 1562 1563 template <bool kVerifierDebug> 1564 bool MethodVerifier<kVerifierDebug>::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) { 1565 uint16_t registers_size = code_item_accessor_.RegistersSize(); 1566 // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of 1567 // integer overflow when adding them here. 1568 if (UNLIKELY(vA + vC > registers_size)) { 1569 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC 1570 << " in range invoke (> " << registers_size << ")"; 1571 return false; 1572 } 1573 return true; 1574 } 1575 1576 template <bool kVerifierDebug> 1577 bool MethodVerifier<kVerifierDebug>::VerifyCodeFlow() { 1578 const uint16_t registers_size = code_item_accessor_.RegistersSize(); 1579 1580 /* Create and initialize table holding register status */ 1581 reg_table_.Init(kTrackCompilerInterestPoints, 1582 insn_flags_.get(), 1583 code_item_accessor_.InsnsSizeInCodeUnits(), 1584 registers_size, 1585 allocator_, 1586 GetRegTypeCache()); 1587 1588 work_line_.reset(RegisterLine::Create(registers_size, allocator_, GetRegTypeCache())); 1589 saved_line_.reset(RegisterLine::Create(registers_size, allocator_, GetRegTypeCache())); 1590 1591 /* Initialize register types of method arguments. */ 1592 if (!SetTypesFromSignature()) { 1593 DCHECK_NE(failures_.size(), 0U); 1594 std::string prepend("Bad signature in "); 1595 prepend += dex_file_->PrettyMethod(dex_method_idx_); 1596 PrependToLastFailMessage(prepend); 1597 return false; 1598 } 1599 // We may have a runtime failure here, clear. 1600 have_pending_runtime_throw_failure_ = false; 1601 1602 /* Perform code flow verification. */ 1603 if (!CodeFlowVerifyMethod()) { 1604 DCHECK_NE(failures_.size(), 0U); 1605 return false; 1606 } 1607 return true; 1608 } 1609 1610 template <bool kVerifierDebug> 1611 std::ostream& MethodVerifier<kVerifierDebug>::DumpFailures(std::ostream& os) { 1612 DCHECK_EQ(failures_.size(), failure_messages_.size()); 1613 for (size_t i = 0; i < failures_.size(); ++i) { 1614 os << failure_messages_[i]->str() << "\n"; 1615 } 1616 return os; 1617 } 1618 1619 template <bool kVerifierDebug> 1620 void MethodVerifier<kVerifierDebug>::Dump(VariableIndentationOutputStream* vios) { 1621 if (!code_item_accessor_.HasCodeItem()) { 1622 vios->Stream() << "Native method\n"; 1623 return; 1624 } 1625 { 1626 vios->Stream() << "Register Types:\n"; 1627 ScopedIndentation indent1(vios); 1628 reg_types_.Dump(vios->Stream()); 1629 } 1630 vios->Stream() << "Dumping instructions and register lines:\n"; 1631 ScopedIndentation indent1(vios); 1632 1633 for (const DexInstructionPcPair& inst : code_item_accessor_) { 1634 const size_t dex_pc = inst.DexPc(); 1635 1636 // Might be asked to dump before the table is initialized. 1637 if (reg_table_.IsInitialized()) { 1638 RegisterLine* reg_line = reg_table_.GetLine(dex_pc); 1639 if (reg_line != nullptr) { 1640 vios->Stream() << reg_line->Dump(this) << "\n"; 1641 } 1642 } 1643 1644 vios->Stream() 1645 << StringPrintf("0x%04zx", dex_pc) << ": " << GetInstructionFlags(dex_pc).ToString() << " "; 1646 const bool kDumpHexOfInstruction = false; 1647 if (kDumpHexOfInstruction) { 1648 vios->Stream() << inst->DumpHex(5) << " "; 1649 } 1650 vios->Stream() << inst->DumpString(dex_file_) << "\n"; 1651 } 1652 } 1653 1654 static bool IsPrimitiveDescriptor(char descriptor) { 1655 switch (descriptor) { 1656 case 'I': 1657 case 'C': 1658 case 'S': 1659 case 'B': 1660 case 'Z': 1661 case 'F': 1662 case 'D': 1663 case 'J': 1664 return true; 1665 default: 1666 return false; 1667 } 1668 } 1669 1670 template <bool kVerifierDebug> 1671 bool MethodVerifier<kVerifierDebug>::SetTypesFromSignature() { 1672 RegisterLine* reg_line = reg_table_.GetLine(0); 1673 1674 // Should have been verified earlier. 1675 DCHECK_GE(code_item_accessor_.RegistersSize(), code_item_accessor_.InsSize()); 1676 1677 uint32_t arg_start = code_item_accessor_.RegistersSize() - code_item_accessor_.InsSize(); 1678 size_t expected_args = code_item_accessor_.InsSize(); /* long/double count as two */ 1679 1680 // Include the "this" pointer. 1681 size_t cur_arg = 0; 1682 if (!IsStatic()) { 1683 if (expected_args == 0) { 1684 // Expect at least a receiver. 1685 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected 0 args, but method is not static"; 1686 return false; 1687 } 1688 1689 // If this is a constructor for a class other than java.lang.Object, mark the first ("this") 1690 // argument as uninitialized. This restricts field access until the superclass constructor is 1691 // called. 1692 const RegType& declaring_class = GetDeclaringClass(); 1693 if (IsConstructor()) { 1694 if (declaring_class.IsJavaLangObject()) { 1695 // "this" is implicitly initialized. 1696 reg_line->SetThisInitialized(); 1697 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class); 1698 } else { 1699 reg_line->SetRegisterType<LockOp::kClear>( 1700 this, 1701 arg_start + cur_arg, 1702 reg_types_.UninitializedThisArgument(declaring_class)); 1703 } 1704 } else { 1705 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class); 1706 } 1707 cur_arg++; 1708 } 1709 1710 const dex::ProtoId& proto_id = 1711 dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_)); 1712 DexFileParameterIterator iterator(*dex_file_, proto_id); 1713 1714 for (; iterator.HasNext(); iterator.Next()) { 1715 const char* descriptor = iterator.GetDescriptor(); 1716 if (descriptor == nullptr) { 1717 LOG(FATAL) << "Null descriptor"; 1718 } 1719 if (cur_arg >= expected_args) { 1720 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1721 << " args, found more (" << descriptor << ")"; 1722 return false; 1723 } 1724 switch (descriptor[0]) { 1725 case 'L': 1726 case '[': 1727 // We assume that reference arguments are initialized. The only way it could be otherwise 1728 // (assuming the caller was verified) is if the current method is <init>, but in that case 1729 // it's effectively considered initialized the instant we reach here (in the sense that we 1730 // can return without doing anything or call virtual methods). 1731 { 1732 // Note: don't check access. No error would be thrown for declaring or passing an 1733 // inaccessible class. Only actual accesses to fields or methods will. 1734 const RegType& reg_type = ResolveClass<CheckAccess::kNo>(iterator.GetTypeIdx()); 1735 if (!reg_type.IsNonZeroReferenceTypes()) { 1736 DCHECK(HasFailures()); 1737 return false; 1738 } 1739 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_type); 1740 } 1741 break; 1742 case 'Z': 1743 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Boolean()); 1744 break; 1745 case 'C': 1746 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Char()); 1747 break; 1748 case 'B': 1749 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Byte()); 1750 break; 1751 case 'I': 1752 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Integer()); 1753 break; 1754 case 'S': 1755 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Short()); 1756 break; 1757 case 'F': 1758 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Float()); 1759 break; 1760 case 'J': 1761 case 'D': { 1762 if (cur_arg + 1 >= expected_args) { 1763 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1764 << " args, found more (" << descriptor << ")"; 1765 return false; 1766 } 1767 1768 const RegType* lo_half; 1769 const RegType* hi_half; 1770 if (descriptor[0] == 'J') { 1771 lo_half = ®_types_.LongLo(); 1772 hi_half = ®_types_.LongHi(); 1773 } else { 1774 lo_half = ®_types_.DoubleLo(); 1775 hi_half = ®_types_.DoubleHi(); 1776 } 1777 reg_line->SetRegisterTypeWide(this, arg_start + cur_arg, *lo_half, *hi_half); 1778 cur_arg++; 1779 break; 1780 } 1781 default: 1782 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '" 1783 << descriptor << "'"; 1784 return false; 1785 } 1786 cur_arg++; 1787 } 1788 if (cur_arg != expected_args) { 1789 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1790 << " arguments, found " << cur_arg; 1791 return false; 1792 } 1793 const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id); 1794 // Validate return type. We don't do the type lookup; just want to make sure that it has the right 1795 // format. Only major difference from the method argument format is that 'V' is supported. 1796 bool result; 1797 if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') { 1798 result = descriptor[1] == '\0'; 1799 } else if (descriptor[0] == '[') { // single/multi-dimensional array of object/primitive 1800 size_t i = 0; 1801 do { 1802 i++; 1803 } while (descriptor[i] == '['); // process leading [ 1804 if (descriptor[i] == 'L') { // object array 1805 do { 1806 i++; // find closing ; 1807 } while (descriptor[i] != ';' && descriptor[i] != '\0'); 1808 result = descriptor[i] == ';'; 1809 } else { // primitive array 1810 result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0'; 1811 } 1812 } else if (descriptor[0] == 'L') { 1813 // could be more thorough here, but shouldn't be required 1814 size_t i = 0; 1815 do { 1816 i++; 1817 } while (descriptor[i] != ';' && descriptor[i] != '\0'); 1818 result = descriptor[i] == ';'; 1819 } else { 1820 result = false; 1821 } 1822 if (!result) { 1823 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '" 1824 << descriptor << "'"; 1825 } 1826 return result; 1827 } 1828 1829 template <bool kVerifierDebug> 1830 bool MethodVerifier<kVerifierDebug>::CodeFlowVerifyMethod() { 1831 const uint16_t* insns = code_item_accessor_.Insns(); 1832 const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits(); 1833 1834 /* Begin by marking the first instruction as "changed". */ 1835 GetModifiableInstructionFlags(0).SetChanged(); 1836 uint32_t start_guess = 0; 1837 1838 /* Continue until no instructions are marked "changed". */ 1839 while (true) { 1840 if (allow_thread_suspension_) { 1841 self_->AllowThreadSuspension(); 1842 } 1843 // Find the first marked one. Use "start_guess" as a way to find one quickly. 1844 uint32_t insn_idx = start_guess; 1845 for (; insn_idx < insns_size; insn_idx++) { 1846 if (GetInstructionFlags(insn_idx).IsChanged()) 1847 break; 1848 } 1849 if (insn_idx == insns_size) { 1850 if (start_guess != 0) { 1851 /* try again, starting from the top */ 1852 start_guess = 0; 1853 continue; 1854 } else { 1855 /* all flags are clear */ 1856 break; 1857 } 1858 } 1859 // We carry the working set of registers from instruction to instruction. If this address can 1860 // be the target of a branch (or throw) instruction, or if we're skipping around chasing 1861 // "changed" flags, we need to load the set of registers from the table. 1862 // Because we always prefer to continue on to the next instruction, we should never have a 1863 // situation where we have a stray "changed" flag set on an instruction that isn't a branch 1864 // target. 1865 work_insn_idx_ = insn_idx; 1866 if (GetInstructionFlags(insn_idx).IsBranchTarget()) { 1867 work_line_->CopyFromLine(reg_table_.GetLine(insn_idx)); 1868 } else if (kIsDebugBuild) { 1869 /* 1870 * Sanity check: retrieve the stored register line (assuming 1871 * a full table) and make sure it actually matches. 1872 */ 1873 RegisterLine* register_line = reg_table_.GetLine(insn_idx); 1874 if (register_line != nullptr) { 1875 if (work_line_->CompareLine(register_line) != 0) { 1876 Dump(LOG_STREAM(FATAL_WITHOUT_ABORT)); 1877 LOG(FATAL_WITHOUT_ABORT) << info_messages_.str(); 1878 LOG(FATAL) << "work_line diverged in " << dex_file_->PrettyMethod(dex_method_idx_) 1879 << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n" 1880 << " work_line=" << work_line_->Dump(this) << "\n" 1881 << " expected=" << register_line->Dump(this); 1882 } 1883 } 1884 } 1885 if (!CodeFlowVerifyInstruction(&start_guess)) { 1886 std::string prepend(dex_file_->PrettyMethod(dex_method_idx_)); 1887 prepend += " failed to verify: "; 1888 PrependToLastFailMessage(prepend); 1889 return false; 1890 } 1891 /* Clear "changed" and mark as visited. */ 1892 GetModifiableInstructionFlags(insn_idx).SetVisited(); 1893 GetModifiableInstructionFlags(insn_idx).ClearChanged(); 1894 } 1895 1896 if (kVerifierDebug) { 1897 /* 1898 * Scan for dead code. There's nothing "evil" about dead code 1899 * (besides the wasted space), but it indicates a flaw somewhere 1900 * down the line, possibly in the verifier. 1901 * 1902 * If we've substituted "always throw" instructions into the stream, 1903 * we are almost certainly going to have some dead code. 1904 */ 1905 int dead_start = -1; 1906 1907 for (const DexInstructionPcPair& inst : code_item_accessor_) { 1908 const uint32_t insn_idx = inst.DexPc(); 1909 /* 1910 * Switch-statement data doesn't get "visited" by scanner. It 1911 * may or may not be preceded by a padding NOP (for alignment). 1912 */ 1913 if (insns[insn_idx] == Instruction::kPackedSwitchSignature || 1914 insns[insn_idx] == Instruction::kSparseSwitchSignature || 1915 insns[insn_idx] == Instruction::kArrayDataSignature || 1916 (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) && 1917 (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature || 1918 insns[insn_idx + 1] == Instruction::kSparseSwitchSignature || 1919 insns[insn_idx + 1] == Instruction::kArrayDataSignature))) { 1920 GetModifiableInstructionFlags(insn_idx).SetVisited(); 1921 } 1922 1923 if (!GetInstructionFlags(insn_idx).IsVisited()) { 1924 if (dead_start < 0) { 1925 dead_start = insn_idx; 1926 } 1927 } else if (dead_start >= 0) { 1928 LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start) 1929 << "-" << reinterpret_cast<void*>(insn_idx - 1); 1930 dead_start = -1; 1931 } 1932 } 1933 if (dead_start >= 0) { 1934 LogVerifyInfo() 1935 << "dead code " << reinterpret_cast<void*>(dead_start) 1936 << "-" << reinterpret_cast<void*>(code_item_accessor_.InsnsSizeInCodeUnits() - 1); 1937 } 1938 // To dump the state of the verify after a method, do something like: 1939 // if (dex_file_->PrettyMethod(dex_method_idx_) == 1940 // "boolean java.lang.String.equals(java.lang.Object)") { 1941 // LOG(INFO) << info_messages_.str(); 1942 // } 1943 } 1944 return true; 1945 } 1946 1947 // Returns the index of the first final instance field of the given class, or kDexNoIndex if there 1948 // is no such field. 1949 static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) { 1950 const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx); 1951 DCHECK(class_def != nullptr); 1952 ClassAccessor accessor(dex_file, *class_def); 1953 for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) { 1954 if (field.IsFinal()) { 1955 return field.GetIndex(); 1956 } 1957 } 1958 return dex::kDexNoIndex; 1959 } 1960 1961 // Setup a register line for the given return instruction. 1962 template <bool kVerifierDebug> 1963 static void AdjustReturnLine(MethodVerifier<kVerifierDebug>* verifier, 1964 const Instruction* ret_inst, 1965 RegisterLine* line) { 1966 Instruction::Code opcode = ret_inst->Opcode(); 1967 1968 switch (opcode) { 1969 case Instruction::RETURN_VOID: 1970 case Instruction::RETURN_VOID_NO_BARRIER: 1971 if (verifier->IsInstanceConstructor()) { 1972 // Before we mark all regs as conflicts, check that we don't have an uninitialized this. 1973 line->CheckConstructorReturn(verifier); 1974 } 1975 line->MarkAllRegistersAsConflicts(verifier); 1976 break; 1977 1978 case Instruction::RETURN: 1979 case Instruction::RETURN_OBJECT: 1980 line->MarkAllRegistersAsConflictsExcept(verifier, ret_inst->VRegA_11x()); 1981 break; 1982 1983 case Instruction::RETURN_WIDE: 1984 line->MarkAllRegistersAsConflictsExceptWide(verifier, ret_inst->VRegA_11x()); 1985 break; 1986 1987 default: 1988 LOG(FATAL) << "Unknown return opcode " << opcode; 1989 UNREACHABLE(); 1990 } 1991 } 1992 1993 template <bool kVerifierDebug> 1994 bool MethodVerifier<kVerifierDebug>::CodeFlowVerifyInstruction(uint32_t* start_guess) { 1995 // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about. 1996 // We want the state _before_ the instruction, for the case where the dex pc we're 1997 // interested in is itself a monitor-enter instruction (which is a likely place 1998 // for a thread to be suspended). 1999 if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) { 2000 monitor_enter_dex_pcs_->clear(); // The new work line is more accurate than the previous one. 2001 2002 std::map<uint32_t, DexLockInfo> depth_to_lock_info; 2003 auto collector = [&](uint32_t dex_reg, uint32_t depth) { 2004 auto insert_pair = depth_to_lock_info.emplace(depth, DexLockInfo(depth)); 2005 auto it = insert_pair.first; 2006 auto set_insert_pair = it->second.dex_registers.insert(dex_reg); 2007 DCHECK(set_insert_pair.second); 2008 }; 2009 work_line_->IterateRegToLockDepths(collector); 2010 for (auto& pair : depth_to_lock_info) { 2011 monitor_enter_dex_pcs_->push_back(pair.second); 2012 // Map depth to dex PC. 2013 (*monitor_enter_dex_pcs_)[monitor_enter_dex_pcs_->size() - 1].dex_pc = 2014 work_line_->GetMonitorEnterDexPc(pair.second.dex_pc); 2015 } 2016 } 2017 2018 /* 2019 * Once we finish decoding the instruction, we need to figure out where 2020 * we can go from here. There are three possible ways to transfer 2021 * control to another statement: 2022 * 2023 * (1) Continue to the next instruction. Applies to all but 2024 * unconditional branches, method returns, and exception throws. 2025 * (2) Branch to one or more possible locations. Applies to branches 2026 * and switch statements. 2027 * (3) Exception handlers. Applies to any instruction that can 2028 * throw an exception that is handled by an encompassing "try" 2029 * block. 2030 * 2031 * We can also return, in which case there is no successor instruction 2032 * from this point. 2033 * 2034 * The behavior can be determined from the opcode flags. 2035 */ 2036 const uint16_t* insns = code_item_accessor_.Insns() + work_insn_idx_; 2037 const Instruction* inst = Instruction::At(insns); 2038 int opcode_flags = Instruction::FlagsOf(inst->Opcode()); 2039 2040 int32_t branch_target = 0; 2041 bool just_set_result = false; 2042 if (kVerifierDebug) { 2043 // Generate processing back trace to debug verifier 2044 LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << std::endl 2045 << work_line_->Dump(this); 2046 } 2047 2048 /* 2049 * Make a copy of the previous register state. If the instruction 2050 * can throw an exception, we will copy/merge this into the "catch" 2051 * address rather than work_line, because we don't want the result 2052 * from the "successful" code path (e.g. a check-cast that "improves" 2053 * a type) to be visible to the exception handler. 2054 */ 2055 if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) { 2056 saved_line_->CopyFromLine(work_line_.get()); 2057 } else if (kIsDebugBuild) { 2058 saved_line_->FillWithGarbage(); 2059 } 2060 DCHECK(!have_pending_runtime_throw_failure_); // Per-instruction flag, should not be set here. 2061 2062 2063 // We need to ensure the work line is consistent while performing validation. When we spot a 2064 // peephole pattern we compute a new line for either the fallthrough instruction or the 2065 // branch target. 2066 RegisterLineArenaUniquePtr branch_line; 2067 RegisterLineArenaUniquePtr fallthrough_line; 2068 2069 switch (inst->Opcode()) { 2070 case Instruction::NOP: 2071 /* 2072 * A "pure" NOP has no effect on anything. Data tables start with 2073 * a signature that looks like a NOP; if we see one of these in 2074 * the course of executing code then we have a problem. 2075 */ 2076 if (inst->VRegA_10x() != 0) { 2077 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream"; 2078 } 2079 break; 2080 2081 case Instruction::MOVE: 2082 work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr); 2083 break; 2084 case Instruction::MOVE_FROM16: 2085 work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr); 2086 break; 2087 case Instruction::MOVE_16: 2088 work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr); 2089 break; 2090 case Instruction::MOVE_WIDE: 2091 work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x()); 2092 break; 2093 case Instruction::MOVE_WIDE_FROM16: 2094 work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x()); 2095 break; 2096 case Instruction::MOVE_WIDE_16: 2097 work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x()); 2098 break; 2099 case Instruction::MOVE_OBJECT: 2100 work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef); 2101 break; 2102 case Instruction::MOVE_OBJECT_FROM16: 2103 work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef); 2104 break; 2105 case Instruction::MOVE_OBJECT_16: 2106 work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef); 2107 break; 2108 2109 /* 2110 * The move-result instructions copy data out of a "pseudo-register" 2111 * with the results from the last method invocation. In practice we 2112 * might want to hold the result in an actual CPU register, so the 2113 * Dalvik spec requires that these only appear immediately after an 2114 * invoke or filled-new-array. 2115 * 2116 * These calls invalidate the "result" register. (This is now 2117 * redundant with the reset done below, but it can make the debug info 2118 * easier to read in some cases.) 2119 */ 2120 case Instruction::MOVE_RESULT: 2121 work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false); 2122 break; 2123 case Instruction::MOVE_RESULT_WIDE: 2124 work_line_->CopyResultRegister2(this, inst->VRegA_11x()); 2125 break; 2126 case Instruction::MOVE_RESULT_OBJECT: 2127 work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true); 2128 break; 2129 2130 case Instruction::MOVE_EXCEPTION: { 2131 // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case 2132 // where one entrypoint to the catch block is not actually an exception path. 2133 if (work_insn_idx_ == 0) { 2134 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0"; 2135 break; 2136 } 2137 /* 2138 * This statement can only appear as the first instruction in an exception handler. We verify 2139 * that as part of extracting the exception type from the catch block list. 2140 */ 2141 const RegType& res_type = GetCaughtExceptionType(); 2142 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_11x(), res_type); 2143 break; 2144 } 2145 case Instruction::RETURN_VOID: 2146 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2147 if (!GetMethodReturnType().IsConflict()) { 2148 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected"; 2149 } 2150 } 2151 break; 2152 case Instruction::RETURN: 2153 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2154 /* check the method signature */ 2155 const RegType& return_type = GetMethodReturnType(); 2156 if (!return_type.IsCategory1Types()) { 2157 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type " 2158 << return_type; 2159 } else { 2160 // Compilers may generate synthetic functions that write byte values into boolean fields. 2161 // Also, it may use integer values for boolean, byte, short, and character return types. 2162 const uint32_t vregA = inst->VRegA_11x(); 2163 const RegType& src_type = work_line_->GetRegisterType(this, vregA); 2164 bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) || 2165 ((return_type.IsBoolean() || return_type.IsByte() || 2166 return_type.IsShort() || return_type.IsChar()) && 2167 src_type.IsInteger())); 2168 /* check the register contents */ 2169 bool success = 2170 work_line_->VerifyRegisterType(this, vregA, use_src ? src_type : return_type); 2171 if (!success) { 2172 AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA)); 2173 } 2174 } 2175 } 2176 break; 2177 case Instruction::RETURN_WIDE: 2178 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2179 /* check the method signature */ 2180 const RegType& return_type = GetMethodReturnType(); 2181 if (!return_type.IsCategory2Types()) { 2182 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected"; 2183 } else { 2184 /* check the register contents */ 2185 const uint32_t vregA = inst->VRegA_11x(); 2186 bool success = work_line_->VerifyRegisterType(this, vregA, return_type); 2187 if (!success) { 2188 AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA)); 2189 } 2190 } 2191 } 2192 break; 2193 case Instruction::RETURN_OBJECT: 2194 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2195 const RegType& return_type = GetMethodReturnType(); 2196 if (!return_type.IsReferenceTypes()) { 2197 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected"; 2198 } else { 2199 /* return_type is the *expected* return type, not register value */ 2200 DCHECK(!return_type.IsZeroOrNull()); 2201 DCHECK(!return_type.IsUninitializedReference()); 2202 const uint32_t vregA = inst->VRegA_11x(); 2203 const RegType& reg_type = work_line_->GetRegisterType(this, vregA); 2204 // Disallow returning undefined, conflict & uninitialized values and verify that the 2205 // reference in vAA is an instance of the "return_type." 2206 if (reg_type.IsUndefined()) { 2207 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning undefined register"; 2208 } else if (reg_type.IsConflict()) { 2209 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning register with conflict"; 2210 } else if (reg_type.IsUninitializedTypes()) { 2211 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning uninitialized object '" 2212 << reg_type << "'"; 2213 } else if (!reg_type.IsReferenceTypes()) { 2214 // We really do expect a reference here. 2215 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object returns a non-reference type " 2216 << reg_type; 2217 } else if (!return_type.IsAssignableFrom(reg_type, this)) { 2218 if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) { 2219 Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type 2220 << "' or '" << reg_type << "'"; 2221 } else { 2222 bool soft_error = false; 2223 // Check whether arrays are involved. They will show a valid class status, even 2224 // if their components are erroneous. 2225 if (reg_type.IsArrayTypes() && return_type.IsArrayTypes()) { 2226 return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this, &soft_error); 2227 if (soft_error) { 2228 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "array with erroneous component type: " 2229 << reg_type << " vs " << return_type; 2230 } 2231 } 2232 2233 if (!soft_error) { 2234 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type 2235 << "', but expected from declaration '" << return_type << "'"; 2236 } 2237 } 2238 } 2239 } 2240 } 2241 break; 2242 2243 /* could be boolean, int, float, or a null reference */ 2244 case Instruction::CONST_4: { 2245 int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28; 2246 work_line_->SetRegisterType<LockOp::kClear>( 2247 this, inst->VRegA_11n(), DetermineCat1Constant(val, need_precise_constants_)); 2248 break; 2249 } 2250 case Instruction::CONST_16: { 2251 int16_t val = static_cast<int16_t>(inst->VRegB_21s()); 2252 work_line_->SetRegisterType<LockOp::kClear>( 2253 this, inst->VRegA_21s(), DetermineCat1Constant(val, need_precise_constants_)); 2254 break; 2255 } 2256 case Instruction::CONST: { 2257 int32_t val = inst->VRegB_31i(); 2258 work_line_->SetRegisterType<LockOp::kClear>( 2259 this, inst->VRegA_31i(), DetermineCat1Constant(val, need_precise_constants_)); 2260 break; 2261 } 2262 case Instruction::CONST_HIGH16: { 2263 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16); 2264 work_line_->SetRegisterType<LockOp::kClear>( 2265 this, inst->VRegA_21h(), DetermineCat1Constant(val, need_precise_constants_)); 2266 break; 2267 } 2268 /* could be long or double; resolved upon use */ 2269 case Instruction::CONST_WIDE_16: { 2270 int64_t val = static_cast<int16_t>(inst->VRegB_21s()); 2271 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2272 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2273 work_line_->SetRegisterTypeWide(this, inst->VRegA_21s(), lo, hi); 2274 break; 2275 } 2276 case Instruction::CONST_WIDE_32: { 2277 int64_t val = static_cast<int32_t>(inst->VRegB_31i()); 2278 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2279 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2280 work_line_->SetRegisterTypeWide(this, inst->VRegA_31i(), lo, hi); 2281 break; 2282 } 2283 case Instruction::CONST_WIDE: { 2284 int64_t val = inst->VRegB_51l(); 2285 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2286 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2287 work_line_->SetRegisterTypeWide(this, inst->VRegA_51l(), lo, hi); 2288 break; 2289 } 2290 case Instruction::CONST_WIDE_HIGH16: { 2291 int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48; 2292 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2293 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2294 work_line_->SetRegisterTypeWide(this, inst->VRegA_21h(), lo, hi); 2295 break; 2296 } 2297 case Instruction::CONST_STRING: 2298 work_line_->SetRegisterType<LockOp::kClear>( 2299 this, inst->VRegA_21c(), reg_types_.JavaLangString()); 2300 break; 2301 case Instruction::CONST_STRING_JUMBO: 2302 work_line_->SetRegisterType<LockOp::kClear>( 2303 this, inst->VRegA_31c(), reg_types_.JavaLangString()); 2304 break; 2305 case Instruction::CONST_CLASS: { 2306 // Get type from instruction if unresolved then we need an access check 2307 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2308 const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c())); 2309 // Register holds class, ie its type is class, on error it will hold Conflict. 2310 work_line_->SetRegisterType<LockOp::kClear>( 2311 this, inst->VRegA_21c(), res_type.IsConflict() ? res_type 2312 : reg_types_.JavaLangClass()); 2313 break; 2314 } 2315 case Instruction::CONST_METHOD_HANDLE: 2316 work_line_->SetRegisterType<LockOp::kClear>( 2317 this, inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodHandle()); 2318 break; 2319 case Instruction::CONST_METHOD_TYPE: 2320 work_line_->SetRegisterType<LockOp::kClear>( 2321 this, inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodType()); 2322 break; 2323 case Instruction::MONITOR_ENTER: 2324 work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_); 2325 // Check whether the previous instruction is a move-object with vAA as a source, creating 2326 // untracked lock aliasing. 2327 if (0 != work_insn_idx_ && !GetInstructionFlags(work_insn_idx_).IsBranchTarget()) { 2328 uint32_t prev_idx = work_insn_idx_ - 1; 2329 while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) { 2330 prev_idx--; 2331 } 2332 const Instruction& prev_inst = code_item_accessor_.InstructionAt(prev_idx); 2333 switch (prev_inst.Opcode()) { 2334 case Instruction::MOVE_OBJECT: 2335 case Instruction::MOVE_OBJECT_16: 2336 case Instruction::MOVE_OBJECT_FROM16: 2337 if (prev_inst.VRegB() == inst->VRegA_11x()) { 2338 // Redo the copy. This won't change the register types, but update the lock status 2339 // for the aliased register. 2340 work_line_->CopyRegister1(this, 2341 prev_inst.VRegA(), 2342 prev_inst.VRegB(), 2343 kTypeCategoryRef); 2344 } 2345 break; 2346 2347 // Catch a case of register aliasing when two registers are linked to the same 2348 // java.lang.Class object via two consequent const-class instructions immediately 2349 // preceding monitor-enter called on one of those registers. 2350 case Instruction::CONST_CLASS: { 2351 // Get the second previous instruction. 2352 if (prev_idx == 0 || GetInstructionFlags(prev_idx).IsBranchTarget()) { 2353 break; 2354 } 2355 prev_idx--; 2356 while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) { 2357 prev_idx--; 2358 } 2359 const Instruction& prev2_inst = code_item_accessor_.InstructionAt(prev_idx); 2360 2361 // Match the pattern "const-class; const-class; monitor-enter;" 2362 if (prev2_inst.Opcode() != Instruction::CONST_CLASS) { 2363 break; 2364 } 2365 2366 // Ensure both const-classes are called for the same type_idx. 2367 if (prev_inst.VRegB_21c() != prev2_inst.VRegB_21c()) { 2368 break; 2369 } 2370 2371 // Update the lock status for the aliased register. 2372 if (prev_inst.VRegA() == inst->VRegA_11x()) { 2373 work_line_->CopyRegister1(this, 2374 prev2_inst.VRegA(), 2375 inst->VRegA_11x(), 2376 kTypeCategoryRef); 2377 } else if (prev2_inst.VRegA() == inst->VRegA_11x()) { 2378 work_line_->CopyRegister1(this, 2379 prev_inst.VRegA(), 2380 inst->VRegA_11x(), 2381 kTypeCategoryRef); 2382 } 2383 break; 2384 } 2385 2386 default: // Other instruction types ignored. 2387 break; 2388 } 2389 } 2390 break; 2391 case Instruction::MONITOR_EXIT: 2392 /* 2393 * monitor-exit instructions are odd. They can throw exceptions, 2394 * but when they do they act as if they succeeded and the PC is 2395 * pointing to the following instruction. (This behavior goes back 2396 * to the need to handle asynchronous exceptions, a now-deprecated 2397 * feature that Dalvik doesn't support.) 2398 * 2399 * In practice we don't need to worry about this. The only 2400 * exceptions that can be thrown from monitor-exit are for a 2401 * null reference and -exit without a matching -enter. If the 2402 * structured locking checks are working, the former would have 2403 * failed on the -enter instruction, and the latter is impossible. 2404 * 2405 * This is fortunate, because issue 3221411 prevents us from 2406 * chasing the "can throw" path when monitor verification is 2407 * enabled. If we can fully verify the locking we can ignore 2408 * some catch blocks (which will show up as "dead" code when 2409 * we skip them here); if we can't, then the code path could be 2410 * "live" so we still need to check it. 2411 */ 2412 opcode_flags &= ~Instruction::kThrow; 2413 work_line_->PopMonitor(this, inst->VRegA_11x()); 2414 break; 2415 case Instruction::CHECK_CAST: 2416 case Instruction::INSTANCE_OF: { 2417 /* 2418 * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This 2419 * could be a "upcast" -- not expected, so we don't try to address it.) 2420 * 2421 * If it fails, an exception is thrown, which we deal with later by ignoring the update to 2422 * dec_insn.vA when branching to a handler. 2423 */ 2424 const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST); 2425 const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c()); 2426 const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx); 2427 if (res_type.IsConflict()) { 2428 // If this is a primitive type, fail HARD. 2429 ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->LookupResolvedType( 2430 type_idx, dex_cache_.Get(), class_loader_.Get()); 2431 if (klass != nullptr && klass->IsPrimitive()) { 2432 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type " 2433 << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in " 2434 << GetDeclaringClass(); 2435 break; 2436 } 2437 2438 DCHECK_NE(failures_.size(), 0U); 2439 if (!is_checkcast) { 2440 work_line_->SetRegisterType<LockOp::kClear>(this, 2441 inst->VRegA_22c(), 2442 reg_types_.Boolean()); 2443 } 2444 break; // bad class 2445 } 2446 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2447 uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c(); 2448 const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg); 2449 if (!res_type.IsNonZeroReferenceTypes()) { 2450 if (is_checkcast) { 2451 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type; 2452 } else { 2453 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type; 2454 } 2455 } else if (!orig_type.IsReferenceTypes()) { 2456 if (is_checkcast) { 2457 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg; 2458 } else { 2459 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg; 2460 } 2461 } else if (orig_type.IsUninitializedTypes()) { 2462 if (is_checkcast) { 2463 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on uninitialized reference in v" 2464 << orig_type_reg; 2465 } else { 2466 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on uninitialized reference in v" 2467 << orig_type_reg; 2468 } 2469 } else { 2470 if (is_checkcast) { 2471 work_line_->SetRegisterType<LockOp::kKeep>(this, inst->VRegA_21c(), res_type); 2472 } else { 2473 work_line_->SetRegisterType<LockOp::kClear>(this, 2474 inst->VRegA_22c(), 2475 reg_types_.Boolean()); 2476 } 2477 } 2478 break; 2479 } 2480 case Instruction::ARRAY_LENGTH: { 2481 const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x()); 2482 if (res_type.IsReferenceTypes()) { 2483 if (!res_type.IsArrayTypes() && !res_type.IsZeroOrNull()) { 2484 // ie not an array or null 2485 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type; 2486 } else { 2487 work_line_->SetRegisterType<LockOp::kClear>(this, 2488 inst->VRegA_12x(), 2489 reg_types_.Integer()); 2490 } 2491 } else { 2492 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type; 2493 } 2494 break; 2495 } 2496 case Instruction::NEW_INSTANCE: { 2497 const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c())); 2498 if (res_type.IsConflict()) { 2499 DCHECK_NE(failures_.size(), 0U); 2500 break; // bad class 2501 } 2502 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2503 // can't create an instance of an interface or abstract class */ 2504 if (!res_type.IsInstantiableTypes()) { 2505 Fail(VERIFY_ERROR_INSTANTIATION) 2506 << "new-instance on primitive, interface or abstract class" << res_type; 2507 // Soft failure so carry on to set register type. 2508 } 2509 const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_); 2510 // Any registers holding previous allocations from this address that have not yet been 2511 // initialized must be marked invalid. 2512 work_line_->MarkUninitRefsAsInvalid(this, uninit_type); 2513 // add the new uninitialized reference to the register state 2514 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_21c(), uninit_type); 2515 break; 2516 } 2517 case Instruction::NEW_ARRAY: 2518 VerifyNewArray(inst, false, false); 2519 break; 2520 case Instruction::FILLED_NEW_ARRAY: 2521 VerifyNewArray(inst, true, false); 2522 just_set_result = true; // Filled new array sets result register 2523 break; 2524 case Instruction::FILLED_NEW_ARRAY_RANGE: 2525 VerifyNewArray(inst, true, true); 2526 just_set_result = true; // Filled new array range sets result register 2527 break; 2528 case Instruction::CMPL_FLOAT: 2529 case Instruction::CMPG_FLOAT: 2530 if (!work_line_->VerifyRegisterType(this, inst->VRegB_23x(), reg_types_.Float())) { 2531 break; 2532 } 2533 if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) { 2534 break; 2535 } 2536 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2537 break; 2538 case Instruction::CMPL_DOUBLE: 2539 case Instruction::CMPG_DOUBLE: 2540 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.DoubleLo(), 2541 reg_types_.DoubleHi())) { 2542 break; 2543 } 2544 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.DoubleLo(), 2545 reg_types_.DoubleHi())) { 2546 break; 2547 } 2548 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2549 break; 2550 case Instruction::CMP_LONG: 2551 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(), 2552 reg_types_.LongHi())) { 2553 break; 2554 } 2555 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.LongLo(), 2556 reg_types_.LongHi())) { 2557 break; 2558 } 2559 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2560 break; 2561 case Instruction::THROW: { 2562 const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x()); 2563 if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type, this)) { 2564 if (res_type.IsUninitializedTypes()) { 2565 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown exception not initialized"; 2566 } else if (!res_type.IsReferenceTypes()) { 2567 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown value of non-reference type " << res_type; 2568 } else { 2569 Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT) 2570 << "thrown class " << res_type << " not instanceof Throwable"; 2571 } 2572 } 2573 break; 2574 } 2575 case Instruction::GOTO: 2576 case Instruction::GOTO_16: 2577 case Instruction::GOTO_32: 2578 /* no effect on or use of registers */ 2579 break; 2580 2581 case Instruction::PACKED_SWITCH: 2582 case Instruction::SPARSE_SWITCH: 2583 /* verify that vAA is an integer, or can be converted to one */ 2584 work_line_->VerifyRegisterType(this, inst->VRegA_31t(), reg_types_.Integer()); 2585 break; 2586 2587 case Instruction::FILL_ARRAY_DATA: { 2588 /* Similar to the verification done for APUT */ 2589 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t()); 2590 /* array_type can be null if the reg type is Zero */ 2591 if (!array_type.IsZeroOrNull()) { 2592 if (!array_type.IsArrayTypes()) { 2593 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type " 2594 << array_type; 2595 } else if (array_type.IsUnresolvedTypes()) { 2596 // If it's an unresolved array type, it must be non-primitive. 2597 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data for array of type " 2598 << array_type; 2599 } else { 2600 const RegType& component_type = reg_types_.GetComponentType(array_type, 2601 class_loader_.Get()); 2602 DCHECK(!component_type.IsConflict()); 2603 if (component_type.IsNonZeroReferenceTypes()) { 2604 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type " 2605 << component_type; 2606 } else { 2607 // Now verify if the element width in the table matches the element width declared in 2608 // the array 2609 const uint16_t* array_data = 2610 insns + (insns[1] | (static_cast<int32_t>(insns[2]) << 16)); 2611 if (array_data[0] != Instruction::kArrayDataSignature) { 2612 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data"; 2613 } else { 2614 size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType()); 2615 // Since we don't compress the data in Dex, expect to see equal width of data stored 2616 // in the table and expected from the array class. 2617 if (array_data[1] != elem_width) { 2618 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1] 2619 << " vs " << elem_width << ")"; 2620 } 2621 } 2622 } 2623 } 2624 } 2625 break; 2626 } 2627 case Instruction::IF_EQ: 2628 case Instruction::IF_NE: { 2629 const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t()); 2630 const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t()); 2631 bool mismatch = false; 2632 if (reg_type1.IsZeroOrNull()) { // zero then integral or reference expected 2633 mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes(); 2634 } else if (reg_type1.IsReferenceTypes()) { // both references? 2635 mismatch = !reg_type2.IsReferenceTypes(); 2636 } else { // both integral? 2637 mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes(); 2638 } 2639 if (mismatch) { 2640 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << "," 2641 << reg_type2 << ") must both be references or integral"; 2642 } 2643 break; 2644 } 2645 case Instruction::IF_LT: 2646 case Instruction::IF_GE: 2647 case Instruction::IF_GT: 2648 case Instruction::IF_LE: { 2649 const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t()); 2650 const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t()); 2651 if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) { 2652 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << "," 2653 << reg_type2 << ") must be integral"; 2654 } 2655 break; 2656 } 2657 case Instruction::IF_EQZ: 2658 case Instruction::IF_NEZ: { 2659 const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t()); 2660 if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) { 2661 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type 2662 << " unexpected as arg to if-eqz/if-nez"; 2663 } 2664 2665 // Find previous instruction - its existence is a precondition to peephole optimization. 2666 uint32_t instance_of_idx = 0; 2667 if (0 != work_insn_idx_) { 2668 instance_of_idx = work_insn_idx_ - 1; 2669 while (0 != instance_of_idx && !GetInstructionFlags(instance_of_idx).IsOpcode()) { 2670 instance_of_idx--; 2671 } 2672 if (FailOrAbort(GetInstructionFlags(instance_of_idx).IsOpcode(), 2673 "Unable to get previous instruction of if-eqz/if-nez for work index ", 2674 work_insn_idx_)) { 2675 break; 2676 } 2677 } else { 2678 break; 2679 } 2680 2681 const Instruction& instance_of_inst = code_item_accessor_.InstructionAt(instance_of_idx); 2682 2683 /* Check for peep-hole pattern of: 2684 * ...; 2685 * instance-of vX, vY, T; 2686 * ifXXX vX, label ; 2687 * ...; 2688 * label: 2689 * ...; 2690 * and sharpen the type of vY to be type T. 2691 * Note, this pattern can't be if: 2692 * - if there are other branches to this branch, 2693 * - when vX == vY. 2694 */ 2695 if (!CurrentInsnFlags()->IsBranchTarget() && 2696 (Instruction::INSTANCE_OF == instance_of_inst.Opcode()) && 2697 (inst->VRegA_21t() == instance_of_inst.VRegA_22c()) && 2698 (instance_of_inst.VRegA_22c() != instance_of_inst.VRegB_22c())) { 2699 // Check the type of the instance-of is different than that of registers type, as if they 2700 // are the same there is no work to be done here. Check that the conversion is not to or 2701 // from an unresolved type as type information is imprecise. If the instance-of is to an 2702 // interface then ignore the type information as interfaces can only be treated as Objects 2703 // and we don't want to disallow field and other operations on the object. If the value 2704 // being instance-of checked against is known null (zero) then allow the optimization as 2705 // we didn't have type information. If the merge of the instance-of type with the original 2706 // type is assignable to the original then allow optimization. This check is performed to 2707 // ensure that subsequent merges don't lose type information - such as becoming an 2708 // interface from a class that would lose information relevant to field checks. 2709 const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst.VRegB_22c()); 2710 const RegType& cast_type = ResolveClass<CheckAccess::kYes>( 2711 dex::TypeIndex(instance_of_inst.VRegC_22c())); 2712 2713 if (!orig_type.Equals(cast_type) && 2714 !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() && 2715 cast_type.HasClass() && // Could be conflict type, make sure it has a class. 2716 !cast_type.GetClass()->IsInterface() && 2717 (orig_type.IsZeroOrNull() || 2718 orig_type.IsStrictlyAssignableFrom( 2719 cast_type.Merge(orig_type, ®_types_, this), this))) { 2720 RegisterLine* update_line = RegisterLine::Create(code_item_accessor_.RegistersSize(), 2721 allocator_, 2722 GetRegTypeCache()); 2723 if (inst->Opcode() == Instruction::IF_EQZ) { 2724 fallthrough_line.reset(update_line); 2725 } else { 2726 branch_line.reset(update_line); 2727 } 2728 update_line->CopyFromLine(work_line_.get()); 2729 update_line->SetRegisterType<LockOp::kKeep>(this, 2730 instance_of_inst.VRegB_22c(), 2731 cast_type); 2732 if (!GetInstructionFlags(instance_of_idx).IsBranchTarget() && 0 != instance_of_idx) { 2733 // See if instance-of was preceded by a move-object operation, common due to the small 2734 // register encoding space of instance-of, and propagate type information to the source 2735 // of the move-object. 2736 // Note: this is only valid if the move source was not clobbered. 2737 uint32_t move_idx = instance_of_idx - 1; 2738 while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) { 2739 move_idx--; 2740 } 2741 if (FailOrAbort(GetInstructionFlags(move_idx).IsOpcode(), 2742 "Unable to get previous instruction of if-eqz/if-nez for work index ", 2743 work_insn_idx_)) { 2744 break; 2745 } 2746 auto maybe_update_fn = [&instance_of_inst, update_line, this, &cast_type]( 2747 uint16_t move_src, 2748 uint16_t move_trg) 2749 REQUIRES_SHARED(Locks::mutator_lock_) { 2750 if (move_trg == instance_of_inst.VRegB_22c() && 2751 move_src != instance_of_inst.VRegA_22c()) { 2752 update_line->SetRegisterType<LockOp::kKeep>(this, move_src, cast_type); 2753 } 2754 }; 2755 const Instruction& move_inst = code_item_accessor_.InstructionAt(move_idx); 2756 switch (move_inst.Opcode()) { 2757 case Instruction::MOVE_OBJECT: 2758 maybe_update_fn(move_inst.VRegB_12x(), move_inst.VRegA_12x()); 2759 break; 2760 case Instruction::MOVE_OBJECT_FROM16: 2761 maybe_update_fn(move_inst.VRegB_22x(), move_inst.VRegA_22x()); 2762 break; 2763 case Instruction::MOVE_OBJECT_16: 2764 maybe_update_fn(move_inst.VRegB_32x(), move_inst.VRegA_32x()); 2765 break; 2766 default: 2767 break; 2768 } 2769 } 2770 } 2771 } 2772 2773 break; 2774 } 2775 case Instruction::IF_LTZ: 2776 case Instruction::IF_GEZ: 2777 case Instruction::IF_GTZ: 2778 case Instruction::IF_LEZ: { 2779 const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t()); 2780 if (!reg_type.IsIntegralTypes()) { 2781 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type 2782 << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez"; 2783 } 2784 break; 2785 } 2786 case Instruction::AGET_BOOLEAN: 2787 VerifyAGet(inst, reg_types_.Boolean(), true); 2788 break; 2789 case Instruction::AGET_BYTE: 2790 VerifyAGet(inst, reg_types_.Byte(), true); 2791 break; 2792 case Instruction::AGET_CHAR: 2793 VerifyAGet(inst, reg_types_.Char(), true); 2794 break; 2795 case Instruction::AGET_SHORT: 2796 VerifyAGet(inst, reg_types_.Short(), true); 2797 break; 2798 case Instruction::AGET: 2799 VerifyAGet(inst, reg_types_.Integer(), true); 2800 break; 2801 case Instruction::AGET_WIDE: 2802 VerifyAGet(inst, reg_types_.LongLo(), true); 2803 break; 2804 case Instruction::AGET_OBJECT: 2805 VerifyAGet(inst, reg_types_.JavaLangObject(false), false); 2806 break; 2807 2808 case Instruction::APUT_BOOLEAN: 2809 VerifyAPut(inst, reg_types_.Boolean(), true); 2810 break; 2811 case Instruction::APUT_BYTE: 2812 VerifyAPut(inst, reg_types_.Byte(), true); 2813 break; 2814 case Instruction::APUT_CHAR: 2815 VerifyAPut(inst, reg_types_.Char(), true); 2816 break; 2817 case Instruction::APUT_SHORT: 2818 VerifyAPut(inst, reg_types_.Short(), true); 2819 break; 2820 case Instruction::APUT: 2821 VerifyAPut(inst, reg_types_.Integer(), true); 2822 break; 2823 case Instruction::APUT_WIDE: 2824 VerifyAPut(inst, reg_types_.LongLo(), true); 2825 break; 2826 case Instruction::APUT_OBJECT: 2827 VerifyAPut(inst, reg_types_.JavaLangObject(false), false); 2828 break; 2829 2830 case Instruction::IGET_BOOLEAN: 2831 case Instruction::IGET_BOOLEAN_QUICK: 2832 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, false); 2833 break; 2834 case Instruction::IGET_BYTE: 2835 case Instruction::IGET_BYTE_QUICK: 2836 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, false); 2837 break; 2838 case Instruction::IGET_CHAR: 2839 case Instruction::IGET_CHAR_QUICK: 2840 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, false); 2841 break; 2842 case Instruction::IGET_SHORT: 2843 case Instruction::IGET_SHORT_QUICK: 2844 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, false); 2845 break; 2846 case Instruction::IGET: 2847 case Instruction::IGET_QUICK: 2848 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, false); 2849 break; 2850 case Instruction::IGET_WIDE: 2851 case Instruction::IGET_WIDE_QUICK: 2852 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, false); 2853 break; 2854 case Instruction::IGET_OBJECT: 2855 case Instruction::IGET_OBJECT_QUICK: 2856 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false, 2857 false); 2858 break; 2859 2860 case Instruction::IPUT_BOOLEAN: 2861 case Instruction::IPUT_BOOLEAN_QUICK: 2862 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, false); 2863 break; 2864 case Instruction::IPUT_BYTE: 2865 case Instruction::IPUT_BYTE_QUICK: 2866 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, false); 2867 break; 2868 case Instruction::IPUT_CHAR: 2869 case Instruction::IPUT_CHAR_QUICK: 2870 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, false); 2871 break; 2872 case Instruction::IPUT_SHORT: 2873 case Instruction::IPUT_SHORT_QUICK: 2874 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, false); 2875 break; 2876 case Instruction::IPUT: 2877 case Instruction::IPUT_QUICK: 2878 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, false); 2879 break; 2880 case Instruction::IPUT_WIDE: 2881 case Instruction::IPUT_WIDE_QUICK: 2882 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, false); 2883 break; 2884 case Instruction::IPUT_OBJECT: 2885 case Instruction::IPUT_OBJECT_QUICK: 2886 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false, 2887 false); 2888 break; 2889 2890 case Instruction::SGET_BOOLEAN: 2891 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, true); 2892 break; 2893 case Instruction::SGET_BYTE: 2894 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, true); 2895 break; 2896 case Instruction::SGET_CHAR: 2897 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, true); 2898 break; 2899 case Instruction::SGET_SHORT: 2900 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, true); 2901 break; 2902 case Instruction::SGET: 2903 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, true); 2904 break; 2905 case Instruction::SGET_WIDE: 2906 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, true); 2907 break; 2908 case Instruction::SGET_OBJECT: 2909 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false, 2910 true); 2911 break; 2912 2913 case Instruction::SPUT_BOOLEAN: 2914 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, true); 2915 break; 2916 case Instruction::SPUT_BYTE: 2917 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, true); 2918 break; 2919 case Instruction::SPUT_CHAR: 2920 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, true); 2921 break; 2922 case Instruction::SPUT_SHORT: 2923 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, true); 2924 break; 2925 case Instruction::SPUT: 2926 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, true); 2927 break; 2928 case Instruction::SPUT_WIDE: 2929 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, true); 2930 break; 2931 case Instruction::SPUT_OBJECT: 2932 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false, 2933 true); 2934 break; 2935 2936 case Instruction::INVOKE_VIRTUAL: 2937 case Instruction::INVOKE_VIRTUAL_RANGE: 2938 case Instruction::INVOKE_SUPER: 2939 case Instruction::INVOKE_SUPER_RANGE: 2940 case Instruction::INVOKE_VIRTUAL_QUICK: 2941 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 2942 bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE || 2943 inst->Opcode() == Instruction::INVOKE_SUPER_RANGE || 2944 inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK); 2945 bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER || 2946 inst->Opcode() == Instruction::INVOKE_SUPER_RANGE); 2947 MethodType type = is_super ? METHOD_SUPER : METHOD_VIRTUAL; 2948 ArtMethod* called_method = VerifyInvocationArgs(inst, type, is_range); 2949 const RegType* return_type = nullptr; 2950 if (called_method != nullptr) { 2951 ObjPtr<mirror::Class> return_type_class = can_load_classes_ 2952 ? called_method->ResolveReturnType() 2953 : called_method->LookupResolvedReturnType(); 2954 if (return_type_class != nullptr) { 2955 return_type = &FromClass(called_method->GetReturnTypeDescriptor(), 2956 return_type_class, 2957 return_type_class->CannotBeAssignedFromOtherTypes()); 2958 } else { 2959 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 2960 self_->ClearException(); 2961 } 2962 } 2963 if (return_type == nullptr) { 2964 uint32_t method_idx = GetMethodIdxOfInvoke(inst); 2965 const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx); 2966 dex::TypeIndex return_type_idx = 2967 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 2968 const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); 2969 return_type = ®_types_.FromDescriptor(class_loader_.Get(), descriptor, false); 2970 } 2971 if (!return_type->IsLowHalf()) { 2972 work_line_->SetResultRegisterType(this, *return_type); 2973 } else { 2974 work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(®_types_)); 2975 } 2976 just_set_result = true; 2977 break; 2978 } 2979 case Instruction::INVOKE_DIRECT: 2980 case Instruction::INVOKE_DIRECT_RANGE: { 2981 bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE); 2982 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, is_range); 2983 const char* return_type_descriptor; 2984 bool is_constructor; 2985 const RegType* return_type = nullptr; 2986 if (called_method == nullptr) { 2987 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 2988 const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx); 2989 is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0; 2990 dex::TypeIndex return_type_idx = 2991 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 2992 return_type_descriptor = dex_file_->StringByTypeIdx(return_type_idx); 2993 } else { 2994 is_constructor = called_method->IsConstructor(); 2995 return_type_descriptor = called_method->GetReturnTypeDescriptor(); 2996 ObjPtr<mirror::Class> return_type_class = can_load_classes_ 2997 ? called_method->ResolveReturnType() 2998 : called_method->LookupResolvedReturnType(); 2999 if (return_type_class != nullptr) { 3000 return_type = &FromClass(return_type_descriptor, 3001 return_type_class, 3002 return_type_class->CannotBeAssignedFromOtherTypes()); 3003 } else { 3004 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 3005 self_->ClearException(); 3006 } 3007 } 3008 if (is_constructor) { 3009 /* 3010 * Some additional checks when calling a constructor. We know from the invocation arg check 3011 * that the "this" argument is an instance of called_method->klass. Now we further restrict 3012 * that to require that called_method->klass is the same as this->klass or this->super, 3013 * allowing the latter only if the "this" argument is the same as the "this" argument to 3014 * this method (which implies that we're in a constructor ourselves). 3015 */ 3016 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 3017 if (this_type.IsConflict()) // failure. 3018 break; 3019 3020 /* no null refs allowed (?) */ 3021 if (this_type.IsZeroOrNull()) { 3022 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref"; 3023 break; 3024 } 3025 3026 /* must be in same class or in superclass */ 3027 // const RegType& this_super_klass = this_type.GetSuperClass(®_types_); 3028 // TODO: re-enable constructor type verification 3029 // if (this_super_klass.IsConflict()) { 3030 // Unknown super class, fail so we re-check at runtime. 3031 // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'"; 3032 // break; 3033 // } 3034 3035 /* arg must be an uninitialized reference */ 3036 if (!this_type.IsUninitializedTypes()) { 3037 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference " 3038 << this_type; 3039 break; 3040 } 3041 3042 /* 3043 * Replace the uninitialized reference with an initialized one. We need to do this for all 3044 * registers that have the same object instance in them, not just the "this" register. 3045 */ 3046 work_line_->MarkRefsAsInitialized(this, this_type); 3047 } 3048 if (return_type == nullptr) { 3049 return_type = ®_types_.FromDescriptor(class_loader_.Get(), 3050 return_type_descriptor, 3051 false); 3052 } 3053 if (!return_type->IsLowHalf()) { 3054 work_line_->SetResultRegisterType(this, *return_type); 3055 } else { 3056 work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(®_types_)); 3057 } 3058 just_set_result = true; 3059 break; 3060 } 3061 case Instruction::INVOKE_STATIC: 3062 case Instruction::INVOKE_STATIC_RANGE: { 3063 bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE); 3064 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_STATIC, is_range); 3065 const char* descriptor; 3066 if (called_method == nullptr) { 3067 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 3068 const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx); 3069 dex::TypeIndex return_type_idx = 3070 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 3071 descriptor = dex_file_->StringByTypeIdx(return_type_idx); 3072 } else { 3073 descriptor = called_method->GetReturnTypeDescriptor(); 3074 } 3075 const RegType& return_type = reg_types_.FromDescriptor(class_loader_.Get(), 3076 descriptor, 3077 false); 3078 if (!return_type.IsLowHalf()) { 3079 work_line_->SetResultRegisterType(this, return_type); 3080 } else { 3081 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3082 } 3083 just_set_result = true; 3084 } 3085 break; 3086 case Instruction::INVOKE_INTERFACE: 3087 case Instruction::INVOKE_INTERFACE_RANGE: { 3088 bool is_range = (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE); 3089 ArtMethod* abs_method = VerifyInvocationArgs(inst, METHOD_INTERFACE, is_range); 3090 if (abs_method != nullptr) { 3091 ObjPtr<mirror::Class> called_interface = abs_method->GetDeclaringClass(); 3092 if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) { 3093 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '" 3094 << abs_method->PrettyMethod() << "'"; 3095 break; 3096 } 3097 } 3098 /* Get the type of the "this" arg, which should either be a sub-interface of called 3099 * interface or Object (see comments in RegType::JoinClass). 3100 */ 3101 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 3102 if (this_type.IsZeroOrNull()) { 3103 /* null pointer always passes (and always fails at runtime) */ 3104 } else { 3105 if (this_type.IsUninitializedTypes()) { 3106 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object " 3107 << this_type; 3108 break; 3109 } 3110 // In the past we have tried to assert that "called_interface" is assignable 3111 // from "this_type.GetClass()", however, as we do an imprecise Join 3112 // (RegType::JoinClass) we don't have full information on what interfaces are 3113 // implemented by "this_type". For example, two classes may implement the same 3114 // interfaces and have a common parent that doesn't implement the interface. The 3115 // join will set "this_type" to the parent class and a test that this implements 3116 // the interface will incorrectly fail. 3117 } 3118 /* 3119 * We don't have an object instance, so we can't find the concrete method. However, all of 3120 * the type information is in the abstract method, so we're good. 3121 */ 3122 const char* descriptor; 3123 if (abs_method == nullptr) { 3124 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 3125 const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx); 3126 dex::TypeIndex return_type_idx = 3127 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 3128 descriptor = dex_file_->StringByTypeIdx(return_type_idx); 3129 } else { 3130 descriptor = abs_method->GetReturnTypeDescriptor(); 3131 } 3132 const RegType& return_type = reg_types_.FromDescriptor(class_loader_.Get(), 3133 descriptor, 3134 false); 3135 if (!return_type.IsLowHalf()) { 3136 work_line_->SetResultRegisterType(this, return_type); 3137 } else { 3138 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3139 } 3140 just_set_result = true; 3141 break; 3142 } 3143 case Instruction::INVOKE_POLYMORPHIC: 3144 case Instruction::INVOKE_POLYMORPHIC_RANGE: { 3145 bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE); 3146 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_POLYMORPHIC, is_range); 3147 if (called_method == nullptr) { 3148 // Convert potential soft failures in VerifyInvocationArgs() to hard errors. 3149 if (failure_messages_.size() > 0) { 3150 std::string message = failure_messages_.back()->str(); 3151 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << message; 3152 } else { 3153 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-polymorphic verification failure."; 3154 } 3155 break; 3156 } 3157 if (!CheckSignaturePolymorphicMethod(called_method) || 3158 !CheckSignaturePolymorphicReceiver(inst)) { 3159 DCHECK(HasFailures()); 3160 break; 3161 } 3162 const uint16_t vRegH = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc(); 3163 const dex::ProtoIndex proto_idx(vRegH); 3164 const char* return_descriptor = 3165 dex_file_->GetReturnTypeDescriptor(dex_file_->GetProtoId(proto_idx)); 3166 const RegType& return_type = 3167 reg_types_.FromDescriptor(class_loader_.Get(), return_descriptor, false); 3168 if (!return_type.IsLowHalf()) { 3169 work_line_->SetResultRegisterType(this, return_type); 3170 } else { 3171 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3172 } 3173 just_set_result = true; 3174 break; 3175 } 3176 case Instruction::INVOKE_CUSTOM: 3177 case Instruction::INVOKE_CUSTOM_RANGE: { 3178 // Verify registers based on method_type in the call site. 3179 bool is_range = (inst->Opcode() == Instruction::INVOKE_CUSTOM_RANGE); 3180 3181 // Step 1. Check the call site that produces the method handle for invocation 3182 const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); 3183 if (!CheckCallSite(call_site_idx)) { 3184 DCHECK(HasFailures()); 3185 break; 3186 } 3187 3188 // Step 2. Check the register arguments correspond to the expected arguments for the 3189 // method handle produced by step 1. The dex file verifier has checked ranges for 3190 // the first three arguments and CheckCallSite has checked the method handle type. 3191 const dex::ProtoIndex proto_idx = dex_file_->GetProtoIndexForCallSite(call_site_idx); 3192 const dex::ProtoId& proto_id = dex_file_->GetProtoId(proto_idx); 3193 DexFileParameterIterator param_it(*dex_file_, proto_id); 3194 // Treat method as static as it has yet to be determined. 3195 VerifyInvocationArgsFromIterator(¶m_it, inst, METHOD_STATIC, is_range, nullptr); 3196 const char* return_descriptor = dex_file_->GetReturnTypeDescriptor(proto_id); 3197 3198 // Step 3. Propagate return type information 3199 const RegType& return_type = 3200 reg_types_.FromDescriptor(class_loader_.Get(), return_descriptor, false); 3201 if (!return_type.IsLowHalf()) { 3202 work_line_->SetResultRegisterType(this, return_type); 3203 } else { 3204 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3205 } 3206 just_set_result = true; 3207 break; 3208 } 3209 case Instruction::NEG_INT: 3210 case Instruction::NOT_INT: 3211 work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer()); 3212 break; 3213 case Instruction::NEG_LONG: 3214 case Instruction::NOT_LONG: 3215 work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3216 reg_types_.LongLo(), reg_types_.LongHi()); 3217 break; 3218 case Instruction::NEG_FLOAT: 3219 work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Float()); 3220 break; 3221 case Instruction::NEG_DOUBLE: 3222 work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3223 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3224 break; 3225 case Instruction::INT_TO_LONG: 3226 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3227 reg_types_.Integer()); 3228 break; 3229 case Instruction::INT_TO_FLOAT: 3230 work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Integer()); 3231 break; 3232 case Instruction::INT_TO_DOUBLE: 3233 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3234 reg_types_.Integer()); 3235 break; 3236 case Instruction::LONG_TO_INT: 3237 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(), 3238 reg_types_.LongLo(), reg_types_.LongHi()); 3239 break; 3240 case Instruction::LONG_TO_FLOAT: 3241 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(), 3242 reg_types_.LongLo(), reg_types_.LongHi()); 3243 break; 3244 case Instruction::LONG_TO_DOUBLE: 3245 work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3246 reg_types_.LongLo(), reg_types_.LongHi()); 3247 break; 3248 case Instruction::FLOAT_TO_INT: 3249 work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Float()); 3250 break; 3251 case Instruction::FLOAT_TO_LONG: 3252 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3253 reg_types_.Float()); 3254 break; 3255 case Instruction::FLOAT_TO_DOUBLE: 3256 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3257 reg_types_.Float()); 3258 break; 3259 case Instruction::DOUBLE_TO_INT: 3260 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(), 3261 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3262 break; 3263 case Instruction::DOUBLE_TO_LONG: 3264 work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3265 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3266 break; 3267 case Instruction::DOUBLE_TO_FLOAT: 3268 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(), 3269 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3270 break; 3271 case Instruction::INT_TO_BYTE: 3272 work_line_->CheckUnaryOp(this, inst, reg_types_.Byte(), reg_types_.Integer()); 3273 break; 3274 case Instruction::INT_TO_CHAR: 3275 work_line_->CheckUnaryOp(this, inst, reg_types_.Char(), reg_types_.Integer()); 3276 break; 3277 case Instruction::INT_TO_SHORT: 3278 work_line_->CheckUnaryOp(this, inst, reg_types_.Short(), reg_types_.Integer()); 3279 break; 3280 3281 case Instruction::ADD_INT: 3282 case Instruction::SUB_INT: 3283 case Instruction::MUL_INT: 3284 case Instruction::REM_INT: 3285 case Instruction::DIV_INT: 3286 case Instruction::SHL_INT: 3287 case Instruction::SHR_INT: 3288 case Instruction::USHR_INT: 3289 work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3290 reg_types_.Integer(), false); 3291 break; 3292 case Instruction::AND_INT: 3293 case Instruction::OR_INT: 3294 case Instruction::XOR_INT: 3295 work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3296 reg_types_.Integer(), true); 3297 break; 3298 case Instruction::ADD_LONG: 3299 case Instruction::SUB_LONG: 3300 case Instruction::MUL_LONG: 3301 case Instruction::DIV_LONG: 3302 case Instruction::REM_LONG: 3303 case Instruction::AND_LONG: 3304 case Instruction::OR_LONG: 3305 case Instruction::XOR_LONG: 3306 work_line_->CheckBinaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3307 reg_types_.LongLo(), reg_types_.LongHi(), 3308 reg_types_.LongLo(), reg_types_.LongHi()); 3309 break; 3310 case Instruction::SHL_LONG: 3311 case Instruction::SHR_LONG: 3312 case Instruction::USHR_LONG: 3313 /* shift distance is Int, making these different from other binary operations */ 3314 work_line_->CheckBinaryOpWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3315 reg_types_.Integer()); 3316 break; 3317 case Instruction::ADD_FLOAT: 3318 case Instruction::SUB_FLOAT: 3319 case Instruction::MUL_FLOAT: 3320 case Instruction::DIV_FLOAT: 3321 case Instruction::REM_FLOAT: 3322 work_line_->CheckBinaryOp(this, inst, reg_types_.Float(), reg_types_.Float(), 3323 reg_types_.Float(), false); 3324 break; 3325 case Instruction::ADD_DOUBLE: 3326 case Instruction::SUB_DOUBLE: 3327 case Instruction::MUL_DOUBLE: 3328 case Instruction::DIV_DOUBLE: 3329 case Instruction::REM_DOUBLE: 3330 work_line_->CheckBinaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3331 reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3332 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3333 break; 3334 case Instruction::ADD_INT_2ADDR: 3335 case Instruction::SUB_INT_2ADDR: 3336 case Instruction::MUL_INT_2ADDR: 3337 case Instruction::REM_INT_2ADDR: 3338 case Instruction::SHL_INT_2ADDR: 3339 case Instruction::SHR_INT_2ADDR: 3340 case Instruction::USHR_INT_2ADDR: 3341 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3342 reg_types_.Integer(), false); 3343 break; 3344 case Instruction::AND_INT_2ADDR: 3345 case Instruction::OR_INT_2ADDR: 3346 case Instruction::XOR_INT_2ADDR: 3347 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3348 reg_types_.Integer(), true); 3349 break; 3350 case Instruction::DIV_INT_2ADDR: 3351 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3352 reg_types_.Integer(), false); 3353 break; 3354 case Instruction::ADD_LONG_2ADDR: 3355 case Instruction::SUB_LONG_2ADDR: 3356 case Instruction::MUL_LONG_2ADDR: 3357 case Instruction::DIV_LONG_2ADDR: 3358 case Instruction::REM_LONG_2ADDR: 3359 case Instruction::AND_LONG_2ADDR: 3360 case Instruction::OR_LONG_2ADDR: 3361 case Instruction::XOR_LONG_2ADDR: 3362 work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3363 reg_types_.LongLo(), reg_types_.LongHi(), 3364 reg_types_.LongLo(), reg_types_.LongHi()); 3365 break; 3366 case Instruction::SHL_LONG_2ADDR: 3367 case Instruction::SHR_LONG_2ADDR: 3368 case Instruction::USHR_LONG_2ADDR: 3369 work_line_->CheckBinaryOp2addrWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3370 reg_types_.Integer()); 3371 break; 3372 case Instruction::ADD_FLOAT_2ADDR: 3373 case Instruction::SUB_FLOAT_2ADDR: 3374 case Instruction::MUL_FLOAT_2ADDR: 3375 case Instruction::DIV_FLOAT_2ADDR: 3376 case Instruction::REM_FLOAT_2ADDR: 3377 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Float(), reg_types_.Float(), 3378 reg_types_.Float(), false); 3379 break; 3380 case Instruction::ADD_DOUBLE_2ADDR: 3381 case Instruction::SUB_DOUBLE_2ADDR: 3382 case Instruction::MUL_DOUBLE_2ADDR: 3383 case Instruction::DIV_DOUBLE_2ADDR: 3384 case Instruction::REM_DOUBLE_2ADDR: 3385 work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3386 reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3387 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3388 break; 3389 case Instruction::ADD_INT_LIT16: 3390 case Instruction::RSUB_INT_LIT16: 3391 case Instruction::MUL_INT_LIT16: 3392 case Instruction::DIV_INT_LIT16: 3393 case Instruction::REM_INT_LIT16: 3394 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false, 3395 true); 3396 break; 3397 case Instruction::AND_INT_LIT16: 3398 case Instruction::OR_INT_LIT16: 3399 case Instruction::XOR_INT_LIT16: 3400 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true, 3401 true); 3402 break; 3403 case Instruction::ADD_INT_LIT8: 3404 case Instruction::RSUB_INT_LIT8: 3405 case Instruction::MUL_INT_LIT8: 3406 case Instruction::DIV_INT_LIT8: 3407 case Instruction::REM_INT_LIT8: 3408 case Instruction::SHL_INT_LIT8: 3409 case Instruction::SHR_INT_LIT8: 3410 case Instruction::USHR_INT_LIT8: 3411 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false, 3412 false); 3413 break; 3414 case Instruction::AND_INT_LIT8: 3415 case Instruction::OR_INT_LIT8: 3416 case Instruction::XOR_INT_LIT8: 3417 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true, 3418 false); 3419 break; 3420 3421 // Special instructions. 3422 case Instruction::RETURN_VOID_NO_BARRIER: 3423 if (IsConstructor() && !IsStatic()) { 3424 const RegType& declaring_class = GetDeclaringClass(); 3425 if (declaring_class.IsUnresolvedReference()) { 3426 // We must iterate over the fields, even if we cannot use mirror classes to do so. Do it 3427 // manually over the underlying dex file. 3428 uint32_t first_index = GetFirstFinalInstanceFieldIndex(*dex_file_, 3429 dex_file_->GetMethodId(dex_method_idx_).class_idx_); 3430 if (first_index != dex::kDexNoIndex) { 3431 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for field " 3432 << first_index; 3433 } 3434 break; 3435 } 3436 ObjPtr<mirror::Class> klass = declaring_class.GetClass(); 3437 for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) { 3438 if (klass->GetInstanceField(i)->IsFinal()) { 3439 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for " 3440 << klass->GetInstanceField(i)->PrettyField(); 3441 break; 3442 } 3443 } 3444 } 3445 // Handle this like a RETURN_VOID now. Code is duplicated to separate standard from 3446 // quickened opcodes (otherwise this could be a fall-through). 3447 if (!IsConstructor()) { 3448 if (!GetMethodReturnType().IsConflict()) { 3449 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected"; 3450 } 3451 } 3452 break; 3453 3454 /* These should never appear during verification. */ 3455 case Instruction::UNUSED_3E ... Instruction::UNUSED_43: 3456 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9: 3457 case Instruction::UNUSED_79: 3458 case Instruction::UNUSED_7A: 3459 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_); 3460 break; 3461 3462 /* 3463 * DO NOT add a "default" clause here. Without it the compiler will 3464 * complain if an instruction is missing (which is desirable). 3465 */ 3466 } // end - switch (dec_insn.opcode) 3467 3468 if (have_pending_hard_failure_) { 3469 if (Runtime::Current()->IsAotCompiler()) { 3470 /* When AOT compiling, check that the last failure is a hard failure */ 3471 if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) { 3472 LOG(ERROR) << "Pending failures:"; 3473 for (auto& error : failures_) { 3474 LOG(ERROR) << error; 3475 } 3476 for (auto& error_msg : failure_messages_) { 3477 LOG(ERROR) << error_msg->str(); 3478 } 3479 LOG(FATAL) << "Pending hard failure, but last failure not hard."; 3480 } 3481 } 3482 /* immediate failure, reject class */ 3483 info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_); 3484 return false; 3485 } else if (have_pending_runtime_throw_failure_) { 3486 /* checking interpreter will throw, mark following code as unreachable */ 3487 opcode_flags = Instruction::kThrow; 3488 // Note: the flag must be reset as it is only global to decouple Fail and is semantically per 3489 // instruction. However, RETURN checking may throw LOCKING errors, so we clear at the 3490 // very end. 3491 } 3492 /* 3493 * If we didn't just set the result register, clear it out. This ensures that you can only use 3494 * "move-result" immediately after the result is set. (We could check this statically, but it's 3495 * not expensive and it makes our debugging output cleaner.) 3496 */ 3497 if (!just_set_result) { 3498 work_line_->SetResultTypeToUnknown(GetRegTypeCache()); 3499 } 3500 3501 /* 3502 * Handle "branch". Tag the branch target. 3503 * 3504 * NOTE: instructions like Instruction::EQZ provide information about the 3505 * state of the register when the branch is taken or not taken. For example, 3506 * somebody could get a reference field, check it for zero, and if the 3507 * branch is taken immediately store that register in a boolean field 3508 * since the value is known to be zero. We do not currently account for 3509 * that, and will reject the code. 3510 * 3511 * TODO: avoid re-fetching the branch target 3512 */ 3513 if ((opcode_flags & Instruction::kBranch) != 0) { 3514 bool isConditional, selfOkay; 3515 if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) { 3516 /* should never happen after static verification */ 3517 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch"; 3518 return false; 3519 } 3520 DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0); 3521 if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(), 3522 work_insn_idx_ + branch_target)) { 3523 return false; 3524 } 3525 /* update branch target, set "changed" if appropriate */ 3526 if (nullptr != branch_line) { 3527 if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) { 3528 return false; 3529 } 3530 } else { 3531 if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) { 3532 return false; 3533 } 3534 } 3535 } 3536 3537 /* 3538 * Handle "switch". Tag all possible branch targets. 3539 * 3540 * We've already verified that the table is structurally sound, so we 3541 * just need to walk through and tag the targets. 3542 */ 3543 if ((opcode_flags & Instruction::kSwitch) != 0) { 3544 int offset_to_switch = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 3545 const uint16_t* switch_insns = insns + offset_to_switch; 3546 int switch_count = switch_insns[1]; 3547 int offset_to_targets, targ; 3548 3549 if ((*insns & 0xff) == Instruction::PACKED_SWITCH) { 3550 /* 0 = sig, 1 = count, 2/3 = first key */ 3551 offset_to_targets = 4; 3552 } else { 3553 /* 0 = sig, 1 = count, 2..count * 2 = keys */ 3554 DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH); 3555 offset_to_targets = 2 + 2 * switch_count; 3556 } 3557 3558 /* verify each switch target */ 3559 for (targ = 0; targ < switch_count; targ++) { 3560 int offset; 3561 uint32_t abs_offset; 3562 3563 /* offsets are 32-bit, and only partly endian-swapped */ 3564 offset = switch_insns[offset_to_targets + targ * 2] | 3565 (static_cast<int32_t>(switch_insns[offset_to_targets + targ * 2 + 1]) << 16); 3566 abs_offset = work_insn_idx_ + offset; 3567 DCHECK_LT(abs_offset, code_item_accessor_.InsnsSizeInCodeUnits()); 3568 if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(), abs_offset)) { 3569 return false; 3570 } 3571 if (!UpdateRegisters(abs_offset, work_line_.get(), false)) { 3572 return false; 3573 } 3574 } 3575 } 3576 3577 /* 3578 * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a 3579 * "try" block when they throw, control transfers out of the method.) 3580 */ 3581 if ((opcode_flags & Instruction::kThrow) != 0 && GetInstructionFlags(work_insn_idx_).IsInTry()) { 3582 bool has_catch_all_handler = false; 3583 const dex::TryItem* try_item = code_item_accessor_.FindTryItem(work_insn_idx_); 3584 CHECK(try_item != nullptr); 3585 CatchHandlerIterator iterator(code_item_accessor_, *try_item); 3586 3587 // Need the linker to try and resolve the handled class to check if it's Throwable. 3588 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3589 3590 for (; iterator.HasNext(); iterator.Next()) { 3591 dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex(); 3592 if (!handler_type_idx.IsValid()) { 3593 has_catch_all_handler = true; 3594 } else { 3595 // It is also a catch-all if it is java.lang.Throwable. 3596 ObjPtr<mirror::Class> klass = 3597 linker->ResolveType(handler_type_idx, dex_cache_, class_loader_); 3598 if (klass != nullptr) { 3599 if (klass == GetClassRoot<mirror::Throwable>()) { 3600 has_catch_all_handler = true; 3601 } 3602 } else { 3603 // Clear exception. 3604 DCHECK(self_->IsExceptionPending()); 3605 self_->ClearException(); 3606 } 3607 } 3608 /* 3609 * Merge registers into the "catch" block. We want to use the "savedRegs" rather than 3610 * "work_regs", because at runtime the exception will be thrown before the instruction 3611 * modifies any registers. 3612 */ 3613 if (kVerifierDebug) { 3614 LogVerifyInfo() << "Updating exception handler 0x" 3615 << std::hex << iterator.GetHandlerAddress(); 3616 } 3617 if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) { 3618 return false; 3619 } 3620 } 3621 3622 /* 3623 * If the monitor stack depth is nonzero, there must be a "catch all" handler for this 3624 * instruction. This does apply to monitor-exit because of async exception handling. 3625 */ 3626 if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) { 3627 /* 3628 * The state in work_line reflects the post-execution state. If the current instruction is a 3629 * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws, 3630 * it will do so before grabbing the lock). 3631 */ 3632 if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) { 3633 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 3634 << "expected to be within a catch-all for an instruction where a monitor is held"; 3635 return false; 3636 } 3637 } 3638 } 3639 3640 /* Handle "continue". Tag the next consecutive instruction. 3641 * Note: Keep the code handling "continue" case below the "branch" and "switch" cases, 3642 * because it changes work_line_ when performing peephole optimization 3643 * and this change should not be used in those cases. 3644 */ 3645 if ((opcode_flags & Instruction::kContinue) != 0) { 3646 DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst); 3647 uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits(); 3648 if (next_insn_idx >= code_item_accessor_.InsnsSizeInCodeUnits()) { 3649 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area"; 3650 return false; 3651 } 3652 // The only way to get to a move-exception instruction is to get thrown there. Make sure the 3653 // next instruction isn't one. 3654 if (!CheckNotMoveException(code_item_accessor_.Insns(), next_insn_idx)) { 3655 return false; 3656 } 3657 if (nullptr != fallthrough_line) { 3658 // Make workline consistent with fallthrough computed from peephole optimization. 3659 work_line_->CopyFromLine(fallthrough_line.get()); 3660 } 3661 if (GetInstructionFlags(next_insn_idx).IsReturn()) { 3662 // For returns we only care about the operand to the return, all other registers are dead. 3663 const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn_idx); 3664 AdjustReturnLine(this, ret_inst, work_line_.get()); 3665 } 3666 RegisterLine* next_line = reg_table_.GetLine(next_insn_idx); 3667 if (next_line != nullptr) { 3668 // Merge registers into what we have for the next instruction, and set the "changed" flag if 3669 // needed. If the merge changes the state of the registers then the work line will be 3670 // updated. 3671 if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) { 3672 return false; 3673 } 3674 } else { 3675 /* 3676 * We're not recording register data for the next instruction, so we don't know what the 3677 * prior state was. We have to assume that something has changed and re-evaluate it. 3678 */ 3679 GetModifiableInstructionFlags(next_insn_idx).SetChanged(); 3680 } 3681 } 3682 3683 /* If we're returning from the method, make sure monitor stack is empty. */ 3684 if ((opcode_flags & Instruction::kReturn) != 0) { 3685 work_line_->VerifyMonitorStackEmpty(this); 3686 } 3687 3688 /* 3689 * Update start_guess. Advance to the next instruction of that's 3690 * possible, otherwise use the branch target if one was found. If 3691 * neither of those exists we're in a return or throw; leave start_guess 3692 * alone and let the caller sort it out. 3693 */ 3694 if ((opcode_flags & Instruction::kContinue) != 0) { 3695 DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst); 3696 *start_guess = work_insn_idx_ + inst->SizeInCodeUnits(); 3697 } else if ((opcode_flags & Instruction::kBranch) != 0) { 3698 /* we're still okay if branch_target is zero */ 3699 *start_guess = work_insn_idx_ + branch_target; 3700 } 3701 3702 DCHECK_LT(*start_guess, code_item_accessor_.InsnsSizeInCodeUnits()); 3703 DCHECK(GetInstructionFlags(*start_guess).IsOpcode()); 3704 3705 if (have_pending_runtime_throw_failure_) { 3706 have_any_pending_runtime_throw_failure_ = true; 3707 // Reset the pending_runtime_throw flag now. 3708 have_pending_runtime_throw_failure_ = false; 3709 } 3710 3711 return true; 3712 } // NOLINT(readability/fn_size) 3713 3714 template <bool kVerifierDebug> 3715 template <CheckAccess C> 3716 const RegType& MethodVerifier<kVerifierDebug>::ResolveClass(dex::TypeIndex class_idx) { 3717 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3718 ObjPtr<mirror::Class> klass = can_load_classes_ 3719 ? linker->ResolveType(class_idx, dex_cache_, class_loader_) 3720 : linker->LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()); 3721 if (can_load_classes_ && klass == nullptr) { 3722 DCHECK(self_->IsExceptionPending()); 3723 self_->ClearException(); 3724 } 3725 const RegType* result = nullptr; 3726 if (klass != nullptr) { 3727 bool precise = klass->CannotBeAssignedFromOtherTypes(); 3728 if (precise && !IsInstantiableOrPrimitive(klass)) { 3729 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3730 UninstantiableError(descriptor); 3731 precise = false; 3732 } 3733 result = reg_types_.FindClass(klass, precise); 3734 if (result == nullptr) { 3735 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3736 result = reg_types_.InsertClass(descriptor, klass, precise); 3737 } 3738 } else { 3739 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3740 result = ®_types_.FromDescriptor(class_loader_.Get(), descriptor, false); 3741 } 3742 DCHECK(result != nullptr); 3743 if (result->IsConflict()) { 3744 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3745 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor 3746 << "' in " << GetDeclaringClass(); 3747 return *result; 3748 } 3749 3750 // Record result of class resolution attempt. 3751 VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass); 3752 3753 // If requested, check if access is allowed. Unresolved types are included in this check, as the 3754 // interpreter only tests whether access is allowed when a class is not pre-verified and runs in 3755 // the access-checks interpreter. If result is primitive, skip the access check. 3756 // 3757 // Note: we do this for unresolved classes to trigger re-verification at runtime. 3758 if (C == CheckAccess::kYes && 3759 result->IsNonZeroReferenceTypes() && 3760 (IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP) || !result->IsUnresolvedTypes())) { 3761 const RegType& referrer = GetDeclaringClass(); 3762 if ((IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP) || !referrer.IsUnresolvedTypes()) && 3763 !referrer.CanAccess(*result)) { 3764 Fail(VERIFY_ERROR_ACCESS_CLASS) << "(possibly) illegal class access: '" 3765 << referrer << "' -> '" << *result << "'"; 3766 } 3767 } 3768 return *result; 3769 } 3770 3771 template <bool kVerifierDebug> 3772 const RegType& MethodVerifier<kVerifierDebug>::GetCaughtExceptionType() { 3773 const RegType* common_super = nullptr; 3774 if (code_item_accessor_.TriesSize() != 0) { 3775 const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData(); 3776 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 3777 for (uint32_t i = 0; i < handlers_size; i++) { 3778 CatchHandlerIterator iterator(handlers_ptr); 3779 for (; iterator.HasNext(); iterator.Next()) { 3780 if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) { 3781 if (!iterator.GetHandlerTypeIndex().IsValid()) { 3782 common_super = ®_types_.JavaLangThrowable(false); 3783 } else { 3784 const RegType& exception = 3785 ResolveClass<CheckAccess::kYes>(iterator.GetHandlerTypeIndex()); 3786 if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception, this)) { 3787 DCHECK(!exception.IsUninitializedTypes()); // Comes from dex, shouldn't be uninit. 3788 if (exception.IsUnresolvedTypes()) { 3789 // We don't know enough about the type. Fail here and let runtime handle it. 3790 Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception; 3791 return exception; 3792 } else { 3793 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception; 3794 return reg_types_.Conflict(); 3795 } 3796 } else if (common_super == nullptr) { 3797 common_super = &exception; 3798 } else if (common_super->Equals(exception)) { 3799 // odd case, but nothing to do 3800 } else { 3801 common_super = &common_super->Merge(exception, ®_types_, this); 3802 if (FailOrAbort(reg_types_.JavaLangThrowable(false).IsAssignableFrom( 3803 *common_super, this), 3804 "java.lang.Throwable is not assignable-from common_super at ", 3805 work_insn_idx_)) { 3806 break; 3807 } 3808 } 3809 } 3810 } 3811 } 3812 handlers_ptr = iterator.EndDataPointer(); 3813 } 3814 } 3815 if (common_super == nullptr) { 3816 /* no catch blocks, or no catches with classes we can find */ 3817 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler"; 3818 return reg_types_.Conflict(); 3819 } 3820 return *common_super; 3821 } 3822 3823 template <bool kVerifierDebug> 3824 ArtMethod* MethodVerifier<kVerifierDebug>::ResolveMethodAndCheckAccess( 3825 uint32_t dex_method_idx, MethodType method_type) { 3826 const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx); 3827 const RegType& klass_type = ResolveClass<CheckAccess::kYes>(method_id.class_idx_); 3828 if (klass_type.IsConflict()) { 3829 std::string append(" in attempt to access method "); 3830 append += dex_file_->GetMethodName(method_id); 3831 AppendToLastFailMessage(append); 3832 return nullptr; 3833 } 3834 if (klass_type.IsUnresolvedTypes()) { 3835 return nullptr; // Can't resolve Class so no more to do here 3836 } 3837 ObjPtr<mirror::Class> klass = klass_type.GetClass(); 3838 const RegType& referrer = GetDeclaringClass(); 3839 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 3840 PointerSize pointer_size = class_linker->GetImagePointerSize(); 3841 3842 ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx, pointer_size); 3843 if (res_method == nullptr) { 3844 res_method = class_linker->FindResolvedMethod( 3845 klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx); 3846 } 3847 3848 // Record result of method resolution attempt. The klass resolution has recorded whether 3849 // the class is an interface or not and therefore the type of the lookup performed above. 3850 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type. 3851 VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_method); 3852 3853 bool must_fail = false; 3854 // This is traditional and helps with screwy bytecode. It will tell you that, yes, a method 3855 // exists, but that it's called incorrectly. This significantly helps debugging, as locally it's 3856 // hard to see the differences. 3857 // If we don't have res_method here we must fail. Just use this bool to make sure of that with a 3858 // DCHECK. 3859 if (res_method == nullptr) { 3860 must_fail = true; 3861 // Try to find the method also with the other type for better error reporting below 3862 // but do not store such bogus lookup result in the DexCache or VerifierDeps. 3863 res_method = class_linker->FindIncompatibleMethod( 3864 klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx); 3865 } 3866 3867 if (res_method == nullptr) { 3868 Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method " 3869 << klass->PrettyDescriptor() << "." 3870 << dex_file_->GetMethodName(method_id) << " " 3871 << dex_file_->GetMethodSignature(method_id); 3872 return nullptr; 3873 } 3874 3875 // Make sure calls to constructors are "direct". There are additional restrictions but we don't 3876 // enforce them here. 3877 if (res_method->IsConstructor() && method_type != METHOD_DIRECT) { 3878 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor " 3879 << res_method->PrettyMethod(); 3880 return nullptr; 3881 } 3882 // Disallow any calls to class initializers. 3883 if (res_method->IsClassInitializer()) { 3884 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer " 3885 << res_method->PrettyMethod(); 3886 return nullptr; 3887 } 3888 3889 // Check that interface methods are static or match interface classes. 3890 // We only allow statics if we don't have default methods enabled. 3891 // 3892 // Note: this check must be after the initializer check, as those are required to fail a class, 3893 // while this check implies an IncompatibleClassChangeError. 3894 if (klass->IsInterface()) { 3895 // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if 3896 // default methods are supported for the dex file), or invoke-static. 3897 if (method_type != METHOD_INTERFACE && 3898 method_type != METHOD_STATIC && 3899 (!dex_file_->SupportsDefaultMethods() || 3900 method_type != METHOD_DIRECT) && 3901 method_type != METHOD_SUPER) { 3902 Fail(VERIFY_ERROR_CLASS_CHANGE) 3903 << "non-interface method " << dex_file_->PrettyMethod(dex_method_idx) 3904 << " is in an interface class " << klass->PrettyClass(); 3905 return nullptr; 3906 } 3907 } else { 3908 if (method_type == METHOD_INTERFACE) { 3909 Fail(VERIFY_ERROR_CLASS_CHANGE) 3910 << "interface method " << dex_file_->PrettyMethod(dex_method_idx) 3911 << " is in a non-interface class " << klass->PrettyClass(); 3912 return nullptr; 3913 } 3914 } 3915 3916 // Check specifically for non-public object methods being provided for interface dispatch. This 3917 // can occur if we failed to find a method with FindInterfaceMethod but later find one with 3918 // FindClassMethod for error message use. 3919 if (method_type == METHOD_INTERFACE && 3920 res_method->GetDeclaringClass()->IsObjectClass() && 3921 !res_method->IsPublic()) { 3922 Fail(VERIFY_ERROR_NO_METHOD) << "invoke-interface " << klass->PrettyDescriptor() << "." 3923 << dex_file_->GetMethodName(method_id) << " " 3924 << dex_file_->GetMethodSignature(method_id) << " resolved to " 3925 << "non-public object method " << res_method->PrettyMethod() << " " 3926 << "but non-public Object methods are excluded from interface " 3927 << "method resolution."; 3928 return nullptr; 3929 } 3930 // Check if access is allowed. 3931 if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) { 3932 Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call " 3933 << res_method->PrettyMethod() 3934 << " from " << referrer << ")"; 3935 return res_method; 3936 } 3937 // Check that invoke-virtual and invoke-super are not used on private methods of the same class. 3938 if (res_method->IsPrivate() && (method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER)) { 3939 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method " 3940 << res_method->PrettyMethod(); 3941 return nullptr; 3942 } 3943 // See if the method type implied by the invoke instruction matches the access flags for the 3944 // target method. The flags for METHOD_POLYMORPHIC are based on there being precisely two 3945 // signature polymorphic methods supported by the run-time which are native methods with variable 3946 // arguments. 3947 if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) || 3948 (method_type == METHOD_STATIC && !res_method->IsStatic()) || 3949 ((method_type == METHOD_SUPER || 3950 method_type == METHOD_VIRTUAL || 3951 method_type == METHOD_INTERFACE) && res_method->IsDirect()) || 3952 ((method_type == METHOD_POLYMORPHIC) && 3953 (!res_method->IsNative() || !res_method->IsVarargs()))) { 3954 Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method " 3955 "type of " << res_method->PrettyMethod(); 3956 return nullptr; 3957 } 3958 // Make sure we weren't expecting to fail. 3959 DCHECK(!must_fail) << "invoke type (" << method_type << ")" 3960 << klass->PrettyDescriptor() << "." 3961 << dex_file_->GetMethodName(method_id) << " " 3962 << dex_file_->GetMethodSignature(method_id) << " unexpectedly resolved to " 3963 << res_method->PrettyMethod() << " without error. Initially this method was " 3964 << "not found so we were expecting to fail for some reason."; 3965 return res_method; 3966 } 3967 3968 template <bool kVerifierDebug> 3969 template <class T> 3970 ArtMethod* MethodVerifier<kVerifierDebug>::VerifyInvocationArgsFromIterator( 3971 T* it, const Instruction* inst, MethodType method_type, bool is_range, ArtMethod* res_method) { 3972 DCHECK_EQ(!is_range, inst->HasVarArgs()); 3973 3974 // We use vAA as our expected arg count, rather than res_method->insSize, because we need to 3975 // match the call to the signature. Also, we might be calling through an abstract method 3976 // definition (which doesn't have register count values). 3977 const size_t expected_args = inst->VRegA(); 3978 /* caught by static verifier */ 3979 DCHECK(is_range || expected_args <= 5); 3980 3981 if (expected_args > code_item_accessor_.OutsSize()) { 3982 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args 3983 << ") exceeds outsSize (" 3984 << code_item_accessor_.OutsSize() << ")"; 3985 return nullptr; 3986 } 3987 3988 /* 3989 * Check the "this" argument, which must be an instance of the class that declared the method. 3990 * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a 3991 * rigorous check here (which is okay since we have to do it at runtime). 3992 */ 3993 if (method_type != METHOD_STATIC) { 3994 const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst); 3995 if (actual_arg_type.IsConflict()) { // GetInvocationThis failed. 3996 CHECK(have_pending_hard_failure_); 3997 return nullptr; 3998 } 3999 bool is_init = false; 4000 if (actual_arg_type.IsUninitializedTypes()) { 4001 if (res_method) { 4002 if (!res_method->IsConstructor()) { 4003 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized"; 4004 return nullptr; 4005 } 4006 } else { 4007 // Check whether the name of the called method is "<init>" 4008 const uint32_t method_idx = GetMethodIdxOfInvoke(inst); 4009 if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) { 4010 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized"; 4011 return nullptr; 4012 } 4013 } 4014 is_init = true; 4015 } 4016 const RegType& adjusted_type = is_init 4017 ? GetRegTypeCache()->FromUninitialized(actual_arg_type) 4018 : actual_arg_type; 4019 if (method_type != METHOD_INTERFACE && !adjusted_type.IsZeroOrNull()) { 4020 const RegType* res_method_class; 4021 // Miranda methods have the declaring interface as their declaring class, not the abstract 4022 // class. It would be wrong to use this for the type check (interface type checks are 4023 // postponed to runtime). 4024 if (res_method != nullptr && !res_method->IsMiranda()) { 4025 ObjPtr<mirror::Class> klass = res_method->GetDeclaringClass(); 4026 std::string temp; 4027 res_method_class = &FromClass(klass->GetDescriptor(&temp), klass, 4028 klass->CannotBeAssignedFromOtherTypes()); 4029 } else { 4030 const uint32_t method_idx = GetMethodIdxOfInvoke(inst); 4031 const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; 4032 res_method_class = ®_types_.FromDescriptor( 4033 class_loader_.Get(), 4034 dex_file_->StringByTypeIdx(class_idx), 4035 false); 4036 } 4037 if (!res_method_class->IsAssignableFrom(adjusted_type, this)) { 4038 Fail(adjusted_type.IsUnresolvedTypes() 4039 ? VERIFY_ERROR_NO_CLASS 4040 : VERIFY_ERROR_BAD_CLASS_SOFT) 4041 << "'this' argument '" << actual_arg_type << "' not instance of '" 4042 << *res_method_class << "'"; 4043 // Continue on soft failures. We need to find possible hard failures to avoid problems in 4044 // the compiler. 4045 if (have_pending_hard_failure_) { 4046 return nullptr; 4047 } 4048 } 4049 } 4050 } 4051 4052 uint32_t arg[5]; 4053 if (!is_range) { 4054 inst->GetVarArgs(arg); 4055 } 4056 uint32_t sig_registers = (method_type == METHOD_STATIC) ? 0 : 1; 4057 for ( ; it->HasNext(); it->Next()) { 4058 if (sig_registers >= expected_args) { 4059 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() << 4060 " argument registers, method signature has " << sig_registers + 1 << " or more"; 4061 return nullptr; 4062 } 4063 4064 const char* param_descriptor = it->GetDescriptor(); 4065 4066 if (param_descriptor == nullptr) { 4067 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature " 4068 "component"; 4069 return nullptr; 4070 } 4071 4072 const RegType& reg_type = reg_types_.FromDescriptor(class_loader_.Get(), 4073 param_descriptor, 4074 false); 4075 uint32_t get_reg = is_range ? inst->VRegC() + static_cast<uint32_t>(sig_registers) : 4076 arg[sig_registers]; 4077 if (reg_type.IsIntegralTypes()) { 4078 const RegType& src_type = work_line_->GetRegisterType(this, get_reg); 4079 if (!src_type.IsIntegralTypes()) { 4080 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type 4081 << " but expected " << reg_type; 4082 return nullptr; 4083 } 4084 } else { 4085 if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) { 4086 // Continue on soft failures. We need to find possible hard failures to avoid problems in 4087 // the compiler. 4088 if (have_pending_hard_failure_) { 4089 return nullptr; 4090 } 4091 } else if (reg_type.IsLongOrDoubleTypes()) { 4092 // Check that registers are consecutive (for non-range invokes). Invokes are the only 4093 // instructions not specifying register pairs by the first component, but require them 4094 // nonetheless. Only check when there's an actual register in the parameters. If there's 4095 // none, this will fail below. 4096 if (!is_range && sig_registers + 1 < expected_args) { 4097 uint32_t second_reg = arg[sig_registers + 1]; 4098 if (second_reg != get_reg + 1) { 4099 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, long or double parameter " 4100 "at index " << sig_registers << " is not a pair: " << get_reg << " + " 4101 << second_reg << "."; 4102 return nullptr; 4103 } 4104 } 4105 } 4106 } 4107 sig_registers += reg_type.IsLongOrDoubleTypes() ? 2 : 1; 4108 } 4109 if (expected_args != sig_registers) { 4110 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args << 4111 " argument registers, method signature has " << sig_registers; 4112 return nullptr; 4113 } 4114 return res_method; 4115 } 4116 4117 template <bool kVerifierDebug> 4118 void MethodVerifier<kVerifierDebug>::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst, 4119 MethodType method_type, 4120 bool is_range) { 4121 // As the method may not have been resolved, make this static check against what we expect. 4122 // The main reason for this code block is to fail hard when we find an illegal use, e.g., 4123 // wrong number of arguments or wrong primitive types, even if the method could not be resolved. 4124 const uint32_t method_idx = GetMethodIdxOfInvoke(inst); 4125 DexFileParameterIterator it(*dex_file_, 4126 dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_)); 4127 VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, nullptr); 4128 } 4129 4130 template <bool kVerifierDebug> 4131 bool MethodVerifier<kVerifierDebug>::CheckCallSite(uint32_t call_site_idx) { 4132 if (call_site_idx >= dex_file_->NumCallSiteIds()) { 4133 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Bad call site id #" << call_site_idx 4134 << " >= " << dex_file_->NumCallSiteIds(); 4135 return false; 4136 } 4137 4138 CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx)); 4139 // Check essential arguments are provided. The dex file verifier has verified indicies of the 4140 // main values (method handle, name, method_type). 4141 static const size_t kRequiredArguments = 3; 4142 if (it.Size() < kRequiredArguments) { 4143 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4144 << " has too few arguments: " 4145 << it.Size() << " < " << kRequiredArguments; 4146 return false; 4147 } 4148 4149 std::pair<const EncodedArrayValueIterator::ValueType, size_t> type_and_max[kRequiredArguments] = 4150 { { EncodedArrayValueIterator::ValueType::kMethodHandle, dex_file_->NumMethodHandles() }, 4151 { EncodedArrayValueIterator::ValueType::kString, dex_file_->NumStringIds() }, 4152 { EncodedArrayValueIterator::ValueType::kMethodType, dex_file_->NumProtoIds() } 4153 }; 4154 uint32_t index[kRequiredArguments]; 4155 4156 // Check arguments have expected types and are within permitted ranges. 4157 for (size_t i = 0; i < kRequiredArguments; ++i) { 4158 if (it.GetValueType() != type_and_max[i].first) { 4159 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site id #" << call_site_idx 4160 << " argument " << i << " has wrong type " 4161 << it.GetValueType() << "!=" << type_and_max[i].first; 4162 return false; 4163 } 4164 index[i] = static_cast<uint32_t>(it.GetJavaValue().i); 4165 if (index[i] >= type_and_max[i].second) { 4166 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site id #" << call_site_idx 4167 << " argument " << i << " bad index " 4168 << index[i] << " >= " << type_and_max[i].second; 4169 return false; 4170 } 4171 it.Next(); 4172 } 4173 4174 // Check method handle kind is valid. 4175 const dex::MethodHandleItem& mh = dex_file_->GetMethodHandle(index[0]); 4176 if (mh.method_handle_type_ != static_cast<uint16_t>(DexFile::MethodHandleType::kInvokeStatic)) { 4177 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4178 << " argument 0 method handle type is not InvokeStatic: " 4179 << mh.method_handle_type_; 4180 return false; 4181 } 4182 return true; 4183 } 4184 4185 class MethodParamListDescriptorIterator { 4186 public: 4187 explicit MethodParamListDescriptorIterator(ArtMethod* res_method) : 4188 res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()), 4189 params_size_(params_ == nullptr ? 0 : params_->Size()) { 4190 } 4191 4192 bool HasNext() { 4193 return pos_ < params_size_; 4194 } 4195 4196 void Next() { 4197 ++pos_; 4198 } 4199 4200 const char* GetDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) { 4201 return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_); 4202 } 4203 4204 private: 4205 ArtMethod* res_method_; 4206 size_t pos_; 4207 const dex::TypeList* params_; 4208 const size_t params_size_; 4209 }; 4210 4211 template <bool kVerifierDebug> 4212 ArtMethod* MethodVerifier<kVerifierDebug>::VerifyInvocationArgs( 4213 const Instruction* inst, MethodType method_type, bool is_range) { 4214 // Resolve the method. This could be an abstract or concrete method depending on what sort of call 4215 // we're making. 4216 const uint32_t method_idx = GetMethodIdxOfInvoke(inst); 4217 ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type); 4218 if (res_method == nullptr) { // error or class is unresolved 4219 // Check what we can statically. 4220 if (!have_pending_hard_failure_) { 4221 VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range); 4222 } 4223 return nullptr; 4224 } 4225 4226 // If we're using invoke-super(method), make sure that the executing method's class' superclass 4227 // has a vtable entry for the target method. Or the target is on a interface. 4228 if (method_type == METHOD_SUPER) { 4229 dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; 4230 const RegType& reference_type = reg_types_.FromDescriptor( 4231 class_loader_.Get(), 4232 dex_file_->StringByTypeIdx(class_idx), 4233 false); 4234 if (reference_type.IsUnresolvedTypes()) { 4235 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Unable to find referenced class from invoke-super"; 4236 return nullptr; 4237 } 4238 if (reference_type.GetClass()->IsInterface()) { 4239 // TODO Can we verify anything else. 4240 if (class_idx == class_def_.class_idx_) { 4241 Fail(VERIFY_ERROR_CLASS_CHANGE) << "Cannot invoke-super on self as interface"; 4242 return nullptr; 4243 } 4244 // TODO Revisit whether we want to allow invoke-super on direct interfaces only like the JLS 4245 // does. 4246 if (!GetDeclaringClass().HasClass()) { 4247 Fail(VERIFY_ERROR_NO_CLASS) << "Unable to resolve the full class of 'this' used in an" 4248 << "interface invoke-super"; 4249 return nullptr; 4250 } else if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this)) { 4251 Fail(VERIFY_ERROR_CLASS_CHANGE) 4252 << "invoke-super in " << mirror::Class::PrettyClass(GetDeclaringClass().GetClass()) 4253 << " in method " 4254 << dex_file_->PrettyMethod(dex_method_idx_) << " to method " 4255 << dex_file_->PrettyMethod(method_idx) << " references " 4256 << "non-super-interface type " << mirror::Class::PrettyClass(reference_type.GetClass()); 4257 return nullptr; 4258 } 4259 } else { 4260 const RegType& super = GetDeclaringClass().GetSuperClass(®_types_); 4261 if (super.IsUnresolvedTypes()) { 4262 Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from " 4263 << dex_file_->PrettyMethod(dex_method_idx_) 4264 << " to super " << res_method->PrettyMethod(); 4265 return nullptr; 4266 } 4267 if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this) || 4268 (res_method->GetMethodIndex() >= super.GetClass()->GetVTableLength())) { 4269 Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from " 4270 << dex_file_->PrettyMethod(dex_method_idx_) 4271 << " to super " << super 4272 << "." << res_method->GetName() 4273 << res_method->GetSignature(); 4274 return nullptr; 4275 } 4276 } 4277 } 4278 4279 if (UNLIKELY(method_type == METHOD_POLYMORPHIC)) { 4280 // Process the signature of the calling site that is invoking the method handle. 4281 dex::ProtoIndex proto_idx(inst->VRegH()); 4282 DexFileParameterIterator it(*dex_file_, dex_file_->GetProtoId(proto_idx)); 4283 return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method); 4284 } else { 4285 // Process the target method's signature. 4286 MethodParamListDescriptorIterator it(res_method); 4287 return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method); 4288 } 4289 } 4290 4291 template <bool kVerifierDebug> 4292 bool MethodVerifier<kVerifierDebug>::CheckSignaturePolymorphicMethod(ArtMethod* method) { 4293 ObjPtr<mirror::Class> klass = method->GetDeclaringClass(); 4294 const char* method_name = method->GetName(); 4295 4296 const char* expected_return_descriptor; 4297 ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = 4298 Runtime::Current()->GetClassLinker()->GetClassRoots(); 4299 if (klass == GetClassRoot<mirror::MethodHandle>(class_roots)) { 4300 expected_return_descriptor = mirror::MethodHandle::GetReturnTypeDescriptor(method_name); 4301 } else if (klass == GetClassRoot<mirror::VarHandle>(class_roots)) { 4302 expected_return_descriptor = mirror::VarHandle::GetReturnTypeDescriptor(method_name); 4303 } else { 4304 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4305 << "Signature polymorphic method in unsuppported class: " << klass->PrettyDescriptor(); 4306 return false; 4307 } 4308 4309 if (expected_return_descriptor == nullptr) { 4310 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4311 << "Signature polymorphic method name invalid: " << method_name; 4312 return false; 4313 } 4314 4315 const dex::TypeList* types = method->GetParameterTypeList(); 4316 if (types->Size() != 1) { 4317 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4318 << "Signature polymorphic method has too many arguments " << types->Size() << " != 1"; 4319 return false; 4320 } 4321 4322 const dex::TypeIndex argument_type_index = types->GetTypeItem(0).type_idx_; 4323 const char* argument_descriptor = method->GetTypeDescriptorFromTypeIdx(argument_type_index); 4324 if (strcmp(argument_descriptor, "[Ljava/lang/Object;") != 0) { 4325 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4326 << "Signature polymorphic method has unexpected argument type: " << argument_descriptor; 4327 return false; 4328 } 4329 4330 const char* return_descriptor = method->GetReturnTypeDescriptor(); 4331 if (strcmp(return_descriptor, expected_return_descriptor) != 0) { 4332 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4333 << "Signature polymorphic method has unexpected return type: " << return_descriptor 4334 << " != " << expected_return_descriptor; 4335 return false; 4336 } 4337 4338 return true; 4339 } 4340 4341 template <bool kVerifierDebug> 4342 bool MethodVerifier<kVerifierDebug>::CheckSignaturePolymorphicReceiver(const Instruction* inst) { 4343 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 4344 if (this_type.IsZeroOrNull()) { 4345 /* null pointer always passes (and always fails at run time) */ 4346 return true; 4347 } else if (!this_type.IsNonZeroReferenceTypes()) { 4348 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4349 << "invoke-polymorphic receiver is not a reference: " 4350 << this_type; 4351 return false; 4352 } else if (this_type.IsUninitializedReference()) { 4353 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4354 << "invoke-polymorphic receiver is uninitialized: " 4355 << this_type; 4356 return false; 4357 } else if (!this_type.HasClass()) { 4358 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4359 << "invoke-polymorphic receiver has no class: " 4360 << this_type; 4361 return false; 4362 } else { 4363 ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = 4364 Runtime::Current()->GetClassLinker()->GetClassRoots(); 4365 if (!this_type.GetClass()->IsSubClass(GetClassRoot<mirror::MethodHandle>(class_roots)) && 4366 !this_type.GetClass()->IsSubClass(GetClassRoot<mirror::VarHandle>(class_roots))) { 4367 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4368 << "invoke-polymorphic receiver is not a subclass of MethodHandle or VarHandle: " 4369 << this_type; 4370 return false; 4371 } 4372 } 4373 return true; 4374 } 4375 4376 template <bool kVerifierDebug> 4377 uint16_t MethodVerifier<kVerifierDebug>::GetMethodIdxOfInvoke(const Instruction* inst) { 4378 switch (inst->Opcode()) { 4379 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: 4380 case Instruction::INVOKE_VIRTUAL_QUICK: { 4381 DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_) 4382 << dex_file_->PrettyMethod(dex_method_idx_, true) << "@" << work_insn_idx_; 4383 DCHECK(method_being_verified_ != nullptr); 4384 uint16_t method_idx = method_being_verified_->GetIndexFromQuickening(work_insn_idx_); 4385 CHECK_NE(method_idx, DexFile::kDexNoIndex16); 4386 return method_idx; 4387 } 4388 default: { 4389 return inst->VRegB(); 4390 } 4391 } 4392 } 4393 4394 template <bool kVerifierDebug> 4395 uint16_t MethodVerifier<kVerifierDebug>::GetFieldIdxOfFieldAccess(const Instruction* inst, 4396 bool is_static) { 4397 if (is_static) { 4398 return inst->VRegB_21c(); 4399 } else if (inst->IsQuickened()) { 4400 DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_); 4401 DCHECK(method_being_verified_ != nullptr); 4402 uint16_t field_idx = method_being_verified_->GetIndexFromQuickening(work_insn_idx_); 4403 CHECK_NE(field_idx, DexFile::kDexNoIndex16); 4404 return field_idx; 4405 } else { 4406 return inst->VRegC_22c(); 4407 } 4408 } 4409 4410 template <bool kVerifierDebug> 4411 void MethodVerifier<kVerifierDebug>::VerifyNewArray(const Instruction* inst, 4412 bool is_filled, 4413 bool is_range) { 4414 dex::TypeIndex type_idx; 4415 if (!is_filled) { 4416 DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY); 4417 type_idx = dex::TypeIndex(inst->VRegC_22c()); 4418 } else if (!is_range) { 4419 DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY); 4420 type_idx = dex::TypeIndex(inst->VRegB_35c()); 4421 } else { 4422 DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE); 4423 type_idx = dex::TypeIndex(inst->VRegB_3rc()); 4424 } 4425 const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx); 4426 if (res_type.IsConflict()) { // bad class 4427 DCHECK_NE(failures_.size(), 0U); 4428 } else { 4429 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 4430 if (!res_type.IsArrayTypes()) { 4431 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type; 4432 } else if (!is_filled) { 4433 /* make sure "size" register is valid type */ 4434 work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer()); 4435 /* set register type to array class */ 4436 const RegType& precise_type = reg_types_.FromUninitialized(res_type); 4437 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_22c(), precise_type); 4438 } else { 4439 DCHECK(!res_type.IsUnresolvedMergedReference()); 4440 // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of 4441 // the list and fail. It's legal, if silly, for arg_count to be zero. 4442 const RegType& expected_type = reg_types_.GetComponentType(res_type, class_loader_.Get()); 4443 uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c(); 4444 uint32_t arg[5]; 4445 if (!is_range) { 4446 inst->GetVarArgs(arg); 4447 } 4448 for (size_t ui = 0; ui < arg_count; ui++) { 4449 uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui]; 4450 if (!work_line_->VerifyRegisterType(this, get_reg, expected_type)) { 4451 work_line_->SetResultRegisterType(this, reg_types_.Conflict()); 4452 return; 4453 } 4454 } 4455 // filled-array result goes into "result" register 4456 const RegType& precise_type = reg_types_.FromUninitialized(res_type); 4457 work_line_->SetResultRegisterType(this, precise_type); 4458 } 4459 } 4460 } 4461 4462 template <bool kVerifierDebug> 4463 void MethodVerifier<kVerifierDebug>::VerifyAGet(const Instruction* inst, 4464 const RegType& insn_type, 4465 bool is_primitive) { 4466 const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x()); 4467 if (!index_type.IsArrayIndexTypes()) { 4468 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")"; 4469 } else { 4470 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x()); 4471 if (array_type.IsZeroOrNull()) { 4472 // Null array class; this code path will fail at runtime. Infer a merge-able type from the 4473 // instruction type. 4474 if (!is_primitive) { 4475 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Null()); 4476 } else if (insn_type.IsInteger()) { 4477 // Pick a non-zero constant (to distinguish with null) that can fit in any primitive. 4478 // We cannot use 'insn_type' as it could be a float array or an int array. 4479 work_line_->SetRegisterType<LockOp::kClear>( 4480 this, inst->VRegA_23x(), DetermineCat1Constant(1, need_precise_constants_)); 4481 } else if (insn_type.IsCategory1Types()) { 4482 // Category 1 4483 // The 'insn_type' is exactly the type we need. 4484 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), insn_type); 4485 } else { 4486 // Category 2 4487 work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), 4488 reg_types_.FromCat2ConstLo(0, false), 4489 reg_types_.FromCat2ConstHi(0, false)); 4490 } 4491 } else if (!array_type.IsArrayTypes()) { 4492 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget"; 4493 } else if (array_type.IsUnresolvedMergedReference()) { 4494 // Unresolved array types must be reference array types. 4495 if (is_primitive) { 4496 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type 4497 << " source for category 1 aget"; 4498 } else { 4499 Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aget for " << array_type 4500 << " because of missing class"; 4501 // Approximate with java.lang.Object[]. 4502 work_line_->SetRegisterType<LockOp::kClear>(this, 4503 inst->VRegA_23x(), 4504 reg_types_.JavaLangObject(false)); 4505 } 4506 } else { 4507 /* verify the class */ 4508 const RegType& component_type = reg_types_.GetComponentType(array_type, class_loader_.Get()); 4509 if (!component_type.IsReferenceTypes() && !is_primitive) { 4510 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type 4511 << " source for aget-object"; 4512 } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) { 4513 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type 4514 << " source for category 1 aget"; 4515 } else if (is_primitive && !insn_type.Equals(component_type) && 4516 !((insn_type.IsInteger() && component_type.IsFloat()) || 4517 (insn_type.IsLong() && component_type.IsDouble()))) { 4518 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type 4519 << " incompatible with aget of type " << insn_type; 4520 } else { 4521 // Use knowledge of the field type which is stronger than the type inferred from the 4522 // instruction, which can't differentiate object types and ints from floats, longs from 4523 // doubles. 4524 if (!component_type.IsLowHalf()) { 4525 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), component_type); 4526 } else { 4527 work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type, 4528 component_type.HighHalf(®_types_)); 4529 } 4530 } 4531 } 4532 } 4533 } 4534 4535 template <bool kVerifierDebug> 4536 void MethodVerifier<kVerifierDebug>::VerifyPrimitivePut(const RegType& target_type, 4537 const RegType& insn_type, 4538 const uint32_t vregA) { 4539 // Primitive assignability rules are weaker than regular assignability rules. 4540 bool instruction_compatible; 4541 bool value_compatible; 4542 const RegType& value_type = work_line_->GetRegisterType(this, vregA); 4543 if (target_type.IsIntegralTypes()) { 4544 instruction_compatible = target_type.Equals(insn_type); 4545 value_compatible = value_type.IsIntegralTypes(); 4546 } else if (target_type.IsFloat()) { 4547 instruction_compatible = insn_type.IsInteger(); // no put-float, so expect put-int 4548 value_compatible = value_type.IsFloatTypes(); 4549 } else if (target_type.IsLong()) { 4550 instruction_compatible = insn_type.IsLong(); 4551 // Additional register check: this is not checked statically (as part of VerifyInstructions), 4552 // as target_type depends on the resolved type of the field. 4553 if (instruction_compatible && work_line_->NumRegs() > vregA + 1) { 4554 const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1); 4555 value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi); 4556 } else { 4557 value_compatible = false; 4558 } 4559 } else if (target_type.IsDouble()) { 4560 instruction_compatible = insn_type.IsLong(); // no put-double, so expect put-long 4561 // Additional register check: this is not checked statically (as part of VerifyInstructions), 4562 // as target_type depends on the resolved type of the field. 4563 if (instruction_compatible && work_line_->NumRegs() > vregA + 1) { 4564 const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1); 4565 value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi); 4566 } else { 4567 value_compatible = false; 4568 } 4569 } else { 4570 instruction_compatible = false; // reference with primitive store 4571 value_compatible = false; // unused 4572 } 4573 if (!instruction_compatible) { 4574 // This is a global failure rather than a class change failure as the instructions and 4575 // the descriptors for the type should have been consistent within the same file at 4576 // compile time. 4577 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type 4578 << "' but expected type '" << target_type << "'"; 4579 return; 4580 } 4581 if (!value_compatible) { 4582 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA 4583 << " of type " << value_type << " but expected " << target_type << " for put"; 4584 return; 4585 } 4586 } 4587 4588 template <bool kVerifierDebug> 4589 void MethodVerifier<kVerifierDebug>::VerifyAPut(const Instruction* inst, 4590 const RegType& insn_type, 4591 bool is_primitive) { 4592 const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x()); 4593 if (!index_type.IsArrayIndexTypes()) { 4594 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")"; 4595 } else { 4596 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x()); 4597 if (array_type.IsZeroOrNull()) { 4598 // Null array type; this code path will fail at runtime. 4599 // Still check that the given value matches the instruction's type. 4600 // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed 4601 // and fits multiple register types. 4602 const RegType* modified_reg_type = &insn_type; 4603 if ((modified_reg_type == ®_types_.Integer()) || 4604 (modified_reg_type == ®_types_.LongLo())) { 4605 // May be integer or float | long or double. Overwrite insn_type accordingly. 4606 const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x()); 4607 if (modified_reg_type == ®_types_.Integer()) { 4608 if (&value_type == ®_types_.Float()) { 4609 modified_reg_type = &value_type; 4610 } 4611 } else { 4612 if (&value_type == ®_types_.DoubleLo()) { 4613 modified_reg_type = &value_type; 4614 } 4615 } 4616 } 4617 work_line_->VerifyRegisterType(this, inst->VRegA_23x(), *modified_reg_type); 4618 } else if (!array_type.IsArrayTypes()) { 4619 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput"; 4620 } else if (array_type.IsUnresolvedMergedReference()) { 4621 // Unresolved array types must be reference array types. 4622 if (is_primitive) { 4623 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type 4624 << "' but unresolved type '" << array_type << "'"; 4625 } else { 4626 Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aput for " << array_type 4627 << " because of missing class"; 4628 } 4629 } else { 4630 const RegType& component_type = reg_types_.GetComponentType(array_type, class_loader_.Get()); 4631 const uint32_t vregA = inst->VRegA_23x(); 4632 if (is_primitive) { 4633 VerifyPrimitivePut(component_type, insn_type, vregA); 4634 } else { 4635 if (!component_type.IsReferenceTypes()) { 4636 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type 4637 << " source for aput-object"; 4638 } else { 4639 // The instruction agrees with the type of array, confirm the value to be stored does too 4640 // Note: we use the instruction type (rather than the component type) for aput-object as 4641 // incompatible classes will be caught at runtime as an array store exception 4642 work_line_->VerifyRegisterType(this, vregA, insn_type); 4643 } 4644 } 4645 } 4646 } 4647 } 4648 4649 template <bool kVerifierDebug> 4650 ArtField* MethodVerifier<kVerifierDebug>::GetStaticField(int field_idx) { 4651 const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4652 // Check access to class 4653 const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_); 4654 if (klass_type.IsConflict()) { // bad class 4655 AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s", 4656 field_idx, dex_file_->GetFieldName(field_id), 4657 dex_file_->GetFieldDeclaringClassDescriptor(field_id))); 4658 return nullptr; 4659 } 4660 if (klass_type.IsUnresolvedTypes()) { 4661 // Accessibility checks depend on resolved fields. 4662 DCHECK(klass_type.Equals(GetDeclaringClass()) || 4663 !failures_.empty() || 4664 IsSdkVersionSetAndLessThan(api_level_, SdkVersion::kP)); 4665 4666 return nullptr; // Can't resolve Class so no more to do here, will do checking at runtime. 4667 } 4668 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 4669 ArtField* field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_); 4670 4671 // Record result of the field resolution attempt. 4672 VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field); 4673 4674 if (field == nullptr) { 4675 VLOG(verifier) << "Unable to resolve static field " << field_idx << " (" 4676 << dex_file_->GetFieldName(field_id) << ") in " 4677 << dex_file_->GetFieldDeclaringClassDescriptor(field_id); 4678 DCHECK(self_->IsExceptionPending()); 4679 self_->ClearException(); 4680 return nullptr; 4681 } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(), 4682 field->GetAccessFlags())) { 4683 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << field->PrettyField() 4684 << " from " << GetDeclaringClass(); 4685 return nullptr; 4686 } else if (!field->IsStatic()) { 4687 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() << " to be static"; 4688 return nullptr; 4689 } 4690 return field; 4691 } 4692 4693 template <bool kVerifierDebug> 4694 ArtField* MethodVerifier<kVerifierDebug>::GetInstanceField(const RegType& obj_type, int field_idx) { 4695 const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4696 // Check access to class. 4697 const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_); 4698 if (klass_type.IsConflict()) { 4699 AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s", 4700 field_idx, dex_file_->GetFieldName(field_id), 4701 dex_file_->GetFieldDeclaringClassDescriptor(field_id))); 4702 return nullptr; 4703 } 4704 if (klass_type.IsUnresolvedTypes()) { 4705 // Accessibility checks depend on resolved fields. 4706 DCHECK(klass_type.Equals(GetDeclaringClass()) || 4707 !failures_.empty() || 4708 IsSdkVersionSetAndLessThan(api_level_, SdkVersion::kP)); 4709 4710 return nullptr; // Can't resolve Class so no more to do here 4711 } 4712 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 4713 ArtField* field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_); 4714 4715 // Record result of the field resolution attempt. 4716 VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field); 4717 4718 if (field == nullptr) { 4719 VLOG(verifier) << "Unable to resolve instance field " << field_idx << " (" 4720 << dex_file_->GetFieldName(field_id) << ") in " 4721 << dex_file_->GetFieldDeclaringClassDescriptor(field_id); 4722 DCHECK(self_->IsExceptionPending()); 4723 self_->ClearException(); 4724 return nullptr; 4725 } else if (obj_type.IsZeroOrNull()) { 4726 // Cannot infer and check type, however, access will cause null pointer exception. 4727 // Fall through into a few last soft failure checks below. 4728 } else if (!obj_type.IsReferenceTypes()) { 4729 // Trying to read a field from something that isn't a reference. 4730 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has " 4731 << "non-reference type " << obj_type; 4732 return nullptr; 4733 } else { 4734 std::string temp; 4735 ObjPtr<mirror::Class> klass = field->GetDeclaringClass(); 4736 const RegType& field_klass = 4737 FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes()); 4738 if (obj_type.IsUninitializedTypes()) { 4739 // Field accesses through uninitialized references are only allowable for constructors where 4740 // the field is declared in this class. 4741 // Note: this IsConstructor check is technically redundant, as UninitializedThis should only 4742 // appear in constructors. 4743 if (!obj_type.IsUninitializedThisReference() || 4744 !IsConstructor() || 4745 !field_klass.Equals(GetDeclaringClass())) { 4746 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << field->PrettyField() 4747 << " of a not fully initialized object within the context" 4748 << " of " << dex_file_->PrettyMethod(dex_method_idx_); 4749 return nullptr; 4750 } 4751 } else if (!field_klass.IsAssignableFrom(obj_type, this)) { 4752 // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class 4753 // of C1. For resolution to occur the declared class of the field must be compatible with 4754 // obj_type, we've discovered this wasn't so, so report the field didn't exist. 4755 VerifyError type; 4756 bool is_aot = Runtime::Current()->IsAotCompiler(); 4757 if (is_aot && (field_klass.IsUnresolvedTypes() || obj_type.IsUnresolvedTypes())) { 4758 // Compiler & unresolved types involved, retry at runtime. 4759 type = VerifyError::VERIFY_ERROR_NO_CLASS; 4760 } else { 4761 // Classes known (resolved; and thus assignability check is precise), or we are at runtime 4762 // and still missing classes. This is a hard failure. 4763 type = VerifyError::VERIFY_ERROR_BAD_CLASS_HARD; 4764 } 4765 Fail(type) << "cannot access instance field " << field->PrettyField() 4766 << " from object of type " << obj_type; 4767 return nullptr; 4768 } 4769 } 4770 4771 // Few last soft failure checks. 4772 if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(), 4773 field->GetAccessFlags())) { 4774 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << field->PrettyField() 4775 << " from " << GetDeclaringClass(); 4776 return nullptr; 4777 } else if (field->IsStatic()) { 4778 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() 4779 << " to not be static"; 4780 return nullptr; 4781 } 4782 4783 return field; 4784 } 4785 4786 template <bool kVerifierDebug> 4787 template <FieldAccessType kAccType> 4788 void MethodVerifier<kVerifierDebug>::VerifyISFieldAccess(const Instruction* inst, 4789 const RegType& insn_type, 4790 bool is_primitive, 4791 bool is_static) { 4792 uint32_t field_idx = GetFieldIdxOfFieldAccess(inst, is_static); 4793 ArtField* field; 4794 if (is_static) { 4795 field = GetStaticField(field_idx); 4796 } else { 4797 const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c()); 4798 4799 // One is not allowed to access fields on uninitialized references, except to write to 4800 // fields in the constructor (before calling another constructor). 4801 // GetInstanceField does an assignability check which will fail for uninitialized types. 4802 // We thus modify the type if the uninitialized reference is a "this" reference (this also 4803 // checks at the same time that we're verifying a constructor). 4804 bool should_adjust = (kAccType == FieldAccessType::kAccPut) && 4805 object_type.IsUninitializedThisReference(); 4806 const RegType& adjusted_type = should_adjust 4807 ? GetRegTypeCache()->FromUninitialized(object_type) 4808 : object_type; 4809 field = GetInstanceField(adjusted_type, field_idx); 4810 if (UNLIKELY(have_pending_hard_failure_)) { 4811 return; 4812 } 4813 if (should_adjust) { 4814 if (field == nullptr) { 4815 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Might be accessing a superclass instance field prior " 4816 << "to the superclass being initialized in " 4817 << dex_file_->PrettyMethod(dex_method_idx_); 4818 } else if (field->GetDeclaringClass() != GetDeclaringClass().GetClass()) { 4819 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access superclass instance field " 4820 << field->PrettyField() << " of a not fully initialized " 4821 << "object within the context of " 4822 << dex_file_->PrettyMethod(dex_method_idx_); 4823 return; 4824 } 4825 } 4826 } 4827 const RegType* field_type = nullptr; 4828 if (field != nullptr) { 4829 if (kAccType == FieldAccessType::kAccPut) { 4830 if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) { 4831 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField() 4832 << " from other class " << GetDeclaringClass(); 4833 // Keep hunting for possible hard fails. 4834 } 4835 } 4836 4837 ObjPtr<mirror::Class> field_type_class = 4838 can_load_classes_ ? field->ResolveType() : field->LookupResolvedType(); 4839 if (field_type_class != nullptr) { 4840 field_type = &FromClass(field->GetTypeDescriptor(), 4841 field_type_class, 4842 field_type_class->CannotBeAssignedFromOtherTypes()); 4843 } else { 4844 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 4845 self_->ClearException(); 4846 } 4847 } else if (IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP)) { 4848 // If we don't have the field (it seems we failed resolution) and this is a PUT, we need to 4849 // redo verification at runtime as the field may be final, unless the field id shows it's in 4850 // the same class. 4851 // 4852 // For simplicity, it is OK to not distinguish compile-time vs runtime, and post this an 4853 // ACCESS_FIELD failure at runtime. This has the same effect as NO_FIELD - punting the class 4854 // to the access-checks interpreter. 4855 // 4856 // Note: see b/34966607. This and above may be changed in the future. 4857 if (kAccType == FieldAccessType::kAccPut) { 4858 const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4859 const char* field_class_descriptor = dex_file_->GetFieldDeclaringClassDescriptor(field_id); 4860 const RegType* field_class_type = ®_types_.FromDescriptor(class_loader_.Get(), 4861 field_class_descriptor, 4862 false); 4863 if (!field_class_type->Equals(GetDeclaringClass())) { 4864 Fail(VERIFY_ERROR_ACCESS_FIELD) << "could not check field put for final field modify of " 4865 << field_class_descriptor 4866 << "." 4867 << dex_file_->GetFieldName(field_id) 4868 << " from other class " 4869 << GetDeclaringClass(); 4870 } 4871 } 4872 } 4873 if (field_type == nullptr) { 4874 const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4875 const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id); 4876 field_type = ®_types_.FromDescriptor(class_loader_.Get(), descriptor, false); 4877 } 4878 DCHECK(field_type != nullptr); 4879 const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c(); 4880 static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet, 4881 "Unexpected third access type"); 4882 if (kAccType == FieldAccessType::kAccPut) { 4883 // sput or iput. 4884 if (is_primitive) { 4885 VerifyPrimitivePut(*field_type, insn_type, vregA); 4886 } else { 4887 if (!insn_type.IsAssignableFrom(*field_type, this)) { 4888 // If the field type is not a reference, this is a global failure rather than 4889 // a class change failure as the instructions and the descriptors for the type 4890 // should have been consistent within the same file at compile time. 4891 VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT 4892 : VERIFY_ERROR_BAD_CLASS_HARD; 4893 Fail(error) << "expected field " << ArtField::PrettyField(field) 4894 << " to be compatible with type '" << insn_type 4895 << "' but found type '" << *field_type 4896 << "' in put-object"; 4897 return; 4898 } 4899 work_line_->VerifyRegisterType(this, vregA, *field_type); 4900 } 4901 } else if (kAccType == FieldAccessType::kAccGet) { 4902 // sget or iget. 4903 if (is_primitive) { 4904 if (field_type->Equals(insn_type) || 4905 (field_type->IsFloat() && insn_type.IsInteger()) || 4906 (field_type->IsDouble() && insn_type.IsLong())) { 4907 // expected that read is of the correct primitive type or that int reads are reading 4908 // floats or long reads are reading doubles 4909 } else { 4910 // This is a global failure rather than a class change failure as the instructions and 4911 // the descriptors for the type should have been consistent within the same file at 4912 // compile time 4913 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field) 4914 << " to be of type '" << insn_type 4915 << "' but found type '" << *field_type << "' in get"; 4916 return; 4917 } 4918 } else { 4919 if (!insn_type.IsAssignableFrom(*field_type, this)) { 4920 // If the field type is not a reference, this is a global failure rather than 4921 // a class change failure as the instructions and the descriptors for the type 4922 // should have been consistent within the same file at compile time. 4923 VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT 4924 : VERIFY_ERROR_BAD_CLASS_HARD; 4925 Fail(error) << "expected field " << ArtField::PrettyField(field) 4926 << " to be compatible with type '" << insn_type 4927 << "' but found type '" << *field_type 4928 << "' in get-object"; 4929 if (error != VERIFY_ERROR_BAD_CLASS_HARD) { 4930 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict()); 4931 } 4932 return; 4933 } 4934 } 4935 if (!field_type->IsLowHalf()) { 4936 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type); 4937 } else { 4938 work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(®_types_)); 4939 } 4940 } else { 4941 LOG(FATAL) << "Unexpected case."; 4942 } 4943 } 4944 4945 template <bool kVerifierDebug> 4946 bool MethodVerifier<kVerifierDebug>::UpdateRegisters(uint32_t next_insn, 4947 RegisterLine* merge_line, 4948 bool update_merge_line) { 4949 bool changed = true; 4950 RegisterLine* target_line = reg_table_.GetLine(next_insn); 4951 if (!GetInstructionFlags(next_insn).IsVisitedOrChanged()) { 4952 /* 4953 * We haven't processed this instruction before, and we haven't touched the registers here, so 4954 * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the 4955 * only way a register can transition out of "unknown", so this is not just an optimization.) 4956 */ 4957 target_line->CopyFromLine(merge_line); 4958 if (GetInstructionFlags(next_insn).IsReturn()) { 4959 // Verify that the monitor stack is empty on return. 4960 merge_line->VerifyMonitorStackEmpty(this); 4961 4962 // For returns we only care about the operand to the return, all other registers are dead. 4963 // Initialize them as conflicts so they don't add to GC and deoptimization information. 4964 const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn); 4965 AdjustReturnLine(this, ret_inst, target_line); 4966 // Directly bail if a hard failure was found. 4967 if (have_pending_hard_failure_) { 4968 return false; 4969 } 4970 } 4971 } else { 4972 RegisterLineArenaUniquePtr copy; 4973 if (kVerifierDebug) { 4974 copy.reset(RegisterLine::Create(target_line->NumRegs(), allocator_, GetRegTypeCache())); 4975 copy->CopyFromLine(target_line); 4976 } 4977 changed = target_line->MergeRegisters(this, merge_line); 4978 if (have_pending_hard_failure_) { 4979 return false; 4980 } 4981 if (kVerifierDebug && changed) { 4982 LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]" 4983 << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n" 4984 << copy->Dump(this) << " MERGE\n" 4985 << merge_line->Dump(this) << " ==\n" 4986 << target_line->Dump(this); 4987 } 4988 if (update_merge_line && changed) { 4989 merge_line->CopyFromLine(target_line); 4990 } 4991 } 4992 if (changed) { 4993 GetModifiableInstructionFlags(next_insn).SetChanged(); 4994 } 4995 return true; 4996 } 4997 4998 template <bool kVerifierDebug> 4999 const RegType& MethodVerifier<kVerifierDebug>::GetMethodReturnType() { 5000 if (return_type_ == nullptr) { 5001 if (method_being_verified_ != nullptr) { 5002 ObjPtr<mirror::Class> return_type_class = can_load_classes_ 5003 ? method_being_verified_->ResolveReturnType() 5004 : method_being_verified_->LookupResolvedReturnType(); 5005 if (return_type_class != nullptr) { 5006 return_type_ = &FromClass(method_being_verified_->GetReturnTypeDescriptor(), 5007 return_type_class, 5008 return_type_class->CannotBeAssignedFromOtherTypes()); 5009 } else { 5010 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 5011 self_->ClearException(); 5012 } 5013 } 5014 if (return_type_ == nullptr) { 5015 const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 5016 const dex::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id); 5017 dex::TypeIndex return_type_idx = proto_id.return_type_idx_; 5018 const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx)); 5019 return_type_ = ®_types_.FromDescriptor(class_loader_.Get(), descriptor, false); 5020 } 5021 } 5022 return *return_type_; 5023 } 5024 5025 template <bool kVerifierDebug> 5026 const RegType& MethodVerifier<kVerifierDebug>::GetDeclaringClass() { 5027 if (declaring_class_ == nullptr) { 5028 const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 5029 const char* descriptor 5030 = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_)); 5031 if (method_being_verified_ != nullptr) { 5032 ObjPtr<mirror::Class> klass = method_being_verified_->GetDeclaringClass(); 5033 declaring_class_ = &FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()); 5034 } else { 5035 declaring_class_ = ®_types_.FromDescriptor(class_loader_.Get(), descriptor, false); 5036 } 5037 } 5038 return *declaring_class_; 5039 } 5040 5041 template <bool kVerifierDebug> 5042 const RegType& MethodVerifier<kVerifierDebug>::DetermineCat1Constant(int32_t value, bool precise) { 5043 if (precise) { 5044 // Precise constant type. 5045 return reg_types_.FromCat1Const(value, true); 5046 } else { 5047 // Imprecise constant type. 5048 if (value < -32768) { 5049 return reg_types_.IntConstant(); 5050 } else if (value < -128) { 5051 return reg_types_.ShortConstant(); 5052 } else if (value < 0) { 5053 return reg_types_.ByteConstant(); 5054 } else if (value == 0) { 5055 return reg_types_.Zero(); 5056 } else if (value == 1) { 5057 return reg_types_.One(); 5058 } else if (value < 128) { 5059 return reg_types_.PosByteConstant(); 5060 } else if (value < 32768) { 5061 return reg_types_.PosShortConstant(); 5062 } else if (value < 65536) { 5063 return reg_types_.CharConstant(); 5064 } else { 5065 return reg_types_.IntConstant(); 5066 } 5067 } 5068 } 5069 5070 template <bool kVerifierDebug> 5071 const RegType& MethodVerifier<kVerifierDebug>::FromClass(const char* descriptor, 5072 ObjPtr<mirror::Class> klass, 5073 bool precise) { 5074 DCHECK(klass != nullptr); 5075 if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) { 5076 Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for " 5077 << "non-instantiable klass " << descriptor; 5078 precise = false; 5079 } 5080 return reg_types_.FromClass(descriptor, klass, precise); 5081 } 5082 5083 } // namespace 5084 } // namespace impl 5085 5086 MethodVerifier::MethodVerifier(Thread* self, 5087 const DexFile* dex_file, 5088 const dex::CodeItem* code_item, 5089 uint32_t dex_method_idx, 5090 bool can_load_classes, 5091 bool allow_thread_suspension, 5092 bool allow_soft_failures) 5093 : self_(self), 5094 arena_stack_(Runtime::Current()->GetArenaPool()), 5095 allocator_(&arena_stack_), 5096 reg_types_(can_load_classes, allocator_, allow_thread_suspension), 5097 reg_table_(allocator_), 5098 work_insn_idx_(dex::kDexNoIndex), 5099 dex_method_idx_(dex_method_idx), 5100 dex_file_(dex_file), 5101 code_item_accessor_(*dex_file, code_item), 5102 have_pending_hard_failure_(false), 5103 have_pending_runtime_throw_failure_(false), 5104 have_pending_experimental_failure_(false), 5105 have_any_pending_runtime_throw_failure_(false), 5106 encountered_failure_types_(0), 5107 can_load_classes_(can_load_classes), 5108 allow_soft_failures_(allow_soft_failures), 5109 has_check_casts_(false), 5110 link_(nullptr) { 5111 self->PushVerifier(this); 5112 } 5113 5114 MethodVerifier::~MethodVerifier() { 5115 Thread::Current()->PopVerifier(this); 5116 STLDeleteElements(&failure_messages_); 5117 } 5118 5119 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, 5120 uint32_t method_idx, 5121 const DexFile* dex_file, 5122 Handle<mirror::DexCache> dex_cache, 5123 Handle<mirror::ClassLoader> class_loader, 5124 const dex::ClassDef& class_def, 5125 const dex::CodeItem* code_item, 5126 ArtMethod* method, 5127 uint32_t method_access_flags, 5128 CompilerCallbacks* callbacks, 5129 bool allow_soft_failures, 5130 HardFailLogMode log_level, 5131 bool need_precise_constants, 5132 uint32_t api_level, 5133 std::string* hard_failure_msg) { 5134 if (VLOG_IS_ON(verifier_debug)) { 5135 return VerifyMethod<true>(self, 5136 method_idx, 5137 dex_file, 5138 dex_cache, 5139 class_loader, 5140 class_def, 5141 code_item, 5142 method, 5143 method_access_flags, 5144 callbacks, 5145 allow_soft_failures, 5146 log_level, 5147 need_precise_constants, 5148 api_level, 5149 hard_failure_msg); 5150 } else { 5151 return VerifyMethod<false>(self, 5152 method_idx, 5153 dex_file, 5154 dex_cache, 5155 class_loader, 5156 class_def, 5157 code_item, 5158 method, 5159 method_access_flags, 5160 callbacks, 5161 allow_soft_failures, 5162 log_level, 5163 need_precise_constants, 5164 api_level, 5165 hard_failure_msg); 5166 } 5167 } 5168 5169 template <bool kVerifierDebug> 5170 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, 5171 uint32_t method_idx, 5172 const DexFile* dex_file, 5173 Handle<mirror::DexCache> dex_cache, 5174 Handle<mirror::ClassLoader> class_loader, 5175 const dex::ClassDef& class_def, 5176 const dex::CodeItem* code_item, 5177 ArtMethod* method, 5178 uint32_t method_access_flags, 5179 CompilerCallbacks* callbacks, 5180 bool allow_soft_failures, 5181 HardFailLogMode log_level, 5182 bool need_precise_constants, 5183 uint32_t api_level, 5184 std::string* hard_failure_msg) { 5185 MethodVerifier::FailureData result; 5186 uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0; 5187 5188 impl::MethodVerifier<kVerifierDebug> verifier(self, 5189 dex_file, 5190 dex_cache, 5191 class_loader, 5192 class_def, 5193 code_item, 5194 method_idx, 5195 method, 5196 method_access_flags, 5197 /* can_load_classes= */ true, 5198 allow_soft_failures, 5199 need_precise_constants, 5200 /* verify to dump */ false, 5201 /* allow_thread_suspension= */ true, 5202 api_level); 5203 if (verifier.Verify()) { 5204 // Verification completed, however failures may be pending that didn't cause the verification 5205 // to hard fail. 5206 CHECK(!verifier.have_pending_hard_failure_); 5207 5208 if (code_item != nullptr && callbacks != nullptr) { 5209 // Let the interested party know that the method was verified. 5210 callbacks->MethodVerified(&verifier); 5211 } 5212 5213 if (verifier.failures_.size() != 0) { 5214 if (VLOG_IS_ON(verifier)) { 5215 verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in " 5216 << dex_file->PrettyMethod(method_idx) << "\n"); 5217 } 5218 if (kVerifierDebug) { 5219 LOG(INFO) << verifier.info_messages_.str(); 5220 verifier.Dump(LOG_STREAM(INFO)); 5221 } 5222 result.kind = FailureKind::kSoftFailure; 5223 if (method != nullptr && 5224 !CanCompilerHandleVerificationFailure(verifier.encountered_failure_types_)) { 5225 method->SetDontCompile(); 5226 } 5227 } 5228 if (method != nullptr) { 5229 if (verifier.HasInstructionThatWillThrow()) { 5230 method->SetDontCompile(); 5231 if (Runtime::Current()->IsAotCompiler() && 5232 (callbacks != nullptr) && !callbacks->IsBootImage()) { 5233 // When compiling apps, make HasInstructionThatWillThrow a soft error to trigger 5234 // re-verification at runtime. 5235 // The dead code after the throw is not verified and might be invalid. This may cause 5236 // the JIT compiler to crash since it assumes that all the code is valid. 5237 // 5238 // There's a strong assumption that the entire boot image is verified and all its dex 5239 // code is valid (even the dead and unverified one). As such this is done only for apps. 5240 // (CompilerDriver DCHECKs in VerifyClassVisitor that methods from boot image are 5241 // fully verified). 5242 result.kind = FailureKind::kSoftFailure; 5243 } 5244 } 5245 if ((verifier.encountered_failure_types_ & VerifyError::VERIFY_ERROR_LOCKING) != 0) { 5246 method->SetMustCountLocks(); 5247 } 5248 } 5249 } else { 5250 // Bad method data. 5251 CHECK_NE(verifier.failures_.size(), 0U); 5252 5253 if (UNLIKELY(verifier.have_pending_experimental_failure_)) { 5254 // Failed due to being forced into interpreter. This is ok because 5255 // we just want to skip verification. 5256 result.kind = FailureKind::kSoftFailure; 5257 } else { 5258 CHECK(verifier.have_pending_hard_failure_); 5259 if (VLOG_IS_ON(verifier)) { 5260 log_level = std::max(HardFailLogMode::kLogVerbose, log_level); 5261 } 5262 if (log_level >= HardFailLogMode::kLogVerbose) { 5263 LogSeverity severity; 5264 switch (log_level) { 5265 case HardFailLogMode::kLogVerbose: 5266 severity = LogSeverity::VERBOSE; 5267 break; 5268 case HardFailLogMode::kLogWarning: 5269 severity = LogSeverity::WARNING; 5270 break; 5271 case HardFailLogMode::kLogInternalFatal: 5272 severity = LogSeverity::FATAL_WITHOUT_ABORT; 5273 break; 5274 default: 5275 LOG(FATAL) << "Unsupported log-level " << static_cast<uint32_t>(log_level); 5276 UNREACHABLE(); 5277 } 5278 verifier.DumpFailures(LOG_STREAM(severity) << "Verification error in " 5279 << dex_file->PrettyMethod(method_idx) 5280 << "\n"); 5281 } 5282 if (hard_failure_msg != nullptr) { 5283 CHECK(!verifier.failure_messages_.empty()); 5284 *hard_failure_msg = 5285 verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str(); 5286 } 5287 result.kind = FailureKind::kHardFailure; 5288 5289 if (callbacks != nullptr) { 5290 // Let the interested party know that we failed the class. 5291 ClassReference ref(dex_file, dex_file->GetIndexForClassDef(class_def)); 5292 callbacks->ClassRejected(ref); 5293 } 5294 } 5295 if (kVerifierDebug || VLOG_IS_ON(verifier)) { 5296 LOG(ERROR) << verifier.info_messages_.str(); 5297 verifier.Dump(LOG_STREAM(ERROR)); 5298 } 5299 // Under verifier-debug, dump the complete log into the error message. 5300 if (kVerifierDebug && hard_failure_msg != nullptr) { 5301 hard_failure_msg->append("\n"); 5302 hard_failure_msg->append(verifier.info_messages_.str()); 5303 hard_failure_msg->append("\n"); 5304 std::ostringstream oss; 5305 verifier.Dump(oss); 5306 hard_failure_msg->append(oss.str()); 5307 } 5308 } 5309 if (kTimeVerifyMethod) { 5310 uint64_t duration_ns = NanoTime() - start_ns; 5311 if (duration_ns > MsToNs(Runtime::Current()->GetVerifierLoggingThresholdMs())) { 5312 LOG(WARNING) << "Verification of " << dex_file->PrettyMethod(method_idx) 5313 << " took " << PrettyDuration(duration_ns) 5314 << (impl::IsLargeMethod(verifier.CodeItem()) ? " (large method)" : ""); 5315 } 5316 } 5317 result.types = verifier.encountered_failure_types_; 5318 return result; 5319 } 5320 5321 MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self, 5322 VariableIndentationOutputStream* vios, 5323 uint32_t dex_method_idx, 5324 const DexFile* dex_file, 5325 Handle<mirror::DexCache> dex_cache, 5326 Handle<mirror::ClassLoader> class_loader, 5327 const dex::ClassDef& class_def, 5328 const dex::CodeItem* code_item, 5329 ArtMethod* method, 5330 uint32_t method_access_flags, 5331 uint32_t api_level) { 5332 impl::MethodVerifier<false>* verifier = new impl::MethodVerifier<false>( 5333 self, 5334 dex_file, 5335 dex_cache, 5336 class_loader, 5337 class_def, 5338 code_item, 5339 dex_method_idx, 5340 method, 5341 method_access_flags, 5342 /* can_load_classes= */ true, 5343 /* allow_soft_failures= */ true, 5344 /* need_precise_constants= */ true, 5345 /* verify_to_dump= */ true, 5346 /* allow_thread_suspension= */ true, 5347 api_level); 5348 verifier->Verify(); 5349 verifier->DumpFailures(vios->Stream()); 5350 vios->Stream() << verifier->info_messages_.str(); 5351 // Only dump and return if no hard failures. Otherwise the verifier may be not fully initialized 5352 // and querying any info is dangerous/can abort. 5353 if (verifier->have_pending_hard_failure_) { 5354 delete verifier; 5355 return nullptr; 5356 } else { 5357 verifier->Dump(vios); 5358 return verifier; 5359 } 5360 } 5361 5362 void MethodVerifier::FindLocksAtDexPc( 5363 ArtMethod* m, 5364 uint32_t dex_pc, 5365 std::vector<MethodVerifier::DexLockInfo>* monitor_enter_dex_pcs, 5366 uint32_t api_level) { 5367 StackHandleScope<2> hs(Thread::Current()); 5368 Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); 5369 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); 5370 impl::MethodVerifier<false> verifier(hs.Self(), 5371 m->GetDexFile(), 5372 dex_cache, 5373 class_loader, 5374 m->GetClassDef(), 5375 m->GetCodeItem(), 5376 m->GetDexMethodIndex(), 5377 m, 5378 m->GetAccessFlags(), 5379 /* can_load_classes= */ false, 5380 /* allow_soft_failures= */ true, 5381 /* need_precise_constants= */ false, 5382 /* verify_to_dump= */ false, 5383 /* allow_thread_suspension= */ false, 5384 api_level); 5385 verifier.interesting_dex_pc_ = dex_pc; 5386 verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs; 5387 verifier.FindLocksAtDexPc(); 5388 } 5389 5390 MethodVerifier* MethodVerifier::CreateVerifier(Thread* self, 5391 const DexFile* dex_file, 5392 Handle<mirror::DexCache> dex_cache, 5393 Handle<mirror::ClassLoader> class_loader, 5394 const dex::ClassDef& class_def, 5395 const dex::CodeItem* code_item, 5396 uint32_t method_idx, 5397 ArtMethod* method, 5398 uint32_t access_flags, 5399 bool can_load_classes, 5400 bool allow_soft_failures, 5401 bool need_precise_constants, 5402 bool verify_to_dump, 5403 bool allow_thread_suspension, 5404 uint32_t api_level) { 5405 return new impl::MethodVerifier<false>(self, 5406 dex_file, 5407 dex_cache, 5408 class_loader, 5409 class_def, 5410 code_item, 5411 method_idx, 5412 method, 5413 access_flags, 5414 can_load_classes, 5415 allow_soft_failures, 5416 need_precise_constants, 5417 verify_to_dump, 5418 allow_thread_suspension, 5419 api_level); 5420 } 5421 5422 void MethodVerifier::Init() { 5423 art::verifier::RegTypeCache::Init(); 5424 } 5425 5426 void MethodVerifier::Shutdown() { 5427 verifier::RegTypeCache::ShutDown(); 5428 } 5429 5430 void MethodVerifier::VisitStaticRoots(RootVisitor* visitor) { 5431 RegTypeCache::VisitStaticRoots(visitor); 5432 } 5433 5434 void MethodVerifier::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) { 5435 reg_types_.VisitRoots(visitor, root_info); 5436 } 5437 5438 std::ostream& MethodVerifier::Fail(VerifyError error) { 5439 // Mark the error type as encountered. 5440 encountered_failure_types_ |= static_cast<uint32_t>(error); 5441 5442 switch (error) { 5443 case VERIFY_ERROR_NO_CLASS: 5444 case VERIFY_ERROR_NO_FIELD: 5445 case VERIFY_ERROR_NO_METHOD: 5446 case VERIFY_ERROR_ACCESS_CLASS: 5447 case VERIFY_ERROR_ACCESS_FIELD: 5448 case VERIFY_ERROR_ACCESS_METHOD: 5449 case VERIFY_ERROR_INSTANTIATION: 5450 case VERIFY_ERROR_CLASS_CHANGE: 5451 case VERIFY_ERROR_FORCE_INTERPRETER: 5452 case VERIFY_ERROR_LOCKING: 5453 if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) { 5454 // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx, 5455 // class change and instantiation errors into soft verification errors so that we re-verify 5456 // at runtime. We may fail to find or to agree on access because of not yet available class 5457 // loaders, or class loaders that will differ at runtime. In these cases, we don't want to 5458 // affect the soundness of the code being compiled. Instead, the generated code runs "slow 5459 // paths" that dynamically perform the verification and cause the behavior to be that akin 5460 // to an interpreter. 5461 error = VERIFY_ERROR_BAD_CLASS_SOFT; 5462 } else { 5463 // If we fail again at runtime, mark that this instruction would throw and force this 5464 // method to be executed using the interpreter with checks. 5465 have_pending_runtime_throw_failure_ = true; 5466 5467 // We need to save the work_line if the instruction wasn't throwing before. Otherwise we'll 5468 // try to merge garbage. 5469 // Note: this assumes that Fail is called before we do any work_line modifications. 5470 // Note: this can fail before we touch any instruction, for the signature of a method. So 5471 // add a check. 5472 if (work_insn_idx_ < dex::kDexNoIndex) { 5473 const Instruction& inst = code_item_accessor_.InstructionAt(work_insn_idx_); 5474 int opcode_flags = Instruction::FlagsOf(inst.Opcode()); 5475 5476 if ((opcode_flags & Instruction::kThrow) == 0 && 5477 GetInstructionFlags(work_insn_idx_).IsInTry()) { 5478 saved_line_->CopyFromLine(work_line_.get()); 5479 } 5480 } 5481 } 5482 break; 5483 5484 // Indication that verification should be retried at runtime. 5485 case VERIFY_ERROR_BAD_CLASS_SOFT: 5486 if (!allow_soft_failures_) { 5487 have_pending_hard_failure_ = true; 5488 } 5489 break; 5490 5491 // Hard verification failures at compile time will still fail at runtime, so the class is 5492 // marked as rejected to prevent it from being compiled. 5493 case VERIFY_ERROR_BAD_CLASS_HARD: { 5494 have_pending_hard_failure_ = true; 5495 break; 5496 } 5497 } 5498 failures_.push_back(error); 5499 std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(), 5500 work_insn_idx_)); 5501 std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate); 5502 failure_messages_.push_back(failure_message); 5503 return *failure_message; 5504 } 5505 5506 ScopedNewLine MethodVerifier::LogVerifyInfo() { 5507 ScopedNewLine ret{info_messages_}; 5508 ret << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_) 5509 << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : "; 5510 return ret; 5511 } 5512 5513 static FailureKind FailureKindMax(FailureKind fk1, FailureKind fk2) { 5514 static_assert(FailureKind::kNoFailure < FailureKind::kSoftFailure 5515 && FailureKind::kSoftFailure < FailureKind::kHardFailure, 5516 "Unexpected FailureKind order"); 5517 return std::max(fk1, fk2); 5518 } 5519 5520 void MethodVerifier::FailureData::Merge(const MethodVerifier::FailureData& fd) { 5521 kind = FailureKindMax(kind, fd.kind); 5522 types |= fd.types; 5523 } 5524 5525 } // namespace verifier 5526 } // namespace art 5527