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