xref: /aosp_15_r20/art/runtime/verifier/method_verifier.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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 &reg_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