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