12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 1610037c866b04550fc5461058c398c2e3e509381ajeffhao 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_DEX_FILE_VERIFIER_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_DEX_FILE_VERIFIER_H_ 1910037c866b04550fc5461058c398c2e3e509381ajeffhao 200ba238dcc21ae3544e1e8cb5d108725db8a1c134Andreas Gampe#include <unordered_set> 210ba238dcc21ae3544e1e8cb5d108725db8a1c134Andreas Gampe 2210037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex_file.h" 23a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 2410037c866b04550fc5461058c398c2e3e509381ajeffhao 2510037c866b04550fc5461058c398c2e3e509381ajeffhaonamespace art { 2610037c866b04550fc5461058c398c2e3e509381ajeffhao 2710037c866b04550fc5461058c398c2e3e509381ajeffhaoclass DexFileVerifier { 2810037c866b04550fc5461058c398c2e3e509381ajeffhao public: 298d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers static bool Verify(const DexFile* dex_file, const byte* begin, size_t size, 308d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const char* location, std::string* error_msg); 318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const std::string& FailureReason() const { 338d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return failure_reason_; 348d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 3510037c866b04550fc5461058c398c2e3e509381ajeffhao 3610037c866b04550fc5461058c398c2e3e509381ajeffhao private: 378d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers DexFileVerifier(const DexFile* dex_file, const byte* begin, size_t size, const char* location) 388d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers : dex_file_(dex_file), begin_(begin), size_(size), location_(location), 3910037c866b04550fc5461058c398c2e3e509381ajeffhao header_(&dex_file->GetHeader()), ptr_(NULL), previous_item_(NULL) { 4010037c866b04550fc5461058c398c2e3e509381ajeffhao } 4110037c866b04550fc5461058c398c2e3e509381ajeffhao 4210037c866b04550fc5461058c398c2e3e509381ajeffhao bool Verify(); 4310037c866b04550fc5461058c398c2e3e509381ajeffhao 448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool CheckShortyDescriptorMatch(char shorty_char, const char* descriptor, bool is_return_type); 4550d1bc198b2e347d60df74c3b0c452e1f929dd2fAndreas Gampe bool CheckListSize(const void* start, size_t count, size_t element_size, const char* label); 4678d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe // Check a list. The head is assumed to be at *ptr, and elements to be of size element_size. If 4778d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe // successful, the ptr will be moved forward the amount covered by the list. 4878d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe bool CheckList(size_t element_size, const char* label, const byte* *ptr); 4978d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe // Checks whether the offset is zero (when size is zero) or that the offset falls within the area 5078d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe // claimed by the file. 5178d639ef4be3ad7314846e1e6c1261d7d30f83faAndreas Gampe bool CheckValidOffsetAndSize(uint32_t offset, uint32_t size, const char* label); 528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool CheckIndex(uint32_t field, uint32_t limit, const char* label); 5310037c866b04550fc5461058c398c2e3e509381ajeffhao 548d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool CheckHeader(); 558d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool CheckMap(); 5610037c866b04550fc5461058c398c2e3e509381ajeffhao 5710037c866b04550fc5461058c398c2e3e509381ajeffhao uint32_t ReadUnsignedLittleEndian(uint32_t size); 5810037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item, 598d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers uint32_t* handler_offsets, uint32_t handlers_size); 608d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool CheckClassDataItemField(uint32_t idx, uint32_t access_flags, bool expect_static); 6110037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags, uint32_t code_offset, 628d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool expect_direct); 638a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckPadding(size_t offset, uint32_t aligned_offset); 6410037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckEncodedValue(); 6510037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckEncodedArray(); 6610037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckEncodedAnnotation(); 6710037c866b04550fc5461058c398c2e3e509381ajeffhao 6810037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraClassDataItem(); 6910037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraCodeItem(); 7010037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraStringDataItem(); 7110037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraDebugInfoItem(); 7210037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraAnnotationItem(); 7310037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraAnnotationsDirectoryItem(); 7410037c866b04550fc5461058c398c2e3e509381ajeffhao 758a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckIntraSectionIterate(size_t offset, uint32_t count, uint16_t type); 768a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type); 778a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type); 7810037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckIntraSection(); 7910037c866b04550fc5461058c398c2e3e509381ajeffhao 808a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckOffsetToTypeMap(size_t offset, uint16_t type); 81e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe 825e31ddadd29325649260aa186e9ffa8ccdb370a2Andreas Gampe // Note: as sometimes kDexNoIndex16, being 0xFFFF, is a valid return value, we need an 835e31ddadd29325649260aa186e9ffa8ccdb370a2Andreas Gampe // additional out parameter to signal any errors loading an index. 845e31ddadd29325649260aa186e9ffa8ccdb370a2Andreas Gampe uint16_t FindFirstClassDataDefiner(const byte* ptr, bool* success); 855e31ddadd29325649260aa186e9ffa8ccdb370a2Andreas Gampe uint16_t FindFirstAnnotationsDirectoryDefiner(const byte* ptr, bool* success); 8610037c866b04550fc5461058c398c2e3e509381ajeffhao 8710037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterStringIdItem(); 8810037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterTypeIdItem(); 8910037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterProtoIdItem(); 9010037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterFieldIdItem(); 9110037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterMethodIdItem(); 9210037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterClassDefItem(); 9310037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterAnnotationSetRefList(); 9410037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterAnnotationSetItem(); 9510037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterClassDataItem(); 9610037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterAnnotationsDirectoryItem(); 9710037c866b04550fc5461058c398c2e3e509381ajeffhao 988a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers bool CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type); 9910037c866b04550fc5461058c398c2e3e509381ajeffhao bool CheckInterSection(); 10010037c866b04550fc5461058c398c2e3e509381ajeffhao 101e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe // Load a string by (type) index. Checks whether the index is in bounds, printing the error if 102e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe // not. If there is an error, nullptr is returned. 103e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe const char* CheckLoadStringByIdx(uint32_t idx, const char* error_fmt); 104e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe const char* CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_fmt); 105e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe 106e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe // Load a field/method Id by index. Checks whether the index is in bounds, printing the error if 107e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe // not. If there is an error, nullptr is returned. 108e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe const DexFile::FieldId* CheckLoadFieldId(uint32_t idx, const char* error_fmt); 109e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe const DexFile::MethodId* CheckLoadMethodId(uint32_t idx, const char* error_fmt); 110e09269ca05e3014e86198e9a2cf6092026fafefdAndreas Gampe 1118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers void ErrorStringPrintf(const char* fmt, ...) 1128d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers __attribute__((__format__(__printf__, 2, 3))) COLD_ATTR; 1138d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 1148d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const DexFile* const dex_file_; 1158d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const byte* const begin_; 1168d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const size_t size_; 1178d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const char* const location_; 1188d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const DexFile::Header* const header_; 11910037c866b04550fc5461058c398c2e3e509381ajeffhao 1205369c40f75fdcb1be7a7c06db212ce965c83a164Mathieu Chartier AllocationTrackingSafeMap<uint32_t, uint16_t, kAllocatorTagDexFileVerifier> offset_to_type_map_; 12110037c866b04550fc5461058c398c2e3e509381ajeffhao const byte* ptr_; 12210037c866b04550fc5461058c398c2e3e509381ajeffhao const void* previous_item_; 1238d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 1248d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string failure_reason_; 1250ba238dcc21ae3544e1e8cb5d108725db8a1c134Andreas Gampe 1260ba238dcc21ae3544e1e8cb5d108725db8a1c134Andreas Gampe // Set of type ids for which there are ClassDef elements in the dex file. 1270ba238dcc21ae3544e1e8cb5d108725db8a1c134Andreas Gampe std::unordered_set<decltype(DexFile::ClassDef::class_idx_)> defined_classes_; 12810037c866b04550fc5461058c398c2e3e509381ajeffhao}; 12910037c866b04550fc5461058c398c2e3e509381ajeffhao 13010037c866b04550fc5461058c398c2e3e509381ajeffhao} // namespace art 13110037c866b04550fc5461058c398c2e3e509381ajeffhao 132fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_DEX_FILE_VERIFIER_H_ 133