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_DEX_FILE_VERIFIER_H_ 18 #define ART_RUNTIME_DEX_FILE_VERIFIER_H_ 19 20 #include <unordered_set> 21 22 #include "dex_file.h" 23 #include "safe_map.h" 24 25 namespace art { 26 27 class DexFileVerifier { 28 public: 29 static bool Verify(const DexFile* dex_file, const byte* begin, size_t size, 30 const char* location, std::string* error_msg); 31 32 const std::string& FailureReason() const { 33 return failure_reason_; 34 } 35 36 private: 37 DexFileVerifier(const DexFile* dex_file, const byte* begin, size_t size, const char* location) 38 : dex_file_(dex_file), begin_(begin), size_(size), location_(location), 39 header_(&dex_file->GetHeader()), ptr_(NULL), previous_item_(NULL) { 40 } 41 42 bool Verify(); 43 44 bool CheckShortyDescriptorMatch(char shorty_char, const char* descriptor, bool is_return_type); 45 bool CheckListSize(const void* start, size_t count, size_t element_size, const char* label); 46 // Check a list. The head is assumed to be at *ptr, and elements to be of size element_size. If 47 // successful, the ptr will be moved forward the amount covered by the list. 48 bool CheckList(size_t element_size, const char* label, const byte* *ptr); 49 // Checks whether the offset is zero (when size is zero) or that the offset falls within the area 50 // claimed by the file. 51 bool CheckValidOffsetAndSize(uint32_t offset, uint32_t size, const char* label); 52 bool CheckIndex(uint32_t field, uint32_t limit, const char* label); 53 54 bool CheckHeader(); 55 bool CheckMap(); 56 57 uint32_t ReadUnsignedLittleEndian(uint32_t size); 58 bool CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item, 59 uint32_t* handler_offsets, uint32_t handlers_size); 60 bool CheckClassDataItemField(uint32_t idx, uint32_t access_flags, bool expect_static); 61 bool CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t code_offset, 62 bool expect_direct); 63 bool CheckPadding(size_t offset, uint32_t aligned_offset); 64 bool CheckEncodedValue(); 65 bool CheckEncodedArray(); 66 bool CheckEncodedAnnotation(); 67 68 bool CheckIntraClassDataItem(); 69 bool CheckIntraCodeItem(); 70 bool CheckIntraStringDataItem(); 71 bool CheckIntraDebugInfoItem(); 72 bool CheckIntraAnnotationItem(); 73 bool CheckIntraAnnotationsDirectoryItem(); 74 75 bool CheckIntraSectionIterate(size_t offset, uint32_t count, uint16_t type); 76 bool CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type); 77 bool CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type); 78 bool CheckIntraSection(); 79 80 bool CheckOffsetToTypeMap(size_t offset, uint16_t type); 81 82 // Note: as sometimes kDexNoIndex16, being 0xFFFF, is a valid return value, we need an 83 // additional out parameter to signal any errors loading an index. 84 uint16_t FindFirstClassDataDefiner(const byte* ptr, bool* success); 85 uint16_t FindFirstAnnotationsDirectoryDefiner(const byte* ptr, bool* success); 86 87 bool CheckInterStringIdItem(); 88 bool CheckInterTypeIdItem(); 89 bool CheckInterProtoIdItem(); 90 bool CheckInterFieldIdItem(); 91 bool CheckInterMethodIdItem(); 92 bool CheckInterClassDefItem(); 93 bool CheckInterAnnotationSetRefList(); 94 bool CheckInterAnnotationSetItem(); 95 bool CheckInterClassDataItem(); 96 bool CheckInterAnnotationsDirectoryItem(); 97 98 bool CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type); 99 bool CheckInterSection(); 100 101 // Load a string by (type) index. Checks whether the index is in bounds, printing the error if 102 // not. If there is an error, nullptr is returned. 103 const char* CheckLoadStringByIdx(uint32_t idx, const char* error_fmt); 104 const char* CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_fmt); 105 106 // Load a field/method Id by index. Checks whether the index is in bounds, printing the error if 107 // not. If there is an error, nullptr is returned. 108 const DexFile::FieldId* CheckLoadFieldId(uint32_t idx, const char* error_fmt); 109 const DexFile::MethodId* CheckLoadMethodId(uint32_t idx, const char* error_fmt); 110 111 void ErrorStringPrintf(const char* fmt, ...) 112 __attribute__((__format__(__printf__, 2, 3))) COLD_ATTR; 113 114 const DexFile* const dex_file_; 115 const byte* const begin_; 116 const size_t size_; 117 const char* const location_; 118 const DexFile::Header* const header_; 119 120 AllocationTrackingSafeMap<uint32_t, uint16_t, kAllocatorTagDexFileVerifier> offset_to_type_map_; 121 const byte* ptr_; 122 const void* previous_item_; 123 124 std::string failure_reason_; 125 126 // Set of type ids for which there are ClassDef elements in the dex file. 127 std::unordered_set<decltype(DexFile::ClassDef::class_idx_)> defined_classes_; 128 }; 129 130 } // namespace art 131 132 #endif // ART_RUNTIME_DEX_FILE_VERIFIER_H_ 133