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 #ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 18 #define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 19 20 #include <memory> 21 #include <sstream> 22 #include <vector> 23 24 #include <android-base/logging.h> 25 26 #include "base/arena_allocator.h" 27 #include "base/arena_containers.h" 28 #include "base/macros.h" 29 #include "base/value_object.h" 30 #include "dex/code_item_accessors.h" 31 #include "dex/dex_file_types.h" 32 #include "dex/method_reference.h" 33 #include "handle.h" 34 #include "instruction_flags.h" 35 #include "register_line.h" 36 #include "verifier_enums.h" 37 38 namespace art HIDDEN { 39 40 class ClassLinker; 41 class DexFile; 42 class Instruction; 43 struct ReferenceMap2Visitor; 44 class Thread; 45 class VariableIndentationOutputStream; 46 47 namespace dex { 48 struct ClassDef; 49 struct CodeItem; 50 } // namespace dex 51 52 namespace mirror { 53 class ClassLoader; 54 class DexCache; 55 } // namespace mirror 56 57 namespace verifier { 58 59 class MethodVerifier; 60 class RegType; 61 class RegTypeCache; 62 struct ScopedNewLine; 63 class VerifierDeps; 64 65 // A mapping from a dex pc to the register line statuses as they are immediately prior to the 66 // execution of that instruction. 67 class PcToRegisterLineTable { 68 public: 69 explicit PcToRegisterLineTable(ArenaAllocator& allocator); 70 ~PcToRegisterLineTable(); 71 72 // Initialize the RegisterTable. Every instruction address can have a different set of information 73 // about what's in which register, but for verification purposes we only need to store it at 74 // branch target addresses (because we merge into that). 75 void Init(InstructionFlags* flags, 76 uint32_t insns_size, 77 uint16_t registers_size, 78 ArenaAllocator& allocator, 79 RegTypeCache* reg_types, 80 uint32_t interesting_dex_pc); 81 IsInitialized()82 bool IsInitialized() const { 83 return !register_lines_.empty(); 84 } 85 GetLine(size_t idx)86 RegisterLine* GetLine(size_t idx) const { 87 return register_lines_[idx].get(); 88 } 89 90 private: 91 ArenaVector<RegisterLineArenaUniquePtr> register_lines_; 92 93 DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable); 94 }; 95 96 // The verifier 97 class MethodVerifier { 98 public: 99 EXPORT static void VerifyMethodAndDump(Thread* self, 100 VariableIndentationOutputStream* vios, 101 uint32_t method_idx, 102 const DexFile* dex_file, 103 Handle<mirror::DexCache> dex_cache, 104 Handle<mirror::ClassLoader> class_loader, 105 const dex::ClassDef& class_def, 106 const dex::CodeItem* code_item, 107 uint32_t method_access_flags, 108 uint32_t api_level) 109 REQUIRES_SHARED(Locks::mutator_lock_); 110 111 // Calculates the type information at the given `dex_pc`. 112 // No classes will be loaded. 113 EXPORT static MethodVerifier* CalculateVerificationInfo(Thread* self, 114 RegTypeCache* reg_types, 115 ArtMethod* method, 116 Handle<mirror::DexCache> dex_cache, 117 uint32_t dex_pc) 118 REQUIRES_SHARED(Locks::mutator_lock_); 119 GetDexFile()120 const DexFile& GetDexFile() const { 121 DCHECK(dex_file_ != nullptr); 122 return *dex_file_; 123 } 124 GetClassDef()125 const dex::ClassDef& GetClassDef() const { 126 return class_def_; 127 } 128 GetRegTypeCache()129 RegTypeCache* GetRegTypeCache() { 130 return ®_types_; 131 } 132 133 // Log a verification failure. 134 std::ostream& Fail(VerifyError error, bool pending_exc = true); 135 136 // Log for verification information. 137 ScopedNewLine LogVerifyInfo(); 138 139 // Information structure for a lock held at a certain point in time. 140 struct DexLockInfo { 141 // The registers aliasing the lock. 142 std::set<uint32_t> dex_registers; 143 // The dex PC of the monitor-enter instruction. 144 uint32_t dex_pc; 145 DexLockInfoDexLockInfo146 explicit DexLockInfo(uint32_t dex_pc_in) { 147 dex_pc = dex_pc_in; 148 } 149 }; 150 // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding 151 // to the locks held at 'dex_pc' in method 'm'. 152 // Note: this is the only situation where the verifier will visit quickened instructions. 153 static void FindLocksAtDexPc(ArtMethod* m, 154 uint32_t dex_pc, 155 std::vector<DexLockInfo>* monitor_enter_dex_pcs, 156 uint32_t api_level) 157 REQUIRES_SHARED(Locks::mutator_lock_); 158 159 virtual ~MethodVerifier(); 160 CodeItem()161 const CodeItemDataAccessor& CodeItem() const { 162 return code_item_accessor_; 163 } 164 RegisterLine* GetRegLine(uint32_t dex_pc); 165 ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const; 166 167 MethodReference GetMethodReference() const; 168 bool HasFailures() const; HasInstructionThatWillThrow()169 bool HasInstructionThatWillThrow() const { 170 return (encountered_failure_types_ & VERIFY_ERROR_RUNTIME_THROW) != 0; 171 } 172 GetEncounteredFailureTypes()173 uint32_t GetEncounteredFailureTypes() const { 174 return encountered_failure_types_; 175 } 176 177 ClassLinker* GetClassLinker() const; 178 IsAotMode()179 bool IsAotMode() const { 180 return const_flags_.aot_mode_; 181 } 182 CanLoadClasses()183 bool CanLoadClasses() const { 184 return const_flags_.can_load_classes_; 185 } 186 GetVerifierDeps()187 VerifierDeps* GetVerifierDeps() const { 188 return verifier_deps_; 189 } 190 191 protected: 192 MethodVerifier(Thread* self, 193 ArenaPool* arena_pool, 194 RegTypeCache* reg_types, 195 VerifierDeps* verifier_deps, 196 const dex::ClassDef& class_def, 197 const dex::CodeItem* code_item, 198 uint32_t dex_method_idx, 199 bool aot_mode) 200 REQUIRES_SHARED(Locks::mutator_lock_); 201 202 // Verification result for method(s). Includes a (maximum) failure kind, and (the union of) 203 // all failure types. 204 struct FailureData : ValueObject { 205 FailureKind kind = FailureKind::kNoFailure; 206 uint32_t types = 0U; 207 208 // Merge src into this. Uses the most severe failure kind, and the union of types. 209 void Merge(const FailureData& src); 210 }; 211 212 /* 213 * Perform verification on a single method. 214 * 215 * We do this in three passes: 216 * (1) Walk through all code units, determining instruction locations, 217 * widths, and other characteristics. 218 * (2) Walk through all code units, performing static checks on 219 * operands. 220 * (3) Iterate through the method, checking type safety and looking 221 * for code flow problems. 222 */ 223 static FailureData VerifyMethod(Thread* self, 224 ArenaPool* arena_pool, 225 RegTypeCache* reg_types, 226 VerifierDeps* verifier_deps, 227 uint32_t method_idx, 228 Handle<mirror::DexCache> dex_cache, 229 const dex::ClassDef& class_def_idx, 230 const dex::CodeItem* code_item, 231 uint32_t method_access_flags, 232 HardFailLogMode log_level, 233 uint32_t api_level, 234 bool aot_mode, 235 std::string* hard_failure_msg) 236 REQUIRES_SHARED(Locks::mutator_lock_); 237 238 template <bool kVerifierDebug> 239 static FailureData VerifyMethod(Thread* self, 240 ArenaPool* arena_pool, 241 RegTypeCache* reg_types, 242 VerifierDeps* verifier_deps, 243 uint32_t method_idx, 244 Handle<mirror::DexCache> dex_cache, 245 const dex::ClassDef& class_def_idx, 246 const dex::CodeItem* code_item, 247 uint32_t method_access_flags, 248 HardFailLogMode log_level, 249 uint32_t api_level, 250 bool aot_mode, 251 std::string* hard_failure_msg) 252 REQUIRES_SHARED(Locks::mutator_lock_); 253 254 /* 255 * Get the "this" pointer from a non-static method invocation. This returns the RegType so the 256 * caller can decide whether it needs the reference to be initialized or not. 257 * 258 * The argument count is in vA, and the first argument is in vC, for both "simple" and "range" 259 * versions. We just need to make sure vA is >= 1 and then return vC. 260 */ 261 const RegType& GetInvocationThis(const Instruction* inst) 262 REQUIRES_SHARED(Locks::mutator_lock_); 263 264 // Can a variable with type `lhs` be assigned a value with type `rhs`? 265 // Note: Object and interface types may always be assigned to one another, see 266 // comment on `ClassJoin()`. 267 bool IsAssignableFrom(const RegType& lhs, const RegType& rhs) const 268 REQUIRES_SHARED(Locks::mutator_lock_); 269 270 // Can a variable with type `lhs` be assigned a value with type `rhs`? 271 // Variant of IsAssignableFrom that doesn't allow assignment to an interface from an Object. 272 bool IsStrictlyAssignableFrom(const RegType& lhs, const RegType& rhs) const 273 REQUIRES_SHARED(Locks::mutator_lock_); 274 275 // Implementation helper for `IsAssignableFrom()` and `IsStrictlyAssignableFrom()`. 276 bool AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) const 277 REQUIRES_SHARED(Locks::mutator_lock_); 278 279 // For VerifierDepsTest. TODO: Refactor. 280 281 // Run verification on the method. Returns true if verification completes and false if the input 282 // has an irrecoverable corruption. 283 virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0; 284 static MethodVerifier* CreateVerifier(Thread* self, 285 RegTypeCache* reg_types, 286 VerifierDeps* verifier_deps, 287 Handle<mirror::DexCache> dex_cache, 288 const dex::ClassDef& class_def, 289 const dex::CodeItem* code_item, 290 uint32_t method_idx, 291 uint32_t access_flags, 292 bool verify_to_dump, 293 uint32_t api_level) 294 REQUIRES_SHARED(Locks::mutator_lock_); 295 296 virtual bool PotentiallyMarkRuntimeThrow() = 0; 297 InfoMessages()298 std::ostringstream& InfoMessages() { 299 if (!info_messages_.has_value()) { 300 info_messages_.emplace(); 301 } 302 return info_messages_.value(); 303 } 304 305 // The thread we're verifying on. 306 Thread* const self_; 307 308 // Arena allocator. 309 ArenaAllocator allocator_; 310 311 RegTypeCache& reg_types_; // TODO: Change to a pointer in a separate CL. 312 313 PcToRegisterLineTable reg_table_; 314 315 // Storage for the register status we're currently working on. 316 RegisterLineArenaUniquePtr work_line_; 317 318 // The address of the instruction we're currently working on, note that this is in 2 byte 319 // quantities 320 uint32_t work_insn_idx_; 321 322 // Storage for the register status we're saving for later. 323 RegisterLineArenaUniquePtr saved_line_; 324 325 const uint32_t dex_method_idx_; // The method we're working on. 326 const DexFile* const dex_file_; // The dex file containing the method. 327 const dex::ClassDef& class_def_; // The class being verified. 328 const CodeItemDataAccessor code_item_accessor_; 329 330 // Instruction widths and flags, one entry per code unit. 331 // Owned, but not unique_ptr since insn_flags_ are allocated in arenas. 332 ArenaUniquePtr<InstructionFlags[]> insn_flags_; 333 334 // The types of any error that occurs. 335 std::vector<VerifyError> failures_; 336 // Error messages associated with failures. 337 std::vector<std::ostringstream*> failure_messages_; 338 339 struct { 340 // Is there a pending hard failure? 341 bool have_pending_hard_failure_ : 1; 342 343 // Is there a pending runtime throw failure? A runtime throw failure is when an instruction 344 // would fail at runtime throwing an exception. Such an instruction causes the following code 345 // to be unreachable. This is set by Fail and used to ensure we don't process unreachable 346 // instructions that would hard fail the verification. 347 // Note: this flag is reset after processing each instruction. 348 bool have_pending_runtime_throw_failure_ : 1; 349 } flags_; 350 351 struct { 352 // Verify in AoT mode? 353 bool aot_mode_ : 1; 354 355 // Whether the `MethodVerifer` can load classes. 356 bool can_load_classes_ : 1; 357 } const const_flags_; 358 359 // Bitset of the encountered failure types. Bits are according to the values in VerifyError. 360 uint32_t encountered_failure_types_; 361 362 // Info message log use primarily for verifier diagnostics. 363 std::optional<std::ostringstream> info_messages_; 364 365 // The verifier deps object we are going to report type assigability 366 // constraints to. Can be null for runtime verification. 367 VerifierDeps* verifier_deps_; 368 369 // Link, for the method verifier root linked list. 370 MethodVerifier* link_; 371 372 friend class art::Thread; 373 friend class ClassVerifier; 374 friend class RegisterLineTest; 375 friend class VerifierDepsTest; 376 377 DISALLOW_COPY_AND_ASSIGN(MethodVerifier); 378 }; 379 380 } // namespace verifier 381 } // namespace art 382 383 #endif // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 384