blob: 3000217697240d4d3ed6ad88cd644fe5c28f081d [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
jeffhao10037c82012-01-23 15:06:23 -080016
17#include "dex_file_verifier.h"
18
Narayan Kamath92572be2013-11-28 14:06:24 +000019#include <zlib.h>
Ian Rogers700a4022014-05-19 16:49:03 -070020#include <memory>
Narayan Kamath92572be2013-11-28 14:06:24 +000021
Elliott Hughese222ee02012-12-13 14:41:43 -080022#include "base/stringprintf.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070023#include "dex_file-inl.h"
jeffhao10037c82012-01-23 15:06:23 -080024#include "leb128.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070025#include "safe_map.h"
Ian Rogersa6724902013-09-23 09:23:37 -070026#include "utf-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027#include "utils.h"
jeffhao10037c82012-01-23 15:06:23 -080028
29namespace art {
30
31static uint32_t MapTypeToBitMask(uint32_t map_type) {
32 switch (map_type) {
33 case DexFile::kDexTypeHeaderItem: return 1 << 0;
34 case DexFile::kDexTypeStringIdItem: return 1 << 1;
35 case DexFile::kDexTypeTypeIdItem: return 1 << 2;
36 case DexFile::kDexTypeProtoIdItem: return 1 << 3;
37 case DexFile::kDexTypeFieldIdItem: return 1 << 4;
38 case DexFile::kDexTypeMethodIdItem: return 1 << 5;
39 case DexFile::kDexTypeClassDefItem: return 1 << 6;
40 case DexFile::kDexTypeMapList: return 1 << 7;
41 case DexFile::kDexTypeTypeList: return 1 << 8;
42 case DexFile::kDexTypeAnnotationSetRefList: return 1 << 9;
43 case DexFile::kDexTypeAnnotationSetItem: return 1 << 10;
44 case DexFile::kDexTypeClassDataItem: return 1 << 11;
45 case DexFile::kDexTypeCodeItem: return 1 << 12;
46 case DexFile::kDexTypeStringDataItem: return 1 << 13;
47 case DexFile::kDexTypeDebugInfoItem: return 1 << 14;
48 case DexFile::kDexTypeAnnotationItem: return 1 << 15;
49 case DexFile::kDexTypeEncodedArrayItem: return 1 << 16;
50 case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 17;
51 }
52 return 0;
53}
54
55static bool IsDataSectionType(uint32_t map_type) {
56 switch (map_type) {
57 case DexFile::kDexTypeHeaderItem:
58 case DexFile::kDexTypeStringIdItem:
59 case DexFile::kDexTypeTypeIdItem:
60 case DexFile::kDexTypeProtoIdItem:
61 case DexFile::kDexTypeFieldIdItem:
62 case DexFile::kDexTypeMethodIdItem:
63 case DexFile::kDexTypeClassDefItem:
64 return false;
65 }
66 return true;
67}
68
Andreas Gampee09269c2014-06-06 18:45:35 -070069const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070070 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumStringIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070071 return nullptr;
72 }
73 return dex_file_->StringDataByIdx(idx);
74}
75
76const char* DexFileVerifier::CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070077 if (UNLIKELY(!CheckIndex(type_idx, dex_file_->NumTypeIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070078 return nullptr;
79 }
80 const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx);
81 uint32_t idx = type_id.descriptor_idx_;
82 return CheckLoadStringByIdx(idx, error_string);
83}
84
85const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070086 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070087 return nullptr;
88 }
89 return &dex_file_->GetFieldId(idx);
90}
91
92const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070093 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070094 return nullptr;
95 }
96 return &dex_file_->GetMethodId(idx);
97}
98
99// Helper macro to load string and return false on error.
100#define LOAD_STRING(var, idx, error) \
101 const char* var = CheckLoadStringByIdx(idx, error); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700102 if (UNLIKELY(var == nullptr)) { \
Andreas Gampee09269c2014-06-06 18:45:35 -0700103 return false; \
104 }
105
106// Helper macro to load string by type idx and return false on error.
107#define LOAD_STRING_BY_TYPE(var, type_idx, error) \
108 const char* var = CheckLoadStringByTypeIdx(type_idx, error); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700109 if (UNLIKELY(var == nullptr)) { \
Andreas Gampee09269c2014-06-06 18:45:35 -0700110 return false; \
111 }
112
113// Helper macro to load method id. Return last parameter on error.
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700114#define LOAD_METHOD(var, idx, error_string, error_stmt) \
Andreas Gampee09269c2014-06-06 18:45:35 -0700115 const DexFile::MethodId* var = CheckLoadMethodId(idx, error_string); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700116 if (UNLIKELY(var == nullptr)) { \
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700117 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700118 }
119
120// Helper macro to load method id. Return last parameter on error.
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700121#define LOAD_FIELD(var, idx, fmt, error_stmt) \
Andreas Gampee09269c2014-06-06 18:45:35 -0700122 const DexFile::FieldId* var = CheckLoadFieldId(idx, fmt); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700123 if (UNLIKELY(var == nullptr)) { \
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700124 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700125 }
126
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700127bool DexFileVerifier::Verify(const DexFile* dex_file, const byte* begin, size_t size,
128 const char* location, std::string* error_msg) {
Ian Rogers700a4022014-05-19 16:49:03 -0700129 std::unique_ptr<DexFileVerifier> verifier(new DexFileVerifier(dex_file, begin, size, location));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700130 if (!verifier->Verify()) {
131 *error_msg = verifier->FailureReason();
132 return false;
133 }
134 return true;
135}
136
137bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
138 bool is_return_type) {
jeffhao10037c82012-01-23 15:06:23 -0800139 switch (shorty_char) {
140 case 'V':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700141 if (UNLIKELY(!is_return_type)) {
142 ErrorStringPrintf("Invalid use of void");
jeffhao10037c82012-01-23 15:06:23 -0800143 return false;
144 }
145 // Intentional fallthrough.
146 case 'B':
147 case 'C':
148 case 'D':
149 case 'F':
150 case 'I':
151 case 'J':
152 case 'S':
153 case 'Z':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700154 if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
155 ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
156 shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800157 return false;
158 }
159 break;
160 case 'L':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700161 if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
162 ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800163 return false;
164 }
165 break;
166 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700167 ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
jeffhao10037c82012-01-23 15:06:23 -0800168 return false;
169 }
170 return true;
171}
172
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700173bool DexFileVerifier::CheckPointerRange(const void* start, const void* end, const char* label) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800174 const byte* range_start = reinterpret_cast<const byte*>(start);
175 const byte* range_end = reinterpret_cast<const byte*>(end);
176 const byte* file_start = reinterpret_cast<const byte*>(begin_);
177 const byte* file_end = file_start + size_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700178 if (UNLIKELY((range_start < file_start) || (range_start > file_end) ||
179 (range_end < file_start) || (range_end > file_end))) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800180 ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
Ian Rogerse3d55812014-06-11 13:00:44 -0700181 static_cast<size_t>(range_start - file_start),
182 static_cast<size_t>(range_end - file_start));
jeffhao10037c82012-01-23 15:06:23 -0800183 return false;
184 }
185 return true;
186}
187
188bool DexFileVerifier::CheckListSize(const void* start, uint32_t count,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700189 uint32_t element_size, const char* label) {
jeffhao10037c82012-01-23 15:06:23 -0800190 const byte* list_start = reinterpret_cast<const byte*>(start);
191 return CheckPointerRange(list_start, list_start + (count * element_size), label);
192}
193
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700194bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
195 if (UNLIKELY(field >= limit)) {
196 ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
jeffhao10037c82012-01-23 15:06:23 -0800197 return false;
198 }
199 return true;
200}
201
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700202bool DexFileVerifier::CheckHeader() {
jeffhaof6174e82012-01-31 16:14:17 -0800203 // Check file size from the header.
204 uint32_t expected_size = header_->file_size_;
205 if (size_ != expected_size) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700206 ErrorStringPrintf("Bad file size (%zd, expected %ud)", size_, expected_size);
jeffhao10037c82012-01-23 15:06:23 -0800207 return false;
208 }
209
210 // Compute and verify the checksum in the header.
211 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
212 const uint32_t non_sum = sizeof(header_->magic_) + sizeof(header_->checksum_);
213 const byte* non_sum_ptr = reinterpret_cast<const byte*>(header_) + non_sum;
jeffhaof6174e82012-01-31 16:14:17 -0800214 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
jeffhao10037c82012-01-23 15:06:23 -0800215 if (adler_checksum != header_->checksum_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700216 ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
jeffhao10037c82012-01-23 15:06:23 -0800217 return false;
218 }
219
220 // Check the contents of the header.
221 if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700222 ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
jeffhao10037c82012-01-23 15:06:23 -0800223 return false;
224 }
225
226 if (header_->header_size_ != sizeof(DexFile::Header)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700227 ErrorStringPrintf("Bad header size: %ud", header_->header_size_);
jeffhao10037c82012-01-23 15:06:23 -0800228 return false;
229 }
230
231 return true;
232}
233
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700234bool DexFileVerifier::CheckMap() {
Ian Rogers30fab402012-01-23 15:43:46 -0800235 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -0800236 const DexFile::MapItem* item = map->list_;
237
238 uint32_t count = map->size_;
239 uint32_t last_offset = 0;
240 uint32_t data_item_count = 0;
241 uint32_t data_items_left = header_->data_size_;
242 uint32_t used_bits = 0;
243
244 // Sanity check the size of the map list.
245 if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
246 return false;
247 }
248
249 // Check the items listed in the map.
250 for (uint32_t i = 0; i < count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700251 if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
252 ErrorStringPrintf("Out of order map item: %x then %x", last_offset, item->offset_);
jeffhao10037c82012-01-23 15:06:23 -0800253 return false;
254 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700255 if (UNLIKELY(item->offset_ >= header_->file_size_)) {
256 ErrorStringPrintf("Map item after end of file: %x, size %x",
257 item->offset_, header_->file_size_);
jeffhao10037c82012-01-23 15:06:23 -0800258 return false;
259 }
260
261 if (IsDataSectionType(item->type_)) {
262 uint32_t icount = item->size_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700263 if (UNLIKELY(icount > data_items_left)) {
264 ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
jeffhao10037c82012-01-23 15:06:23 -0800265 return false;
266 }
267 data_items_left -= icount;
268 data_item_count += icount;
269 }
270
271 uint32_t bit = MapTypeToBitMask(item->type_);
272
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700273 if (UNLIKELY(bit == 0)) {
274 ErrorStringPrintf("Unknown map section type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800275 return false;
276 }
277
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700278 if (UNLIKELY((used_bits & bit) != 0)) {
279 ErrorStringPrintf("Duplicate map section of type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800280 return false;
281 }
282
283 used_bits |= bit;
284 last_offset = item->offset_;
285 item++;
286 }
287
288 // Check for missing sections in the map.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700289 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
290 ErrorStringPrintf("Map is missing header entry");
jeffhao10037c82012-01-23 15:06:23 -0800291 return false;
292 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700293 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
294 ErrorStringPrintf("Map is missing map_list entry");
jeffhao10037c82012-01-23 15:06:23 -0800295 return false;
296 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700297 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
298 ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
299 ErrorStringPrintf("Map is missing string_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800300 return false;
301 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700302 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
303 ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
304 ErrorStringPrintf("Map is missing type_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800305 return false;
306 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700307 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
308 ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
309 ErrorStringPrintf("Map is missing proto_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800310 return false;
311 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700312 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
313 ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
314 ErrorStringPrintf("Map is missing field_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800315 return false;
316 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700317 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
318 ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
319 ErrorStringPrintf("Map is missing method_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800320 return false;
321 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700322 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
323 ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
324 ErrorStringPrintf("Map is missing class_defs entry");
jeffhao10037c82012-01-23 15:06:23 -0800325 return false;
326 }
jeffhao10037c82012-01-23 15:06:23 -0800327 return true;
328}
329
330uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
331 uint32_t result = 0;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700332 if (LIKELY(CheckPointerRange(ptr_, ptr_ + size, "encoded_value"))) {
333 for (uint32_t i = 0; i < size; i++) {
334 result |= ((uint32_t) *(ptr_++)) << (i * 8);
335 }
jeffhao10037c82012-01-23 15:06:23 -0800336 }
jeffhao10037c82012-01-23 15:06:23 -0800337 return result;
338}
339
340bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700341 uint32_t* handler_offsets, uint32_t handlers_size) {
jeffhao10037c82012-01-23 15:06:23 -0800342 const byte* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
343
344 for (uint32_t i = 0; i < handlers_size; i++) {
345 bool catch_all;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800346 size_t offset = ptr_ - handlers_base;
jeffhao10037c82012-01-23 15:06:23 -0800347 int32_t size = DecodeSignedLeb128(&ptr_);
348
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700349 if (UNLIKELY((size < -65536) || (size > 65536))) {
350 ErrorStringPrintf("Invalid exception handler size: %d", size);
jeffhao10037c82012-01-23 15:06:23 -0800351 return false;
352 }
353
354 if (size <= 0) {
355 catch_all = true;
356 size = -size;
357 } else {
358 catch_all = false;
359 }
360
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800361 handler_offsets[i] = static_cast<uint32_t>(offset);
jeffhao10037c82012-01-23 15:06:23 -0800362
363 while (size-- > 0) {
364 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
365 if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
366 return false;
367 }
368
369 uint32_t addr = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700370 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
371 ErrorStringPrintf("Invalid handler addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800372 return false;
373 }
374 }
375
376 if (catch_all) {
377 uint32_t addr = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700378 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
379 ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800380 return false;
381 }
382 }
383 }
384
385 return true;
386}
387
388bool DexFileVerifier::CheckClassDataItemField(uint32_t idx, uint32_t access_flags,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700389 bool expect_static) {
jeffhao10037c82012-01-23 15:06:23 -0800390 if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
391 return false;
392 }
393
394 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700395 if (UNLIKELY(is_static != expect_static)) {
396 ErrorStringPrintf("Static/instance field not in expected list");
jeffhao10037c82012-01-23 15:06:23 -0800397 return false;
398 }
399
400 uint32_t access_field_mask = kAccPublic | kAccPrivate | kAccProtected | kAccStatic |
401 kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700402 if (UNLIKELY((access_flags & ~access_field_mask) != 0)) {
403 ErrorStringPrintf("Bad class_data_item field access_flags %x", access_flags);
jeffhao10037c82012-01-23 15:06:23 -0800404 return false;
405 }
406
407 return true;
408}
409
410bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx, uint32_t access_flags,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700411 uint32_t code_offset, bool expect_direct) {
jeffhao10037c82012-01-23 15:06:23 -0800412 if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
413 return false;
414 }
415
416 bool is_direct = (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
417 bool expect_code = (access_flags & (kAccNative | kAccAbstract)) == 0;
418 bool is_synchronized = (access_flags & kAccSynchronized) != 0;
419 bool allow_synchronized = (access_flags & kAccNative) != 0;
420
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700421 if (UNLIKELY(is_direct != expect_direct)) {
422 ErrorStringPrintf("Direct/virtual method not in expected list");
jeffhao10037c82012-01-23 15:06:23 -0800423 return false;
424 }
425
426 uint32_t access_method_mask = kAccPublic | kAccPrivate | kAccProtected | kAccStatic |
427 kAccFinal | kAccSynchronized | kAccBridge | kAccVarargs | kAccNative | kAccAbstract |
428 kAccStrict | kAccSynthetic | kAccConstructor | kAccDeclaredSynchronized;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700429 if (UNLIKELY(((access_flags & ~access_method_mask) != 0) ||
430 (is_synchronized && !allow_synchronized))) {
431 ErrorStringPrintf("Bad class_data_item method access_flags %x", access_flags);
jeffhao10037c82012-01-23 15:06:23 -0800432 return false;
433 }
434
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700435 if (UNLIKELY(expect_code && (code_offset == 0))) {
436 ErrorStringPrintf("Unexpected zero value for class_data_item method code_off with access "
437 "flags %x", access_flags);
jeffhao10037c82012-01-23 15:06:23 -0800438 return false;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700439 } else if (UNLIKELY(!expect_code && (code_offset != 0))) {
440 ErrorStringPrintf("Unexpected non-zero value %x for class_data_item method code_off"
441 " with access flags %x", code_offset, access_flags);
jeffhao10037c82012-01-23 15:06:23 -0800442 return false;
443 }
444
445 return true;
446}
447
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800448bool DexFileVerifier::CheckPadding(size_t offset, uint32_t aligned_offset) {
jeffhao10037c82012-01-23 15:06:23 -0800449 if (offset < aligned_offset) {
Ian Rogers30fab402012-01-23 15:43:46 -0800450 if (!CheckPointerRange(begin_ + offset, begin_ + aligned_offset, "section")) {
jeffhao10037c82012-01-23 15:06:23 -0800451 return false;
452 }
453 while (offset < aligned_offset) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700454 if (UNLIKELY(*ptr_ != '\0')) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800455 ErrorStringPrintf("Non-zero padding %x before section start at %zx", *ptr_, offset);
jeffhao10037c82012-01-23 15:06:23 -0800456 return false;
457 }
458 ptr_++;
459 offset++;
460 }
461 }
462 return true;
463}
464
465bool DexFileVerifier::CheckEncodedValue() {
466 if (!CheckPointerRange(ptr_, ptr_ + 1, "encoded_value header")) {
467 return false;
468 }
469
470 uint8_t header_byte = *(ptr_++);
471 uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
472 uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
473
474 switch (value_type) {
475 case DexFile::kDexAnnotationByte:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700476 if (UNLIKELY(value_arg != 0)) {
477 ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800478 return false;
479 }
480 ptr_++;
481 break;
482 case DexFile::kDexAnnotationShort:
483 case DexFile::kDexAnnotationChar:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700484 if (UNLIKELY(value_arg > 1)) {
485 ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800486 return false;
487 }
488 ptr_ += value_arg + 1;
489 break;
490 case DexFile::kDexAnnotationInt:
491 case DexFile::kDexAnnotationFloat:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700492 if (UNLIKELY(value_arg > 3)) {
493 ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800494 return false;
495 }
496 ptr_ += value_arg + 1;
497 break;
498 case DexFile::kDexAnnotationLong:
499 case DexFile::kDexAnnotationDouble:
500 ptr_ += value_arg + 1;
501 break;
502 case DexFile::kDexAnnotationString: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700503 if (UNLIKELY(value_arg > 3)) {
504 ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800505 return false;
506 }
507 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
508 if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
509 return false;
510 }
511 break;
512 }
513 case DexFile::kDexAnnotationType: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700514 if (UNLIKELY(value_arg > 3)) {
515 ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800516 return false;
517 }
518 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
519 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
520 return false;
521 }
522 break;
523 }
524 case DexFile::kDexAnnotationField:
525 case DexFile::kDexAnnotationEnum: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700526 if (UNLIKELY(value_arg > 3)) {
527 ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800528 return false;
529 }
530 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
531 if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
532 return false;
533 }
534 break;
535 }
536 case DexFile::kDexAnnotationMethod: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700537 if (UNLIKELY(value_arg > 3)) {
538 ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800539 return false;
540 }
541 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
542 if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
543 return false;
544 }
545 break;
546 }
547 case DexFile::kDexAnnotationArray:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700548 if (UNLIKELY(value_arg != 0)) {
549 ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800550 return false;
551 }
552 if (!CheckEncodedArray()) {
553 return false;
554 }
555 break;
556 case DexFile::kDexAnnotationAnnotation:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700557 if (UNLIKELY(value_arg != 0)) {
558 ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800559 return false;
560 }
561 if (!CheckEncodedAnnotation()) {
562 return false;
563 }
564 break;
565 case DexFile::kDexAnnotationNull:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700566 if (UNLIKELY(value_arg != 0)) {
567 ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800568 return false;
569 }
570 break;
571 case DexFile::kDexAnnotationBoolean:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700572 if (UNLIKELY(value_arg > 1)) {
573 ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800574 return false;
575 }
576 break;
577 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700578 ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
jeffhao10037c82012-01-23 15:06:23 -0800579 return false;
580 }
581
582 return true;
583}
584
585bool DexFileVerifier::CheckEncodedArray() {
586 uint32_t size = DecodeUnsignedLeb128(&ptr_);
587
588 while (size--) {
589 if (!CheckEncodedValue()) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700590 failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800591 return false;
592 }
593 }
594 return true;
595}
596
597bool DexFileVerifier::CheckEncodedAnnotation() {
598 uint32_t idx = DecodeUnsignedLeb128(&ptr_);
599 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
600 return false;
601 }
602
603 uint32_t size = DecodeUnsignedLeb128(&ptr_);
604 uint32_t last_idx = 0;
605
606 for (uint32_t i = 0; i < size; i++) {
607 idx = DecodeUnsignedLeb128(&ptr_);
608 if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
609 return false;
610 }
611
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700612 if (UNLIKELY(last_idx >= idx && i != 0)) {
613 ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
614 last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -0800615 return false;
616 }
617
618 if (!CheckEncodedValue()) {
619 return false;
620 }
621
622 last_idx = idx;
623 }
624 return true;
625}
626
627bool DexFileVerifier::CheckIntraClassDataItem() {
628 ClassDataItemIterator it(*dex_file_, ptr_);
629
630 for (; it.HasNextStaticField(); it.Next()) {
631 if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetMemberAccessFlags(), true)) {
632 return false;
633 }
634 }
635 for (; it.HasNextInstanceField(); it.Next()) {
636 if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetMemberAccessFlags(), false)) {
637 return false;
638 }
639 }
640 for (; it.HasNextDirectMethod(); it.Next()) {
641 if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetMemberAccessFlags(),
642 it.GetMethodCodeItemOffset(), true)) {
643 return false;
644 }
645 }
646 for (; it.HasNextVirtualMethod(); it.Next()) {
647 if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetMemberAccessFlags(),
648 it.GetMethodCodeItemOffset(), false)) {
649 return false;
650 }
651 }
652
653 ptr_ = it.EndDataPointer();
654 return true;
655}
656
657bool DexFileVerifier::CheckIntraCodeItem() {
658 const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
659 if (!CheckPointerRange(code_item, code_item + 1, "code")) {
660 return false;
661 }
662
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700663 if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
664 ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
665 code_item->ins_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800666 return false;
667 }
668
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700669 if (UNLIKELY((code_item->outs_size_ > 5) &&
670 (code_item->outs_size_ > code_item->registers_size_))) {
jeffhao10037c82012-01-23 15:06:23 -0800671 /*
672 * outs_size can be up to 5, even if registers_size is smaller, since the
673 * short forms of method invocation allow repetitions of a register multiple
674 * times within a single parameter list. However, longer parameter lists
675 * need to be represented in-order in the register file.
676 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700677 ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
678 code_item->outs_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800679 return false;
680 }
681
682 const uint16_t* insns = code_item->insns_;
683 uint32_t insns_size = code_item->insns_size_in_code_units_;
684 if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
685 return false;
686 }
687
688 // Grab the end of the insns if there are no try_items.
689 uint32_t try_items_size = code_item->tries_size_;
690 if (try_items_size == 0) {
691 ptr_ = reinterpret_cast<const byte*>(&insns[insns_size]);
692 return true;
693 }
694
695 // try_items are 4-byte aligned. Verify the spacer is 0.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800696 if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700697 ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -0800698 return false;
699 }
700
701 const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
702 ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
703 uint32_t handlers_size = DecodeUnsignedLeb128(&ptr_);
704
705 if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
706 return false;
707 }
708
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700709 if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
710 ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
jeffhao10037c82012-01-23 15:06:23 -0800711 return false;
712 }
713
Ian Rogers700a4022014-05-19 16:49:03 -0700714 std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
Elliott Hughesee0fa762012-03-26 17:12:41 -0700715 if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
jeffhao10037c82012-01-23 15:06:23 -0800716 return false;
717 }
718
719 uint32_t last_addr = 0;
720 while (try_items_size--) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700721 if (UNLIKELY(try_items->start_addr_ < last_addr)) {
722 ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -0800723 return false;
724 }
725
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700726 if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
727 ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -0800728 return false;
729 }
730
731 uint32_t i;
732 for (i = 0; i < handlers_size; i++) {
733 if (try_items->handler_off_ == handler_offsets[i]) {
734 break;
735 }
736 }
737
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700738 if (UNLIKELY(i == handlers_size)) {
739 ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
jeffhao10037c82012-01-23 15:06:23 -0800740 return false;
741 }
742
743 last_addr = try_items->start_addr_ + try_items->insn_count_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700744 if (UNLIKELY(last_addr > insns_size)) {
745 ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
jeffhao10037c82012-01-23 15:06:23 -0800746 return false;
747 }
748
749 try_items++;
750 }
751
752 return true;
753}
754
755bool DexFileVerifier::CheckIntraStringDataItem() {
756 uint32_t size = DecodeUnsignedLeb128(&ptr_);
jeffhaof6174e82012-01-31 16:14:17 -0800757 const byte* file_end = begin_ + size_;
jeffhao10037c82012-01-23 15:06:23 -0800758
759 for (uint32_t i = 0; i < size; i++) {
Brian Carlstromc6475642014-05-27 11:14:12 -0700760 CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700761 if (UNLIKELY(ptr_ >= file_end)) {
762 ErrorStringPrintf("String data would go beyond end-of-file");
jeffhao10037c82012-01-23 15:06:23 -0800763 return false;
764 }
765
766 uint8_t byte = *(ptr_++);
767
768 // Switch on the high 4 bits.
769 switch (byte >> 4) {
770 case 0x00:
771 // Special case of bit pattern 0xxx.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700772 if (UNLIKELY(byte == 0)) {
Brian Carlstromc6475642014-05-27 11:14:12 -0700773 CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700774 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
jeffhao10037c82012-01-23 15:06:23 -0800775 return false;
776 }
777 break;
778 case 0x01:
779 case 0x02:
780 case 0x03:
781 case 0x04:
782 case 0x05:
783 case 0x06:
784 case 0x07:
785 // No extra checks necessary for bit pattern 0xxx.
786 break;
787 case 0x08:
788 case 0x09:
789 case 0x0a:
790 case 0x0b:
791 case 0x0f:
792 // Illegal bit patterns 10xx or 1111.
793 // Note: 1111 is valid for normal UTF-8, but not here.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700794 ErrorStringPrintf("Illegal start byte %x in string data", byte);
jeffhao10037c82012-01-23 15:06:23 -0800795 return false;
796 case 0x0c:
797 case 0x0d: {
798 // Bit pattern 110x has an additional byte.
799 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700800 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
801 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -0800802 return false;
803 }
804 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700805 if (UNLIKELY((value != 0) && (value < 0x80))) {
806 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -0800807 return false;
808 }
809 break;
810 }
811 case 0x0e: {
812 // Bit pattern 1110 has 2 additional bytes.
813 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700814 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
815 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -0800816 return false;
817 }
818 uint8_t byte3 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700819 if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
820 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
jeffhao10037c82012-01-23 15:06:23 -0800821 return false;
822 }
823 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700824 if (UNLIKELY(value < 0x800)) {
825 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -0800826 return false;
827 }
828 break;
829 }
830 }
831 }
832
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700833 if (UNLIKELY(*(ptr_++) != '\0')) {
834 ErrorStringPrintf("String longer than indicated size %x", size);
jeffhao10037c82012-01-23 15:06:23 -0800835 return false;
836 }
837
838 return true;
839}
840
841bool DexFileVerifier::CheckIntraDebugInfoItem() {
842 DecodeUnsignedLeb128(&ptr_);
843 uint32_t parameters_size = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700844 if (UNLIKELY(parameters_size > 65536)) {
845 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
jeffhao10037c82012-01-23 15:06:23 -0800846 return false;
847 }
848
849 for (uint32_t j = 0; j < parameters_size; j++) {
850 uint32_t parameter_name = DecodeUnsignedLeb128(&ptr_);
851 if (parameter_name != 0) {
852 parameter_name--;
853 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
854 return false;
855 }
856 }
857 }
858
859 while (true) {
860 uint8_t opcode = *(ptr_++);
861 switch (opcode) {
862 case DexFile::DBG_END_SEQUENCE: {
863 return true;
864 }
865 case DexFile::DBG_ADVANCE_PC: {
866 DecodeUnsignedLeb128(&ptr_);
867 break;
868 }
869 case DexFile::DBG_ADVANCE_LINE: {
870 DecodeSignedLeb128(&ptr_);
871 break;
872 }
873 case DexFile::DBG_START_LOCAL: {
874 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700875 if (UNLIKELY(reg_num >= 65536)) {
876 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -0800877 return false;
878 }
879 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
880 if (name_idx != 0) {
881 name_idx--;
882 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
883 return false;
884 }
885 }
886 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
887 if (type_idx != 0) {
888 type_idx--;
889 if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL type_idx")) {
890 return false;
891 }
892 }
893 break;
894 }
895 case DexFile::DBG_END_LOCAL:
896 case DexFile::DBG_RESTART_LOCAL: {
897 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700898 if (UNLIKELY(reg_num >= 65536)) {
899 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -0800900 return false;
901 }
902 break;
903 }
904 case DexFile::DBG_START_LOCAL_EXTENDED: {
905 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700906 if (UNLIKELY(reg_num >= 65536)) {
907 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -0800908 return false;
909 }
910 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
911 if (name_idx != 0) {
912 name_idx--;
913 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
914 return false;
915 }
916 }
917 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
918 if (type_idx != 0) {
919 type_idx--;
920 if (!CheckIndex(type_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
921 return false;
922 }
923 }
924 uint32_t sig_idx = DecodeUnsignedLeb128(&ptr_);
925 if (sig_idx != 0) {
926 sig_idx--;
927 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
928 return false;
929 }
930 }
931 break;
932 }
933 case DexFile::DBG_SET_FILE: {
934 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
935 if (name_idx != 0) {
936 name_idx--;
937 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
938 return false;
939 }
940 }
941 break;
942 }
943 }
944 }
945}
946
947bool DexFileVerifier::CheckIntraAnnotationItem() {
948 if (!CheckPointerRange(ptr_, ptr_ + 1, "annotation visibility")) {
949 return false;
950 }
951
952 // Check visibility
953 switch (*(ptr_++)) {
954 case DexFile::kDexVisibilityBuild:
955 case DexFile::kDexVisibilityRuntime:
956 case DexFile::kDexVisibilitySystem:
957 break;
958 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700959 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
jeffhao10037c82012-01-23 15:06:23 -0800960 return false;
961 }
962
963 if (!CheckEncodedAnnotation()) {
964 return false;
965 }
966
967 return true;
968}
969
970bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
971 const DexFile::AnnotationsDirectoryItem* item =
972 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
973 if (!CheckPointerRange(item, item + 1, "annotations_directory")) {
974 return false;
975 }
976
977 // Field annotations follow immediately after the annotations directory.
978 const DexFile::FieldAnnotationsItem* field_item =
979 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
980 uint32_t field_count = item->fields_size_;
981 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
982 return false;
983 }
984
985 uint32_t last_idx = 0;
986 for (uint32_t i = 0; i < field_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700987 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
988 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
jeffhao10037c82012-01-23 15:06:23 -0800989 return false;
990 }
991 last_idx = field_item->field_idx_;
992 field_item++;
993 }
994
995 // Method annotations follow immediately after field annotations.
996 const DexFile::MethodAnnotationsItem* method_item =
997 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
998 uint32_t method_count = item->methods_size_;
999 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1000 return false;
1001 }
1002
1003 last_idx = 0;
1004 for (uint32_t i = 0; i < method_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001005 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1006 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1007 last_idx, method_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001008 return false;
1009 }
1010 last_idx = method_item->method_idx_;
1011 method_item++;
1012 }
1013
1014 // Parameter annotations follow immediately after method annotations.
1015 const DexFile::ParameterAnnotationsItem* parameter_item =
1016 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1017 uint32_t parameter_count = item->parameters_size_;
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001018 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001019 "parameter_annotations list")) {
jeffhao10037c82012-01-23 15:06:23 -08001020 return false;
1021 }
1022
1023 last_idx = 0;
1024 for (uint32_t i = 0; i < parameter_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001025 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1026 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1027 last_idx, parameter_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001028 return false;
1029 }
1030 last_idx = parameter_item->method_idx_;
1031 parameter_item++;
1032 }
1033
1034 // Return a pointer to the end of the annotations.
1035 ptr_ = reinterpret_cast<const byte*>(parameter_item);
1036 return true;
1037}
1038
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001039bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001040 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001041 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001042 switch (type) {
1043 case DexFile::kDexTypeClassDataItem:
1044 case DexFile::kDexTypeStringDataItem:
1045 case DexFile::kDexTypeDebugInfoItem:
1046 case DexFile::kDexTypeAnnotationItem:
1047 case DexFile::kDexTypeEncodedArrayItem:
1048 alignment_mask = sizeof(uint8_t) - 1;
1049 break;
1050 default:
1051 alignment_mask = sizeof(uint32_t) - 1;
1052 break;
1053 }
1054
1055 // Iterate through the items in the section.
1056 for (uint32_t i = 0; i < count; i++) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001057 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001058
1059 // Check the padding between items.
1060 if (!CheckPadding(offset, aligned_offset)) {
1061 return false;
1062 }
1063
1064 // Check depending on the section type.
1065 switch (type) {
1066 case DexFile::kDexTypeStringIdItem: {
1067 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::StringId), "string_ids")) {
1068 return false;
1069 }
1070 ptr_ += sizeof(DexFile::StringId);
1071 break;
1072 }
1073 case DexFile::kDexTypeTypeIdItem: {
1074 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::TypeId), "type_ids")) {
1075 return false;
1076 }
1077 ptr_ += sizeof(DexFile::TypeId);
1078 break;
1079 }
1080 case DexFile::kDexTypeProtoIdItem: {
1081 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::ProtoId), "proto_ids")) {
1082 return false;
1083 }
1084 ptr_ += sizeof(DexFile::ProtoId);
1085 break;
1086 }
1087 case DexFile::kDexTypeFieldIdItem: {
1088 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::FieldId), "field_ids")) {
1089 return false;
1090 }
1091 ptr_ += sizeof(DexFile::FieldId);
1092 break;
1093 }
1094 case DexFile::kDexTypeMethodIdItem: {
1095 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::MethodId), "method_ids")) {
1096 return false;
1097 }
1098 ptr_ += sizeof(DexFile::MethodId);
1099 break;
1100 }
1101 case DexFile::kDexTypeClassDefItem: {
1102 if (!CheckPointerRange(ptr_, ptr_ + sizeof(DexFile::ClassDef), "class_defs")) {
1103 return false;
1104 }
1105 ptr_ += sizeof(DexFile::ClassDef);
1106 break;
1107 }
1108 case DexFile::kDexTypeTypeList: {
1109 const DexFile::TypeList* list = reinterpret_cast<const DexFile::TypeList*>(ptr_);
1110 const DexFile::TypeItem* item = &list->GetTypeItem(0);
1111 uint32_t count = list->Size();
1112
1113 if (!CheckPointerRange(list, list + 1, "type_list") ||
1114 !CheckListSize(item, count, sizeof(DexFile::TypeItem), "type_list size")) {
1115 return false;
1116 }
1117 ptr_ = reinterpret_cast<const byte*>(item + count);
1118 break;
1119 }
1120 case DexFile::kDexTypeAnnotationSetRefList: {
1121 const DexFile::AnnotationSetRefList* list =
1122 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
1123 const DexFile::AnnotationSetRefItem* item = list->list_;
1124 uint32_t count = list->size_;
1125
1126 if (!CheckPointerRange(list, list + 1, "annotation_set_ref_list") ||
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001127 !CheckListSize(item, count, sizeof(DexFile::AnnotationSetRefItem),
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001128 "annotation_set_ref_list size")) {
jeffhao10037c82012-01-23 15:06:23 -08001129 return false;
1130 }
1131 ptr_ = reinterpret_cast<const byte*>(item + count);
1132 break;
1133 }
1134 case DexFile::kDexTypeAnnotationSetItem: {
1135 const DexFile::AnnotationSetItem* set =
1136 reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
1137 const uint32_t* item = set->entries_;
1138 uint32_t count = set->size_;
1139
1140 if (!CheckPointerRange(set, set + 1, "annotation_set_item") ||
1141 !CheckListSize(item, count, sizeof(uint32_t), "annotation_set_item size")) {
1142 return false;
1143 }
1144 ptr_ = reinterpret_cast<const byte*>(item + count);
1145 break;
1146 }
1147 case DexFile::kDexTypeClassDataItem: {
1148 if (!CheckIntraClassDataItem()) {
1149 return false;
1150 }
1151 break;
1152 }
1153 case DexFile::kDexTypeCodeItem: {
1154 if (!CheckIntraCodeItem()) {
1155 return false;
1156 }
1157 break;
1158 }
1159 case DexFile::kDexTypeStringDataItem: {
1160 if (!CheckIntraStringDataItem()) {
1161 return false;
1162 }
1163 break;
1164 }
1165 case DexFile::kDexTypeDebugInfoItem: {
1166 if (!CheckIntraDebugInfoItem()) {
1167 return false;
1168 }
1169 break;
1170 }
1171 case DexFile::kDexTypeAnnotationItem: {
1172 if (!CheckIntraAnnotationItem()) {
1173 return false;
1174 }
1175 break;
1176 }
1177 case DexFile::kDexTypeEncodedArrayItem: {
1178 if (!CheckEncodedArray()) {
1179 return false;
1180 }
1181 break;
1182 }
1183 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1184 if (!CheckIntraAnnotationsDirectoryItem()) {
1185 return false;
1186 }
1187 break;
1188 }
1189 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001190 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001191 return false;
1192 }
1193
1194 if (IsDataSectionType(type)) {
Elliott Hughesa0e18062012-04-13 15:59:59 -07001195 offset_to_type_map_.Put(aligned_offset, type);
jeffhao10037c82012-01-23 15:06:23 -08001196 }
1197
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001198 aligned_offset = ptr_ - begin_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001199 if (UNLIKELY(aligned_offset > size_)) {
1200 ErrorStringPrintf("Item %d at ends out of bounds", i);
jeffhao10037c82012-01-23 15:06:23 -08001201 return false;
1202 }
1203
1204 offset = aligned_offset;
1205 }
1206
1207 return true;
1208}
1209
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001210bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001211 uint32_t expected_offset;
1212 uint32_t expected_size;
1213
1214 // Get the expected offset and size from the header.
1215 switch (type) {
1216 case DexFile::kDexTypeStringIdItem:
1217 expected_offset = header_->string_ids_off_;
1218 expected_size = header_->string_ids_size_;
1219 break;
1220 case DexFile::kDexTypeTypeIdItem:
1221 expected_offset = header_->type_ids_off_;
1222 expected_size = header_->type_ids_size_;
1223 break;
1224 case DexFile::kDexTypeProtoIdItem:
1225 expected_offset = header_->proto_ids_off_;
1226 expected_size = header_->proto_ids_size_;
1227 break;
1228 case DexFile::kDexTypeFieldIdItem:
1229 expected_offset = header_->field_ids_off_;
1230 expected_size = header_->field_ids_size_;
1231 break;
1232 case DexFile::kDexTypeMethodIdItem:
1233 expected_offset = header_->method_ids_off_;
1234 expected_size = header_->method_ids_size_;
1235 break;
1236 case DexFile::kDexTypeClassDefItem:
1237 expected_offset = header_->class_defs_off_;
1238 expected_size = header_->class_defs_size_;
1239 break;
1240 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001241 ErrorStringPrintf("Bad type for id section: %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001242 return false;
1243 }
1244
1245 // Check that the offset and size are what were expected from the header.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001246 if (UNLIKELY(offset != expected_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001247 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
jeffhao10037c82012-01-23 15:06:23 -08001248 return false;
1249 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001250 if (UNLIKELY(count != expected_size)) {
1251 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
jeffhao10037c82012-01-23 15:06:23 -08001252 return false;
1253 }
1254
1255 return CheckIntraSectionIterate(offset, count, type);
1256}
1257
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001258bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
1259 size_t data_start = header_->data_off_;
1260 size_t data_end = data_start + header_->data_size_;
jeffhao10037c82012-01-23 15:06:23 -08001261
1262 // Sanity check the offset of the section.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001263 if (UNLIKELY((offset < data_start) || (offset > data_end))) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001264 ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
jeffhao10037c82012-01-23 15:06:23 -08001265 return false;
1266 }
1267
1268 if (!CheckIntraSectionIterate(offset, count, type)) {
1269 return false;
1270 }
1271
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001272 size_t next_offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001273 if (next_offset > data_end) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001274 ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset);
jeffhao10037c82012-01-23 15:06:23 -08001275 return false;
1276 }
1277
1278 return true;
1279}
1280
1281bool DexFileVerifier::CheckIntraSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08001282 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001283 const DexFile::MapItem* item = map->list_;
1284
1285 uint32_t count = map->size_;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001286 size_t offset = 0;
Ian Rogers30fab402012-01-23 15:43:46 -08001287 ptr_ = begin_;
jeffhao10037c82012-01-23 15:06:23 -08001288
1289 // Check the items listed in the map.
1290 while (count--) {
1291 uint32_t section_offset = item->offset_;
1292 uint32_t section_count = item->size_;
1293 uint16_t type = item->type_;
1294
1295 // Check for padding and overlap between items.
1296 if (!CheckPadding(offset, section_offset)) {
1297 return false;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001298 } else if (UNLIKELY(offset > section_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001299 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001300 return false;
1301 }
1302
1303 // Check each item based on its type.
1304 switch (type) {
1305 case DexFile::kDexTypeHeaderItem:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001306 if (UNLIKELY(section_count != 1)) {
1307 ErrorStringPrintf("Multiple header items");
jeffhao10037c82012-01-23 15:06:23 -08001308 return false;
1309 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001310 if (UNLIKELY(section_offset != 0)) {
1311 ErrorStringPrintf("Header at %x, not at start of file", section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001312 return false;
1313 }
Ian Rogers30fab402012-01-23 15:43:46 -08001314 ptr_ = begin_ + header_->header_size_;
jeffhao10037c82012-01-23 15:06:23 -08001315 offset = header_->header_size_;
1316 break;
1317 case DexFile::kDexTypeStringIdItem:
1318 case DexFile::kDexTypeTypeIdItem:
1319 case DexFile::kDexTypeProtoIdItem:
1320 case DexFile::kDexTypeFieldIdItem:
1321 case DexFile::kDexTypeMethodIdItem:
1322 case DexFile::kDexTypeClassDefItem:
1323 if (!CheckIntraIdSection(section_offset, section_count, type)) {
1324 return false;
1325 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001326 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001327 break;
1328 case DexFile::kDexTypeMapList:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001329 if (UNLIKELY(section_count != 1)) {
1330 ErrorStringPrintf("Multiple map list items");
jeffhao10037c82012-01-23 15:06:23 -08001331 return false;
1332 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001333 if (UNLIKELY(section_offset != header_->map_off_)) {
1334 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1335 section_offset, header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001336 return false;
1337 }
1338 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1339 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1340 break;
1341 case DexFile::kDexTypeTypeList:
1342 case DexFile::kDexTypeAnnotationSetRefList:
1343 case DexFile::kDexTypeAnnotationSetItem:
1344 case DexFile::kDexTypeClassDataItem:
1345 case DexFile::kDexTypeCodeItem:
1346 case DexFile::kDexTypeStringDataItem:
1347 case DexFile::kDexTypeDebugInfoItem:
1348 case DexFile::kDexTypeAnnotationItem:
1349 case DexFile::kDexTypeEncodedArrayItem:
1350 case DexFile::kDexTypeAnnotationsDirectoryItem:
1351 if (!CheckIntraDataSection(section_offset, section_count, type)) {
1352 return false;
1353 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001354 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001355 break;
1356 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001357 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001358 return false;
1359 }
1360
1361 item++;
1362 }
1363
1364 return true;
1365}
1366
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001367bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
Mathieu Chartier02e25112013-08-14 16:14:24 -07001368 auto it = offset_to_type_map_.find(offset);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001369 if (UNLIKELY(it == offset_to_type_map_.end())) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001370 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
jeffhao10037c82012-01-23 15:06:23 -08001371 return false;
1372 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001373 if (UNLIKELY(it->second != type)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001374 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001375 offset, type, it->second);
jeffhao10037c82012-01-23 15:06:23 -08001376 return false;
1377 }
1378 return true;
1379}
1380
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001381uint16_t DexFileVerifier::FindFirstClassDataDefiner(const byte* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001382 ClassDataItemIterator it(*dex_file_, ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001383 *success = true;
jeffhao10037c82012-01-23 15:06:23 -08001384
1385 if (it.HasNextStaticField() || it.HasNextInstanceField()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001386 LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
1387 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001388 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001389 }
1390
1391 if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001392 LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
1393 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001394 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001395 }
1396
1397 return DexFile::kDexNoIndex16;
1398}
1399
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001400uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const byte* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001401 const DexFile::AnnotationsDirectoryItem* item =
1402 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001403 *success = true;
1404
jeffhao10037c82012-01-23 15:06:23 -08001405 if (item->fields_size_ != 0) {
1406 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001407 LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
1408 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001409 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001410 }
1411
1412 if (item->methods_size_ != 0) {
1413 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001414 LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001415 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001416 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001417 }
1418
1419 if (item->parameters_size_ != 0) {
1420 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001421 LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001422 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001423 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001424 }
1425
1426 return DexFile::kDexNoIndex16;
1427}
1428
1429bool DexFileVerifier::CheckInterStringIdItem() {
1430 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
1431
1432 // Check the map to make sure it has the right offset->type.
1433 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
1434 return false;
1435 }
1436
1437 // Check ordering between items.
1438 if (previous_item_ != NULL) {
1439 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
1440 const char* prev_str = dex_file_->GetStringData(*prev_item);
1441 const char* str = dex_file_->GetStringData(*item);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001442 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
1443 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
jeffhao10037c82012-01-23 15:06:23 -08001444 return false;
1445 }
1446 }
1447
1448 ptr_ += sizeof(DexFile::StringId);
1449 return true;
1450}
1451
1452bool DexFileVerifier::CheckInterTypeIdItem() {
1453 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001454
1455 LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
jeffhao10037c82012-01-23 15:06:23 -08001456
1457 // Check that the descriptor is a valid type.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001458 if (UNLIKELY(!IsValidDescriptor(descriptor))) {
1459 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001460 return false;
1461 }
1462
1463 // Check ordering between items.
1464 if (previous_item_ != NULL) {
1465 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001466 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
1467 ErrorStringPrintf("Out-of-order type_ids: %x then %x",
1468 prev_item->descriptor_idx_, item->descriptor_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001469 return false;
1470 }
1471 }
1472
1473 ptr_ += sizeof(DexFile::TypeId);
1474 return true;
1475}
1476
1477bool DexFileVerifier::CheckInterProtoIdItem() {
1478 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001479
1480 LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
1481
jeffhao10037c82012-01-23 15:06:23 -08001482 if (item->parameters_off_ != 0 &&
1483 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
1484 return false;
1485 }
1486
1487 // Check the return type and advance the shorty.
Andreas Gampee09269c2014-06-06 18:45:35 -07001488 LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
1489 if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
jeffhao10037c82012-01-23 15:06:23 -08001490 return false;
1491 }
1492 shorty++;
1493
1494 DexFileParameterIterator it(*dex_file_, *item);
1495 while (it.HasNext() && *shorty != '\0') {
1496 const char* descriptor = it.GetDescriptor();
1497 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
1498 return false;
1499 }
1500 it.Next();
1501 shorty++;
1502 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001503 if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
1504 ErrorStringPrintf("Mismatched length for parameters and shorty");
jeffhao10037c82012-01-23 15:06:23 -08001505 return false;
1506 }
1507
1508 // Check ordering between items. This relies on type_ids being in order.
1509 if (previous_item_ != NULL) {
1510 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001511 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
1512 ErrorStringPrintf("Out-of-order proto_id return types");
jeffhao10037c82012-01-23 15:06:23 -08001513 return false;
1514 } else if (prev->return_type_idx_ == item->return_type_idx_) {
1515 DexFileParameterIterator curr_it(*dex_file_, *item);
1516 DexFileParameterIterator prev_it(*dex_file_, *prev);
1517
1518 while (curr_it.HasNext() && prev_it.HasNext()) {
1519 uint16_t prev_idx = prev_it.GetTypeIdx();
1520 uint16_t curr_idx = curr_it.GetTypeIdx();
1521 if (prev_idx == DexFile::kDexNoIndex16) {
1522 break;
1523 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001524 if (UNLIKELY(curr_idx == DexFile::kDexNoIndex16)) {
1525 ErrorStringPrintf("Out-of-order proto_id arguments");
jeffhao10037c82012-01-23 15:06:23 -08001526 return false;
1527 }
1528
1529 if (prev_idx < curr_idx) {
1530 break;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001531 } else if (UNLIKELY(prev_idx > curr_idx)) {
1532 ErrorStringPrintf("Out-of-order proto_id arguments");
jeffhao10037c82012-01-23 15:06:23 -08001533 return false;
1534 }
1535
1536 prev_it.Next();
1537 curr_it.Next();
1538 }
1539 }
1540 }
1541
1542 ptr_ += sizeof(DexFile::ProtoId);
1543 return true;
1544}
1545
1546bool DexFileVerifier::CheckInterFieldIdItem() {
1547 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
1548
1549 // Check that the class descriptor is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001550 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
1551 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1552 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001553 return false;
1554 }
1555
1556 // Check that the type descriptor is a valid field name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001557 LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
1558 if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
1559 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001560 return false;
1561 }
1562
1563 // Check that the name is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001564 LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001565 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1566 ErrorStringPrintf("Invalid field name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001567 return false;
1568 }
1569
1570 // Check ordering between items. This relies on the other sections being in order.
1571 if (previous_item_ != NULL) {
1572 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001573 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1574 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001575 return false;
1576 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001577 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1578 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001579 return false;
1580 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001581 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
1582 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001583 return false;
1584 }
1585 }
1586 }
1587 }
1588
1589 ptr_ += sizeof(DexFile::FieldId);
1590 return true;
1591}
1592
1593bool DexFileVerifier::CheckInterMethodIdItem() {
1594 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
1595
1596 // Check that the class descriptor is a valid reference name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001597 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
1598 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
1599 class_descriptor[0] != '['))) {
1600 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001601 return false;
1602 }
1603
1604 // Check that the name is valid.
Andreas Gampedf10b322014-06-11 21:46:05 -07001605 LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001606 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1607 ErrorStringPrintf("Invalid method name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001608 return false;
1609 }
1610
Andreas Gampedf10b322014-06-11 21:46:05 -07001611 // Check that the proto id is valid.
1612 if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
1613 "inter_method_id_item proto_idx"))) {
1614 return false;
1615 }
1616
jeffhao10037c82012-01-23 15:06:23 -08001617 // Check ordering between items. This relies on the other sections being in order.
1618 if (previous_item_ != NULL) {
1619 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001620 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1621 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001622 return false;
1623 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001624 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1625 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001626 return false;
1627 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001628 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
1629 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001630 return false;
1631 }
1632 }
1633 }
1634 }
1635
1636 ptr_ += sizeof(DexFile::MethodId);
1637 return true;
1638}
1639
1640bool DexFileVerifier::CheckInterClassDefItem() {
1641 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001642
Andreas Gampee09269c2014-06-06 18:45:35 -07001643 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
1644 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1645 ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001646 return false;
1647 }
1648
1649 if (item->interfaces_off_ != 0 &&
1650 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
1651 return false;
1652 }
1653 if (item->annotations_off_ != 0 &&
1654 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
1655 return false;
1656 }
1657 if (item->class_data_off_ != 0 &&
1658 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
1659 return false;
1660 }
1661 if (item->static_values_off_ != 0 &&
1662 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
1663 return false;
1664 }
1665
1666 if (item->superclass_idx_ != DexFile::kDexNoIndex16) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001667 LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
1668 "inter_class_def_item superclass_idx")
1669 if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
1670 ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001671 return false;
1672 }
1673 }
1674
1675 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
1676 if (interfaces != NULL) {
1677 uint32_t size = interfaces->Size();
1678
1679 // Ensure that all interfaces refer to classes (not arrays or primitives).
1680 for (uint32_t i = 0; i < size; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001681 LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
1682 "inter_class_def_item interface type_idx")
1683 if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
1684 ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001685 return false;
1686 }
1687 }
1688
1689 /*
1690 * Ensure that there are no duplicates. This is an O(N^2) test, but in
1691 * practice the number of interfaces implemented by any given class is low.
1692 */
1693 for (uint32_t i = 1; i < size; i++) {
1694 uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_;
1695 for (uint32_t j =0; j < i; j++) {
1696 uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001697 if (UNLIKELY(idx1 == idx2)) {
1698 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
jeffhao10037c82012-01-23 15:06:23 -08001699 return false;
1700 }
1701 }
1702 }
1703 }
1704
1705 // Check that references in class_data_item are to the right class.
1706 if (item->class_data_off_ != 0) {
Ian Rogers30fab402012-01-23 15:43:46 -08001707 const byte* data = begin_ + item->class_data_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001708 bool success;
1709 uint16_t data_definer = FindFirstClassDataDefiner(data, &success);
1710 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001711 return false;
1712 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001713 if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) {
1714 ErrorStringPrintf("Invalid class_data_item");
jeffhao10037c82012-01-23 15:06:23 -08001715 return false;
1716 }
1717 }
1718
1719 // Check that references in annotations_directory_item are to right class.
1720 if (item->annotations_off_ != 0) {
Ian Rogers30fab402012-01-23 15:43:46 -08001721 const byte* data = begin_ + item->annotations_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001722 bool success;
1723 uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
1724 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001725 return false;
1726 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001727 if (UNLIKELY((annotations_definer != item->class_idx_) &&
1728 (annotations_definer != DexFile::kDexNoIndex16))) {
1729 ErrorStringPrintf("Invalid annotations_directory_item");
jeffhao10037c82012-01-23 15:06:23 -08001730 return false;
1731 }
1732 }
1733
1734 ptr_ += sizeof(DexFile::ClassDef);
1735 return true;
1736}
1737
1738bool DexFileVerifier::CheckInterAnnotationSetRefList() {
1739 const DexFile::AnnotationSetRefList* list =
1740 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
1741 const DexFile::AnnotationSetRefItem* item = list->list_;
1742 uint32_t count = list->size_;
1743
1744 while (count--) {
1745 if (item->annotations_off_ != 0 &&
1746 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1747 return false;
1748 }
1749 item++;
1750 }
1751
1752 ptr_ = reinterpret_cast<const byte*>(item);
1753 return true;
1754}
1755
1756bool DexFileVerifier::CheckInterAnnotationSetItem() {
1757 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
1758 const uint32_t* offsets = set->entries_;
1759 uint32_t count = set->size_;
1760 uint32_t last_idx = 0;
1761
1762 for (uint32_t i = 0; i < count; i++) {
1763 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
1764 return false;
1765 }
1766
1767 // Get the annotation from the offset and the type index for the annotation.
1768 const DexFile::AnnotationItem* annotation =
Ian Rogers30fab402012-01-23 15:43:46 -08001769 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
jeffhao10037c82012-01-23 15:06:23 -08001770 const uint8_t* data = annotation->annotation_;
1771 uint32_t idx = DecodeUnsignedLeb128(&data);
1772
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001773 if (UNLIKELY(last_idx >= idx && i != 0)) {
1774 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -08001775 return false;
1776 }
1777
1778 last_idx = idx;
1779 offsets++;
1780 }
1781
1782 ptr_ = reinterpret_cast<const byte*>(offsets);
1783 return true;
1784}
1785
1786bool DexFileVerifier::CheckInterClassDataItem() {
1787 ClassDataItemIterator it(*dex_file_, ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001788 bool success;
1789 uint16_t defining_class = FindFirstClassDataDefiner(ptr_, &success);
1790 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001791 return false;
1792 }
jeffhao10037c82012-01-23 15:06:23 -08001793
1794 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001795 LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07001796 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001797 ErrorStringPrintf("Mismatched defining class for class_data_item field");
jeffhao10037c82012-01-23 15:06:23 -08001798 return false;
1799 }
1800 }
1801 for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) {
1802 uint32_t code_off = it.GetMethodCodeItemOffset();
1803 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
1804 return false;
1805 }
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001806 LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07001807 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001808 ErrorStringPrintf("Mismatched defining class for class_data_item method");
jeffhao10037c82012-01-23 15:06:23 -08001809 return false;
1810 }
1811 }
1812
1813 ptr_ = it.EndDataPointer();
1814 return true;
1815}
1816
1817bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
1818 const DexFile::AnnotationsDirectoryItem* item =
1819 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001820 bool success;
1821 uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
1822 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001823 return false;
1824 }
jeffhao10037c82012-01-23 15:06:23 -08001825
1826 if (item->class_annotations_off_ != 0 &&
1827 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1828 return false;
1829 }
1830
1831 // Field annotations follow immediately after the annotations directory.
1832 const DexFile::FieldAnnotationsItem* field_item =
1833 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1834 uint32_t field_count = item->fields_size_;
1835 for (uint32_t i = 0; i < field_count; i++) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001836 LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
1837 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07001838 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001839 ErrorStringPrintf("Mismatched defining class for field_annotation");
jeffhao10037c82012-01-23 15:06:23 -08001840 return false;
1841 }
1842 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1843 return false;
1844 }
1845 field_item++;
1846 }
1847
1848 // Method annotations follow immediately after field annotations.
1849 const DexFile::MethodAnnotationsItem* method_item =
1850 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1851 uint32_t method_count = item->methods_size_;
1852 for (uint32_t i = 0; i < method_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001853 LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001854 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07001855 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001856 ErrorStringPrintf("Mismatched defining class for method_annotation");
jeffhao10037c82012-01-23 15:06:23 -08001857 return false;
1858 }
1859 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
1860 return false;
1861 }
1862 method_item++;
1863 }
1864
1865 // Parameter annotations follow immediately after method annotations.
1866 const DexFile::ParameterAnnotationsItem* parameter_item =
1867 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1868 uint32_t parameter_count = item->parameters_size_;
1869 for (uint32_t i = 0; i < parameter_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001870 LOAD_METHOD(parameter_method, parameter_item->method_idx_,
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001871 "inter_annotations_directory_item parameter method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07001872 if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001873 ErrorStringPrintf("Mismatched defining class for parameter_annotation");
jeffhao10037c82012-01-23 15:06:23 -08001874 return false;
1875 }
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001876 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
1877 DexFile::kDexTypeAnnotationSetRefList)) {
jeffhao10037c82012-01-23 15:06:23 -08001878 return false;
1879 }
1880 parameter_item++;
1881 }
1882
1883 ptr_ = reinterpret_cast<const byte*>(parameter_item);
1884 return true;
1885}
1886
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001887bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001888 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001889 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001890 switch (type) {
1891 case DexFile::kDexTypeClassDataItem:
1892 alignment_mask = sizeof(uint8_t) - 1;
1893 break;
1894 default:
1895 alignment_mask = sizeof(uint32_t) - 1;
1896 break;
1897 }
1898
1899 // Iterate through the items in the section.
1900 previous_item_ = NULL;
1901 for (uint32_t i = 0; i < count; i++) {
1902 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
Ian Rogers30fab402012-01-23 15:43:46 -08001903 ptr_ = begin_ + new_offset;
jeffhao10037c82012-01-23 15:06:23 -08001904 const byte* prev_ptr = ptr_;
1905
1906 // Check depending on the section type.
1907 switch (type) {
1908 case DexFile::kDexTypeStringIdItem: {
1909 if (!CheckInterStringIdItem()) {
1910 return false;
1911 }
1912 break;
1913 }
1914 case DexFile::kDexTypeTypeIdItem: {
1915 if (!CheckInterTypeIdItem()) {
1916 return false;
1917 }
1918 break;
1919 }
1920 case DexFile::kDexTypeProtoIdItem: {
1921 if (!CheckInterProtoIdItem()) {
1922 return false;
1923 }
1924 break;
1925 }
1926 case DexFile::kDexTypeFieldIdItem: {
1927 if (!CheckInterFieldIdItem()) {
1928 return false;
1929 }
1930 break;
1931 }
1932 case DexFile::kDexTypeMethodIdItem: {
1933 if (!CheckInterMethodIdItem()) {
1934 return false;
1935 }
1936 break;
1937 }
1938 case DexFile::kDexTypeClassDefItem: {
1939 if (!CheckInterClassDefItem()) {
1940 return false;
1941 }
1942 break;
1943 }
1944 case DexFile::kDexTypeAnnotationSetRefList: {
1945 if (!CheckInterAnnotationSetRefList()) {
1946 return false;
1947 }
1948 break;
1949 }
1950 case DexFile::kDexTypeAnnotationSetItem: {
1951 if (!CheckInterAnnotationSetItem()) {
1952 return false;
1953 }
1954 break;
1955 }
1956 case DexFile::kDexTypeClassDataItem: {
1957 if (!CheckInterClassDataItem()) {
1958 return false;
1959 }
1960 break;
1961 }
1962 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1963 if (!CheckInterAnnotationsDirectoryItem()) {
1964 return false;
1965 }
1966 break;
1967 }
1968 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001969 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001970 return false;
1971 }
1972
1973 previous_item_ = prev_ptr;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001974 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001975 }
1976
1977 return true;
1978}
1979
1980bool DexFileVerifier::CheckInterSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08001981 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001982 const DexFile::MapItem* item = map->list_;
1983 uint32_t count = map->size_;
1984
1985 // Cross check the items listed in the map.
1986 while (count--) {
1987 uint32_t section_offset = item->offset_;
1988 uint32_t section_count = item->size_;
1989 uint16_t type = item->type_;
1990
1991 switch (type) {
1992 case DexFile::kDexTypeHeaderItem:
1993 case DexFile::kDexTypeMapList:
1994 case DexFile::kDexTypeTypeList:
1995 case DexFile::kDexTypeCodeItem:
1996 case DexFile::kDexTypeStringDataItem:
1997 case DexFile::kDexTypeDebugInfoItem:
1998 case DexFile::kDexTypeAnnotationItem:
1999 case DexFile::kDexTypeEncodedArrayItem:
2000 break;
2001 case DexFile::kDexTypeStringIdItem:
2002 case DexFile::kDexTypeTypeIdItem:
2003 case DexFile::kDexTypeProtoIdItem:
2004 case DexFile::kDexTypeFieldIdItem:
2005 case DexFile::kDexTypeMethodIdItem:
2006 case DexFile::kDexTypeClassDefItem:
2007 case DexFile::kDexTypeAnnotationSetRefList:
2008 case DexFile::kDexTypeAnnotationSetItem:
2009 case DexFile::kDexTypeClassDataItem:
2010 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2011 if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2012 return false;
2013 }
2014 break;
2015 }
2016 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002017 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002018 return false;
2019 }
2020
2021 item++;
2022 }
2023
2024 return true;
2025}
2026
2027bool DexFileVerifier::Verify() {
2028 // Check the header.
2029 if (!CheckHeader()) {
2030 return false;
2031 }
2032
2033 // Check the map section.
2034 if (!CheckMap()) {
2035 return false;
2036 }
2037
2038 // Check structure within remaining sections.
2039 if (!CheckIntraSection()) {
2040 return false;
2041 }
2042
2043 // Check references from one section to another.
2044 if (!CheckInterSection()) {
2045 return false;
2046 }
2047
2048 return true;
2049}
2050
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002051void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2052 va_list ap;
2053 va_start(ap, fmt);
2054 DCHECK(failure_reason_.empty()) << failure_reason_;
2055 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2056 StringAppendV(&failure_reason_, fmt, ap);
2057 va_end(ap);
2058}
2059
jeffhao10037c82012-01-23 15:06:23 -08002060} // namespace art