Home | History | Annotate | Download | only in verifier
      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/macros.h"
     28 #include "base/scoped_arena_containers.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 "reg_type_cache.h"
     36 #include "register_line.h"
     37 #include "verifier_enums.h"
     38 
     39 namespace art {
     40 
     41 class ClassLinker;
     42 class CompilerCallbacks;
     43 class DexFile;
     44 class Instruction;
     45 struct ReferenceMap2Visitor;
     46 class Thread;
     47 class VariableIndentationOutputStream;
     48 
     49 namespace dex {
     50 struct ClassDef;
     51 struct CodeItem;
     52 }  // namespace dex
     53 
     54 namespace mirror {
     55 class DexCache;
     56 }  // namespace mirror
     57 
     58 namespace verifier {
     59 
     60 class MethodVerifier;
     61 class RegisterLine;
     62 using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>;
     63 class RegType;
     64 struct ScopedNewLine;
     65 
     66 // We don't need to store the register data for many instructions, because we either only need
     67 // it at branch points (for verification) or GC points and branches (for verification +
     68 // type-precise register analysis).
     69 enum RegisterTrackingMode {
     70   kTrackRegsBranches,
     71   kTrackCompilerInterestPoints,
     72   kTrackRegsAll,
     73 };
     74 
     75 // A mapping from a dex pc to the register line statuses as they are immediately prior to the
     76 // execution of that instruction.
     77 class PcToRegisterLineTable {
     78  public:
     79   explicit PcToRegisterLineTable(ScopedArenaAllocator& allocator);
     80   ~PcToRegisterLineTable();
     81 
     82   // Initialize the RegisterTable. Every instruction address can have a different set of information
     83   // about what's in which register, but for verification purposes we only need to store it at
     84   // branch target addresses (because we merge into that).
     85   void Init(RegisterTrackingMode mode,
     86             InstructionFlags* flags,
     87             uint32_t insns_size,
     88             uint16_t registers_size,
     89             ScopedArenaAllocator& allocator,
     90             RegTypeCache* reg_types);
     91 
     92   bool IsInitialized() const {
     93     return !register_lines_.empty();
     94   }
     95 
     96   RegisterLine* GetLine(size_t idx) const {
     97     return register_lines_[idx].get();
     98   }
     99 
    100  private:
    101   ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_;
    102 
    103   DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable);
    104 };
    105 
    106 // The verifier
    107 class MethodVerifier {
    108  public:
    109   static MethodVerifier* VerifyMethodAndDump(Thread* self,
    110                                              VariableIndentationOutputStream* vios,
    111                                              uint32_t method_idx,
    112                                              const DexFile* dex_file,
    113                                              Handle<mirror::DexCache> dex_cache,
    114                                              Handle<mirror::ClassLoader> class_loader,
    115                                              const dex::ClassDef& class_def,
    116                                              const dex::CodeItem* code_item, ArtMethod* method,
    117                                              uint32_t method_access_flags,
    118                                              uint32_t api_level)
    119       REQUIRES_SHARED(Locks::mutator_lock_);
    120 
    121   const DexFile& GetDexFile() const {
    122     DCHECK(dex_file_ != nullptr);
    123     return *dex_file_;
    124   }
    125 
    126   RegTypeCache* GetRegTypeCache() {
    127     return &reg_types_;
    128   }
    129 
    130   // Log a verification failure.
    131   std::ostream& Fail(VerifyError error);
    132 
    133   // Log for verification information.
    134   ScopedNewLine LogVerifyInfo();
    135 
    136   // Information structure for a lock held at a certain point in time.
    137   struct DexLockInfo {
    138     // The registers aliasing the lock.
    139     std::set<uint32_t> dex_registers;
    140     // The dex PC of the monitor-enter instruction.
    141     uint32_t dex_pc;
    142 
    143     explicit DexLockInfo(uint32_t dex_pc_in) {
    144       dex_pc = dex_pc_in;
    145     }
    146   };
    147   // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
    148   // to the locks held at 'dex_pc' in method 'm'.
    149   // Note: this is the only situation where the verifier will visit quickened instructions.
    150   static void FindLocksAtDexPc(ArtMethod* m,
    151                                uint32_t dex_pc,
    152                                std::vector<DexLockInfo>* monitor_enter_dex_pcs,
    153                                uint32_t api_level)
    154       REQUIRES_SHARED(Locks::mutator_lock_);
    155 
    156   static void Init() REQUIRES_SHARED(Locks::mutator_lock_);
    157   static void Shutdown();
    158 
    159   virtual ~MethodVerifier();
    160 
    161   static void VisitStaticRoots(RootVisitor* visitor)
    162       REQUIRES_SHARED(Locks::mutator_lock_);
    163   void VisitRoots(RootVisitor* visitor, const RootInfo& roots)
    164       REQUIRES_SHARED(Locks::mutator_lock_);
    165 
    166   // Accessors used by the compiler via CompilerCallback
    167   const CodeItemDataAccessor& CodeItem() const {
    168     return code_item_accessor_;
    169   }
    170   RegisterLine* GetRegLine(uint32_t dex_pc);
    171   ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const;
    172 
    173   MethodReference GetMethodReference() const;
    174   bool HasCheckCasts() const;
    175   bool HasFailures() const;
    176   bool HasInstructionThatWillThrow() const {
    177     return have_any_pending_runtime_throw_failure_;
    178   }
    179 
    180   virtual const RegType& ResolveCheckedClass(dex::TypeIndex class_idx)
    181       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
    182 
    183   uint32_t GetEncounteredFailureTypes() {
    184     return encountered_failure_types_;
    185   }
    186 
    187  protected:
    188   MethodVerifier(Thread* self,
    189                  const DexFile* dex_file,
    190                  const dex::CodeItem* code_item,
    191                  uint32_t dex_method_idx,
    192                  bool can_load_classes,
    193                  bool allow_thread_suspension,
    194                  bool allow_soft_failures)
    195       REQUIRES_SHARED(Locks::mutator_lock_);
    196 
    197   // Verification result for method(s). Includes a (maximum) failure kind, and (the union of)
    198   // all failure types.
    199   struct FailureData : ValueObject {
    200     FailureKind kind = FailureKind::kNoFailure;
    201     uint32_t types = 0U;
    202 
    203     // Merge src into this. Uses the most severe failure kind, and the union of types.
    204     void Merge(const FailureData& src);
    205   };
    206 
    207   /*
    208    * Perform verification on a single method.
    209    *
    210    * We do this in three passes:
    211    *  (1) Walk through all code units, determining instruction locations,
    212    *      widths, and other characteristics.
    213    *  (2) Walk through all code units, performing static checks on
    214    *      operands.
    215    *  (3) Iterate through the method, checking type safety and looking
    216    *      for code flow problems.
    217    */
    218   static FailureData VerifyMethod(Thread* self,
    219                                   uint32_t method_idx,
    220                                   const DexFile* dex_file,
    221                                   Handle<mirror::DexCache> dex_cache,
    222                                   Handle<mirror::ClassLoader> class_loader,
    223                                   const dex::ClassDef& class_def_idx,
    224                                   const dex::CodeItem* code_item,
    225                                   ArtMethod* method,
    226                                   uint32_t method_access_flags,
    227                                   CompilerCallbacks* callbacks,
    228                                   bool allow_soft_failures,
    229                                   HardFailLogMode log_level,
    230                                   bool need_precise_constants,
    231                                   uint32_t api_level,
    232                                   std::string* hard_failure_msg)
    233       REQUIRES_SHARED(Locks::mutator_lock_);
    234 
    235   template <bool kVerifierDebug>
    236   static FailureData VerifyMethod(Thread* self,
    237                                   uint32_t method_idx,
    238                                   const DexFile* dex_file,
    239                                   Handle<mirror::DexCache> dex_cache,
    240                                   Handle<mirror::ClassLoader> class_loader,
    241                                   const dex::ClassDef& class_def_idx,
    242                                   const dex::CodeItem* code_item,
    243                                   ArtMethod* method,
    244                                   uint32_t method_access_flags,
    245                                   CompilerCallbacks* callbacks,
    246                                   bool allow_soft_failures,
    247                                   HardFailLogMode log_level,
    248                                   bool need_precise_constants,
    249                                   uint32_t api_level,
    250                                   std::string* hard_failure_msg)
    251       REQUIRES_SHARED(Locks::mutator_lock_);
    252 
    253   // For VerifierDepsTest. TODO: Refactor.
    254 
    255   // Run verification on the method. Returns true if verification completes and false if the input
    256   // has an irrecoverable corruption.
    257   virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
    258   static MethodVerifier* CreateVerifier(Thread* self,
    259                                         const DexFile* dex_file,
    260                                         Handle<mirror::DexCache> dex_cache,
    261                                         Handle<mirror::ClassLoader> class_loader,
    262                                         const dex::ClassDef& class_def,
    263                                         const dex::CodeItem* code_item,
    264                                         uint32_t method_idx,
    265                                         ArtMethod* method,
    266                                         uint32_t access_flags,
    267                                         bool can_load_classes,
    268                                         bool allow_soft_failures,
    269                                         bool need_precise_constants,
    270                                         bool verify_to_dump,
    271                                         bool allow_thread_suspension,
    272                                         uint32_t api_level)
    273       REQUIRES_SHARED(Locks::mutator_lock_);
    274 
    275   // The thread we're verifying on.
    276   Thread* const self_;
    277 
    278   // Arena allocator.
    279   ArenaStack arena_stack_;
    280   ScopedArenaAllocator allocator_;
    281 
    282   RegTypeCache reg_types_;
    283 
    284   PcToRegisterLineTable reg_table_;
    285 
    286   // Storage for the register status we're currently working on.
    287   RegisterLineArenaUniquePtr work_line_;
    288 
    289   // The address of the instruction we're currently working on, note that this is in 2 byte
    290   // quantities
    291   uint32_t work_insn_idx_;
    292 
    293   // Storage for the register status we're saving for later.
    294   RegisterLineArenaUniquePtr saved_line_;
    295 
    296   const uint32_t dex_method_idx_;  // The method we're working on.
    297   const DexFile* const dex_file_;  // The dex file containing the method.
    298   const CodeItemDataAccessor code_item_accessor_;
    299 
    300   // Instruction widths and flags, one entry per code unit.
    301   // Owned, but not unique_ptr since insn_flags_ are allocated in arenas.
    302   ArenaUniquePtr<InstructionFlags[]> insn_flags_;
    303 
    304   // The types of any error that occurs.
    305   std::vector<VerifyError> failures_;
    306   // Error messages associated with failures.
    307   std::vector<std::ostringstream*> failure_messages_;
    308   // Is there a pending hard failure?
    309   bool have_pending_hard_failure_;
    310   // Is there a pending runtime throw failure? A runtime throw failure is when an instruction
    311   // would fail at runtime throwing an exception. Such an instruction causes the following code
    312   // to be unreachable. This is set by Fail and used to ensure we don't process unreachable
    313   // instructions that would hard fail the verification.
    314   // Note: this flag is reset after processing each instruction.
    315   bool have_pending_runtime_throw_failure_;
    316   // Is there a pending experimental failure?
    317   bool have_pending_experimental_failure_;
    318 
    319   // A version of the above that is not reset and thus captures if there were *any* throw failures.
    320   bool have_any_pending_runtime_throw_failure_;
    321 
    322   // Info message log use primarily for verifier diagnostics.
    323   std::ostringstream info_messages_;
    324 
    325   // Bitset of the encountered failure types. Bits are according to the values in VerifyError.
    326   uint32_t encountered_failure_types_;
    327 
    328   const bool can_load_classes_;
    329 
    330   // Converts soft failures to hard failures when false. Only false when the compiler isn't
    331   // running and the verifier is called from the class linker.
    332   const bool allow_soft_failures_;
    333 
    334   // Indicates the method being verified contains at least one check-cast or aput-object
    335   // instruction. Aput-object operations implicitly check for array-store exceptions, similar to
    336   // check-cast.
    337   bool has_check_casts_;
    338 
    339   // Link, for the method verifier root linked list.
    340   MethodVerifier* link_;
    341 
    342   friend class art::Thread;
    343   friend class ClassVerifier;
    344   friend class VerifierDepsTest;
    345 
    346   DISALLOW_COPY_AND_ASSIGN(MethodVerifier);
    347 };
    348 
    349 }  // namespace verifier
    350 }  // namespace art
    351 
    352 #endif  // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
    353