blob: 4effed4a952a5530c9aab300383b64239275de10 [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
Andreas Gampee6215c02015-08-31 18:54:38 -070019#include <inttypes.h>
Narayan Kamath92572be2013-11-28 14:06:24 +000020#include <zlib.h>
Andreas Gampee6215c02015-08-31 18:54:38 -070021
David Sehr28e74ed2016-11-21 12:52:12 -080022#include <limits>
Ian Rogers700a4022014-05-19 16:49:03 -070023#include <memory>
Narayan Kamath92572be2013-11-28 14:06:24 +000024
Elliott Hughese222ee02012-12-13 14:41:43 -080025#include "base/stringprintf.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070026#include "dex_file-inl.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070027#include "experimental_flags.h"
jeffhao10037c82012-01-23 15:06:23 -080028#include "leb128.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070029#include "safe_map.h"
Ian Rogersa6724902013-09-23 09:23:37 -070030#include "utf-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031#include "utils.h"
jeffhao10037c82012-01-23 15:06:23 -080032
33namespace art {
34
David Sehr28e74ed2016-11-21 12:52:12 -080035static constexpr uint32_t kTypeIdLimit = std::numeric_limits<uint16_t>::max();
36
37static bool IsValidOrNoTypeId(uint16_t low, uint16_t high) {
38 return (high == 0) || ((high == 0xffffU) && (low == 0xffffU));
39}
40
41static bool IsValidTypeId(uint16_t low ATTRIBUTE_UNUSED, uint16_t high) {
42 return (high == 0);
43}
44
jeffhao10037c82012-01-23 15:06:23 -080045static uint32_t MapTypeToBitMask(uint32_t map_type) {
46 switch (map_type) {
47 case DexFile::kDexTypeHeaderItem: return 1 << 0;
48 case DexFile::kDexTypeStringIdItem: return 1 << 1;
49 case DexFile::kDexTypeTypeIdItem: return 1 << 2;
50 case DexFile::kDexTypeProtoIdItem: return 1 << 3;
51 case DexFile::kDexTypeFieldIdItem: return 1 << 4;
52 case DexFile::kDexTypeMethodIdItem: return 1 << 5;
53 case DexFile::kDexTypeClassDefItem: return 1 << 6;
54 case DexFile::kDexTypeMapList: return 1 << 7;
55 case DexFile::kDexTypeTypeList: return 1 << 8;
56 case DexFile::kDexTypeAnnotationSetRefList: return 1 << 9;
57 case DexFile::kDexTypeAnnotationSetItem: return 1 << 10;
58 case DexFile::kDexTypeClassDataItem: return 1 << 11;
59 case DexFile::kDexTypeCodeItem: return 1 << 12;
60 case DexFile::kDexTypeStringDataItem: return 1 << 13;
61 case DexFile::kDexTypeDebugInfoItem: return 1 << 14;
62 case DexFile::kDexTypeAnnotationItem: return 1 << 15;
63 case DexFile::kDexTypeEncodedArrayItem: return 1 << 16;
64 case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 17;
65 }
66 return 0;
67}
68
69static bool IsDataSectionType(uint32_t map_type) {
70 switch (map_type) {
71 case DexFile::kDexTypeHeaderItem:
72 case DexFile::kDexTypeStringIdItem:
73 case DexFile::kDexTypeTypeIdItem:
74 case DexFile::kDexTypeProtoIdItem:
75 case DexFile::kDexTypeFieldIdItem:
76 case DexFile::kDexTypeMethodIdItem:
77 case DexFile::kDexTypeClassDefItem:
78 return false;
79 }
80 return true;
81}
82
Andreas Gampee09269c2014-06-06 18:45:35 -070083const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070084 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumStringIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070085 return nullptr;
86 }
87 return dex_file_->StringDataByIdx(idx);
88}
89
Andreas Gampea5b09a62016-11-17 15:21:22 -080090const char* DexFileVerifier::CheckLoadStringByTypeIdx(dex::TypeIndex type_idx,
91 const char* error_string) {
92 if (UNLIKELY(!CheckIndex(type_idx.index_, dex_file_->NumTypeIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070093 return nullptr;
94 }
95 const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx);
96 uint32_t idx = type_id.descriptor_idx_;
97 return CheckLoadStringByIdx(idx, error_string);
98}
99
100const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -0700101 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -0700102 return nullptr;
103 }
104 return &dex_file_->GetFieldId(idx);
105}
106
107const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -0700108 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -0700109 return nullptr;
110 }
111 return &dex_file_->GetMethodId(idx);
112}
113
114// Helper macro to load string and return false on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700115#define LOAD_STRING(var, idx, error) \
116 const char* (var) = CheckLoadStringByIdx(idx, error); \
117 if (UNLIKELY((var) == nullptr)) { \
118 return false; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700119 }
120
121// Helper macro to load string by type idx and return false on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700122#define LOAD_STRING_BY_TYPE(var, type_idx, error) \
123 const char* (var) = CheckLoadStringByTypeIdx(type_idx, error); \
124 if (UNLIKELY((var) == nullptr)) { \
125 return false; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700126 }
127
128// Helper macro to load method id. Return last parameter on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700129#define LOAD_METHOD(var, idx, error_string, error_stmt) \
130 const DexFile::MethodId* (var) = CheckLoadMethodId(idx, error_string); \
131 if (UNLIKELY((var) == nullptr)) { \
132 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700133 }
134
135// Helper macro to load method id. Return last parameter on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700136#define LOAD_FIELD(var, idx, fmt, error_stmt) \
137 const DexFile::FieldId* (var) = CheckLoadFieldId(idx, fmt); \
138 if (UNLIKELY((var) == nullptr)) { \
139 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700140 }
141
Aart Bik37d6a3b2016-06-21 18:30:10 -0700142bool DexFileVerifier::Verify(const DexFile* dex_file,
143 const uint8_t* begin,
144 size_t size,
145 const char* location,
146 bool verify_checksum,
147 std::string* error_msg) {
148 std::unique_ptr<DexFileVerifier> verifier(
149 new DexFileVerifier(dex_file, begin, size, location, verify_checksum));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700150 if (!verifier->Verify()) {
151 *error_msg = verifier->FailureReason();
152 return false;
153 }
154 return true;
155}
156
157bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
158 bool is_return_type) {
jeffhao10037c82012-01-23 15:06:23 -0800159 switch (shorty_char) {
160 case 'V':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700161 if (UNLIKELY(!is_return_type)) {
162 ErrorStringPrintf("Invalid use of void");
jeffhao10037c82012-01-23 15:06:23 -0800163 return false;
164 }
Ian Rogersfc787ec2014-10-09 21:56:44 -0700165 FALLTHROUGH_INTENDED;
jeffhao10037c82012-01-23 15:06:23 -0800166 case 'B':
167 case 'C':
168 case 'D':
169 case 'F':
170 case 'I':
171 case 'J':
172 case 'S':
173 case 'Z':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700174 if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
175 ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
176 shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800177 return false;
178 }
179 break;
180 case 'L':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700181 if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
182 ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800183 return false;
184 }
185 break;
186 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700187 ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
jeffhao10037c82012-01-23 15:06:23 -0800188 return false;
189 }
190 return true;
191}
192
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700193bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700194 const char* label) {
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700195 // Check that size is not 0.
196 CHECK_NE(elem_size, 0U);
197
Ian Rogers13735952014-10-08 12:43:28 -0700198 const uint8_t* range_start = reinterpret_cast<const uint8_t*>(start);
199 const uint8_t* file_start = reinterpret_cast<const uint8_t*>(begin_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700200
201 // Check for overflow.
202 uintptr_t max = 0 - 1;
203 size_t available_bytes_till_end_of_mem = max - reinterpret_cast<uintptr_t>(start);
204 size_t max_count = available_bytes_till_end_of_mem / elem_size;
205 if (max_count < count) {
206 ErrorStringPrintf("Overflow in range for %s: %zx for %zu@%zu", label,
207 static_cast<size_t>(range_start - file_start),
208 count, elem_size);
209 return false;
210 }
211
Ian Rogers13735952014-10-08 12:43:28 -0700212 const uint8_t* range_end = range_start + count * elem_size;
213 const uint8_t* file_end = file_start + size_;
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700214 if (UNLIKELY((range_start < file_start) || (range_end > file_end))) {
215 // Note: these two tests are enough as we make sure above that there's no overflow.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800216 ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
Ian Rogerse3d55812014-06-11 13:00:44 -0700217 static_cast<size_t>(range_start - file_start),
218 static_cast<size_t>(range_end - file_start));
jeffhao10037c82012-01-23 15:06:23 -0800219 return false;
220 }
221 return true;
222}
223
Ian Rogers13735952014-10-08 12:43:28 -0700224bool DexFileVerifier::CheckList(size_t element_size, const char* label, const uint8_t* *ptr) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700225 // Check that the list is available. The first 4B are the count.
226 if (!CheckListSize(*ptr, 1, 4U, label)) {
227 return false;
228 }
229
230 uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
231 if (count > 0) {
232 if (!CheckListSize(*ptr + 4, count, element_size, label)) {
233 return false;
234 }
235 }
236
237 *ptr += 4 + count * element_size;
238 return true;
239}
240
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700241bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
242 if (UNLIKELY(field >= limit)) {
243 ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
jeffhao10037c82012-01-23 15:06:23 -0800244 return false;
245 }
246 return true;
247}
248
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800249bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset,
250 uint32_t size,
251 size_t alignment,
252 const char* label) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700253 if (size == 0) {
254 if (offset != 0) {
255 ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
256 return false;
257 }
258 }
259 if (size_ <= offset) {
260 ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
261 return false;
262 }
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800263 if (alignment != 0 && !IsAlignedParam(offset, alignment)) {
264 ErrorStringPrintf("Offset(%d) should be aligned by %zu for %s.", offset, alignment, label);
265 return false;
266 }
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700267 return true;
268}
269
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100270bool DexFileVerifier::CheckSizeLimit(uint32_t size, uint32_t limit, const char* label) {
271 if (size > limit) {
272 ErrorStringPrintf("Size(%u) should not exceed limit(%u) for %s.", size, limit, label);
273 return false;
274 }
275 return true;
276}
277
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700278bool DexFileVerifier::CheckHeader() {
jeffhaof6174e82012-01-31 16:14:17 -0800279 // Check file size from the header.
280 uint32_t expected_size = header_->file_size_;
281 if (size_ != expected_size) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700282 ErrorStringPrintf("Bad file size (%zd, expected %ud)", size_, expected_size);
jeffhao10037c82012-01-23 15:06:23 -0800283 return false;
284 }
285
286 // Compute and verify the checksum in the header.
287 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
288 const uint32_t non_sum = sizeof(header_->magic_) + sizeof(header_->checksum_);
Ian Rogers13735952014-10-08 12:43:28 -0700289 const uint8_t* non_sum_ptr = reinterpret_cast<const uint8_t*>(header_) + non_sum;
jeffhaof6174e82012-01-31 16:14:17 -0800290 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
jeffhao10037c82012-01-23 15:06:23 -0800291 if (adler_checksum != header_->checksum_) {
Aart Bik37d6a3b2016-06-21 18:30:10 -0700292 if (verify_checksum_) {
293 ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
294 return false;
295 } else {
296 LOG(WARNING) << StringPrintf(
297 "Ignoring bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
298 }
jeffhao10037c82012-01-23 15:06:23 -0800299 }
300
301 // Check the contents of the header.
302 if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700303 ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
jeffhao10037c82012-01-23 15:06:23 -0800304 return false;
305 }
306
307 if (header_->header_size_ != sizeof(DexFile::Header)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700308 ErrorStringPrintf("Bad header size: %ud", header_->header_size_);
jeffhao10037c82012-01-23 15:06:23 -0800309 return false;
310 }
311
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700312 // Check that all offsets are inside the file.
313 bool result =
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800314 CheckValidOffsetAndSize(header_->link_off_,
315 header_->link_size_,
316 0 /* unaligned */,
317 "link") &&
318 CheckValidOffsetAndSize(header_->map_off_,
319 header_->map_off_,
320 4,
321 "map") &&
322 CheckValidOffsetAndSize(header_->string_ids_off_,
323 header_->string_ids_size_,
324 4,
325 "string-ids") &&
326 CheckValidOffsetAndSize(header_->type_ids_off_,
327 header_->type_ids_size_,
328 4,
329 "type-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100330 CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800331 CheckValidOffsetAndSize(header_->proto_ids_off_,
332 header_->proto_ids_size_,
333 4,
334 "proto-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100335 CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800336 CheckValidOffsetAndSize(header_->field_ids_off_,
337 header_->field_ids_size_,
338 4,
339 "field-ids") &&
340 CheckValidOffsetAndSize(header_->method_ids_off_,
341 header_->method_ids_size_,
342 4,
343 "method-ids") &&
344 CheckValidOffsetAndSize(header_->class_defs_off_,
345 header_->class_defs_size_,
346 4,
347 "class-defs") &&
348 CheckValidOffsetAndSize(header_->data_off_,
349 header_->data_size_,
350 0, // Unaligned, spec doesn't talk about it, even though size
351 // is supposed to be a multiple of 4.
352 "data");
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700353 return result;
jeffhao10037c82012-01-23 15:06:23 -0800354}
355
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700356bool DexFileVerifier::CheckMap() {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700357 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ +
358 header_->map_off_);
359 // Check that map list content is available.
360 if (!CheckListSize(map, 1, sizeof(DexFile::MapList), "maplist content")) {
361 return false;
362 }
363
jeffhao10037c82012-01-23 15:06:23 -0800364 const DexFile::MapItem* item = map->list_;
365
366 uint32_t count = map->size_;
367 uint32_t last_offset = 0;
368 uint32_t data_item_count = 0;
369 uint32_t data_items_left = header_->data_size_;
370 uint32_t used_bits = 0;
371
372 // Sanity check the size of the map list.
373 if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
374 return false;
375 }
376
377 // Check the items listed in the map.
378 for (uint32_t i = 0; i < count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700379 if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
380 ErrorStringPrintf("Out of order map item: %x then %x", last_offset, item->offset_);
jeffhao10037c82012-01-23 15:06:23 -0800381 return false;
382 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700383 if (UNLIKELY(item->offset_ >= header_->file_size_)) {
384 ErrorStringPrintf("Map item after end of file: %x, size %x",
385 item->offset_, header_->file_size_);
jeffhao10037c82012-01-23 15:06:23 -0800386 return false;
387 }
388
389 if (IsDataSectionType(item->type_)) {
390 uint32_t icount = item->size_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700391 if (UNLIKELY(icount > data_items_left)) {
392 ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
jeffhao10037c82012-01-23 15:06:23 -0800393 return false;
394 }
395 data_items_left -= icount;
396 data_item_count += icount;
397 }
398
399 uint32_t bit = MapTypeToBitMask(item->type_);
400
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700401 if (UNLIKELY(bit == 0)) {
402 ErrorStringPrintf("Unknown map section type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800403 return false;
404 }
405
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700406 if (UNLIKELY((used_bits & bit) != 0)) {
407 ErrorStringPrintf("Duplicate map section of type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800408 return false;
409 }
410
411 used_bits |= bit;
412 last_offset = item->offset_;
413 item++;
414 }
415
416 // Check for missing sections in the map.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700417 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
418 ErrorStringPrintf("Map is missing header entry");
jeffhao10037c82012-01-23 15:06:23 -0800419 return false;
420 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700421 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
422 ErrorStringPrintf("Map is missing map_list entry");
jeffhao10037c82012-01-23 15:06:23 -0800423 return false;
424 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700425 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
426 ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
427 ErrorStringPrintf("Map is missing string_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800428 return false;
429 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700430 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
431 ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
432 ErrorStringPrintf("Map is missing type_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800433 return false;
434 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700435 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
436 ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
437 ErrorStringPrintf("Map is missing proto_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800438 return false;
439 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700440 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
441 ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
442 ErrorStringPrintf("Map is missing field_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800443 return false;
444 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700445 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
446 ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
447 ErrorStringPrintf("Map is missing method_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800448 return false;
449 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700450 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
451 ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
452 ErrorStringPrintf("Map is missing class_defs entry");
jeffhao10037c82012-01-23 15:06:23 -0800453 return false;
454 }
jeffhao10037c82012-01-23 15:06:23 -0800455 return true;
456}
457
458uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
459 uint32_t result = 0;
Ian Rogers13735952014-10-08 12:43:28 -0700460 if (LIKELY(CheckListSize(ptr_, size, sizeof(uint8_t), "encoded_value"))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700461 for (uint32_t i = 0; i < size; i++) {
462 result |= ((uint32_t) *(ptr_++)) << (i * 8);
463 }
jeffhao10037c82012-01-23 15:06:23 -0800464 }
jeffhao10037c82012-01-23 15:06:23 -0800465 return result;
466}
467
Andreas Gampebed6daf2016-09-02 18:12:00 -0700468
469#define DECODE_UNSIGNED_CHECKED_FROM_WITH_ERROR_VALUE(ptr, var, error_value) \
470 uint32_t var; \
Andreas Gampe44fd2352016-11-03 08:21:21 -0700471 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700472 return error_value; \
473 }
474
Andreas Gampe44fd2352016-11-03 08:21:21 -0700475#define DECODE_UNSIGNED_CHECKED_FROM(ptr, var) \
476 uint32_t var; \
477 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
478 ErrorStringPrintf("Read out of bounds"); \
479 return false; \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700480 }
481
Andreas Gampe44fd2352016-11-03 08:21:21 -0700482#define DECODE_SIGNED_CHECKED_FROM(ptr, var) \
483 int32_t var; \
484 if (!DecodeSignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
485 ErrorStringPrintf("Read out of bounds"); \
486 return false; \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700487 }
488
jeffhao10037c82012-01-23 15:06:23 -0800489bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700490 uint32_t* handler_offsets, uint32_t handlers_size) {
Ian Rogers13735952014-10-08 12:43:28 -0700491 const uint8_t* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -0800492
493 for (uint32_t i = 0; i < handlers_size; i++) {
494 bool catch_all;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800495 size_t offset = ptr_ - handlers_base;
Andreas Gampebed6daf2016-09-02 18:12:00 -0700496 DECODE_SIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800497
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700498 if (UNLIKELY((size < -65536) || (size > 65536))) {
499 ErrorStringPrintf("Invalid exception handler size: %d", size);
jeffhao10037c82012-01-23 15:06:23 -0800500 return false;
501 }
502
503 if (size <= 0) {
504 catch_all = true;
505 size = -size;
506 } else {
507 catch_all = false;
508 }
509
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800510 handler_offsets[i] = static_cast<uint32_t>(offset);
jeffhao10037c82012-01-23 15:06:23 -0800511
512 while (size-- > 0) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700513 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -0800514 if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
515 return false;
516 }
517
Andreas Gampebed6daf2016-09-02 18:12:00 -0700518 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700519 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
520 ErrorStringPrintf("Invalid handler addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800521 return false;
522 }
523 }
524
525 if (catch_all) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700526 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700527 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
528 ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800529 return false;
530 }
531 }
532 }
533
534 return true;
535}
536
Andreas Gampee6215c02015-08-31 18:54:38 -0700537bool DexFileVerifier::CheckClassDataItemField(uint32_t idx,
538 uint32_t access_flags,
539 uint32_t class_access_flags,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800540 dex::TypeIndex class_type_index,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700541 bool expect_static) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700542 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800543 if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
544 return false;
545 }
546
Andreas Gampee6215c02015-08-31 18:54:38 -0700547 // Check that it's the right class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800548 dex::TypeIndex my_class_index =
Andreas Gampee6215c02015-08-31 18:54:38 -0700549 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)->
550 class_idx_;
551 if (class_type_index != my_class_index) {
552 ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800553 my_class_index.index_,
554 class_type_index.index_);
Andreas Gampee6215c02015-08-31 18:54:38 -0700555 return false;
556 }
557
558 // Check that it falls into the right class-data list.
jeffhao10037c82012-01-23 15:06:23 -0800559 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700560 if (UNLIKELY(is_static != expect_static)) {
561 ErrorStringPrintf("Static/instance field not in expected list");
jeffhao10037c82012-01-23 15:06:23 -0800562 return false;
563 }
564
Andreas Gampee6215c02015-08-31 18:54:38 -0700565 // Check field access flags.
566 std::string error_msg;
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800567 if (!CheckFieldAccessFlags(idx, access_flags, class_access_flags, &error_msg)) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700568 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800569 return false;
570 }
571
572 return true;
573}
574
Andreas Gampee6215c02015-08-31 18:54:38 -0700575bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx,
576 uint32_t access_flags,
577 uint32_t class_access_flags,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800578 dex::TypeIndex class_type_index,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700579 uint32_t code_offset,
Andreas Gampee6215c02015-08-31 18:54:38 -0700580 std::unordered_set<uint32_t>* direct_method_indexes,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700581 bool expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700582 DCHECK(direct_method_indexes != nullptr);
583 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800584 if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
585 return false;
586 }
587
Andreas Gampee6215c02015-08-31 18:54:38 -0700588 // Check that it's the right class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800589 dex::TypeIndex my_class_index =
Andreas Gampee6215c02015-08-31 18:54:38 -0700590 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)->
591 class_idx_;
592 if (class_type_index != my_class_index) {
593 ErrorStringPrintf("Method's class index unexpected, %" PRIu16 "vs %" PRIu16,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800594 my_class_index.index_,
595 class_type_index.index_);
jeffhao10037c82012-01-23 15:06:23 -0800596 return false;
597 }
598
Andreas Gampee6215c02015-08-31 18:54:38 -0700599 // Check that it's not defined as both direct and virtual.
Jeff Haoa574b0e2015-06-04 18:12:26 -0700600 if (expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700601 direct_method_indexes->insert(idx);
602 } else if (direct_method_indexes->find(idx) != direct_method_indexes->end()) {
Jeff Haoa574b0e2015-06-04 18:12:26 -0700603 ErrorStringPrintf("Found virtual method with same index as direct method: %d", idx);
604 return false;
605 }
606
Andreas Gampee6215c02015-08-31 18:54:38 -0700607 // Check method access flags.
608 bool has_code = (code_offset != 0);
609 std::string error_msg;
610 if (!CheckMethodAccessFlags(idx,
611 access_flags,
612 class_access_flags,
613 has_code,
614 expect_direct,
615 &error_msg)) {
616 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800617 return false;
618 }
619
620 return true;
621}
622
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800623bool DexFileVerifier::CheckPadding(size_t offset, uint32_t aligned_offset) {
jeffhao10037c82012-01-23 15:06:23 -0800624 if (offset < aligned_offset) {
Ian Rogers13735952014-10-08 12:43:28 -0700625 if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(uint8_t), "section")) {
jeffhao10037c82012-01-23 15:06:23 -0800626 return false;
627 }
628 while (offset < aligned_offset) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700629 if (UNLIKELY(*ptr_ != '\0')) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800630 ErrorStringPrintf("Non-zero padding %x before section start at %zx", *ptr_, offset);
jeffhao10037c82012-01-23 15:06:23 -0800631 return false;
632 }
633 ptr_++;
634 offset++;
635 }
636 }
637 return true;
638}
639
640bool DexFileVerifier::CheckEncodedValue() {
Ian Rogers13735952014-10-08 12:43:28 -0700641 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "encoded_value header")) {
jeffhao10037c82012-01-23 15:06:23 -0800642 return false;
643 }
644
645 uint8_t header_byte = *(ptr_++);
646 uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
647 uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
648
649 switch (value_type) {
650 case DexFile::kDexAnnotationByte:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700651 if (UNLIKELY(value_arg != 0)) {
652 ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800653 return false;
654 }
655 ptr_++;
656 break;
657 case DexFile::kDexAnnotationShort:
658 case DexFile::kDexAnnotationChar:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700659 if (UNLIKELY(value_arg > 1)) {
660 ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800661 return false;
662 }
663 ptr_ += value_arg + 1;
664 break;
665 case DexFile::kDexAnnotationInt:
666 case DexFile::kDexAnnotationFloat:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700667 if (UNLIKELY(value_arg > 3)) {
668 ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800669 return false;
670 }
671 ptr_ += value_arg + 1;
672 break;
673 case DexFile::kDexAnnotationLong:
674 case DexFile::kDexAnnotationDouble:
675 ptr_ += value_arg + 1;
676 break;
677 case DexFile::kDexAnnotationString: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700678 if (UNLIKELY(value_arg > 3)) {
679 ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800680 return false;
681 }
682 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
683 if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
684 return false;
685 }
686 break;
687 }
688 case DexFile::kDexAnnotationType: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700689 if (UNLIKELY(value_arg > 3)) {
690 ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800691 return false;
692 }
693 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
694 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
695 return false;
696 }
697 break;
698 }
699 case DexFile::kDexAnnotationField:
700 case DexFile::kDexAnnotationEnum: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700701 if (UNLIKELY(value_arg > 3)) {
702 ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800703 return false;
704 }
705 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
706 if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
707 return false;
708 }
709 break;
710 }
711 case DexFile::kDexAnnotationMethod: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700712 if (UNLIKELY(value_arg > 3)) {
713 ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800714 return false;
715 }
716 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
717 if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
718 return false;
719 }
720 break;
721 }
722 case DexFile::kDexAnnotationArray:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700723 if (UNLIKELY(value_arg != 0)) {
724 ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800725 return false;
726 }
727 if (!CheckEncodedArray()) {
728 return false;
729 }
730 break;
731 case DexFile::kDexAnnotationAnnotation:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700732 if (UNLIKELY(value_arg != 0)) {
733 ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800734 return false;
735 }
736 if (!CheckEncodedAnnotation()) {
737 return false;
738 }
739 break;
740 case DexFile::kDexAnnotationNull:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700741 if (UNLIKELY(value_arg != 0)) {
742 ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800743 return false;
744 }
745 break;
746 case DexFile::kDexAnnotationBoolean:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700747 if (UNLIKELY(value_arg > 1)) {
748 ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800749 return false;
750 }
751 break;
752 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700753 ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
jeffhao10037c82012-01-23 15:06:23 -0800754 return false;
755 }
756
757 return true;
758}
759
760bool DexFileVerifier::CheckEncodedArray() {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700761 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800762
763 while (size--) {
764 if (!CheckEncodedValue()) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700765 failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800766 return false;
767 }
768 }
769 return true;
770}
771
772bool DexFileVerifier::CheckEncodedAnnotation() {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700773 DECODE_UNSIGNED_CHECKED_FROM(ptr_, anno_idx);
774 if (!CheckIndex(anno_idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -0800775 return false;
776 }
777
Andreas Gampebed6daf2016-09-02 18:12:00 -0700778 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800779 uint32_t last_idx = 0;
780
781 for (uint32_t i = 0; i < size; i++) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700782 DECODE_UNSIGNED_CHECKED_FROM(ptr_, idx);
jeffhao10037c82012-01-23 15:06:23 -0800783 if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
784 return false;
785 }
786
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700787 if (UNLIKELY(last_idx >= idx && i != 0)) {
788 ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
789 last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -0800790 return false;
791 }
792
793 if (!CheckEncodedValue()) {
794 return false;
795 }
796
797 last_idx = idx;
798 }
799 return true;
800}
801
Andreas Gampee6215c02015-08-31 18:54:38 -0700802bool DexFileVerifier::FindClassFlags(uint32_t index,
803 bool is_field,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800804 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700805 uint32_t* class_access_flags) {
806 DCHECK(class_type_index != nullptr);
807 DCHECK(class_access_flags != nullptr);
808
809 // First check if the index is valid.
810 if (index >= (is_field ? header_->field_ids_size_ : header_->method_ids_size_)) {
811 return false;
812 }
813
814 // Next get the type index.
815 if (is_field) {
816 *class_type_index =
817 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + index)->
818 class_idx_;
819 } else {
820 *class_type_index =
821 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + index)->
822 class_idx_;
823 }
824
825 // Check if that is valid.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800826 if (class_type_index->index_ >= header_->type_ids_size_) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700827 return false;
828 }
829
830 // Now search for the class def. This is basically a specialized version of the DexFile code, as
831 // we should not trust that this is a valid DexFile just yet.
832 const DexFile::ClassDef* class_def_begin =
833 reinterpret_cast<const DexFile::ClassDef*>(begin_ + header_->class_defs_off_);
834 for (size_t i = 0; i < header_->class_defs_size_; ++i) {
835 const DexFile::ClassDef* class_def = class_def_begin + i;
836 if (class_def->class_idx_ == *class_type_index) {
837 *class_access_flags = class_def->access_flags_;
838 return true;
839 }
840 }
841
842 // Didn't find the class-def, not defined here...
843 return false;
844}
845
846bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field,
847 const char* type_descr,
848 uint32_t curr_index,
849 uint32_t prev_index,
850 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800851 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700852 uint32_t* class_access_flags) {
853 if (curr_index < prev_index) {
854 ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32,
855 type_descr,
856 prev_index,
857 curr_index);
858 return false;
859 }
860
861 if (!*have_class) {
862 *have_class = FindClassFlags(curr_index, is_field, class_type_index, class_access_flags);
863 if (!*have_class) {
864 // Should have really found one.
865 ErrorStringPrintf("could not find declaring class for %s index %" PRIu32,
866 type_descr,
867 curr_index);
868 return false;
869 }
870 }
871 return true;
872}
873
874template <bool kStatic>
875bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it,
876 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800877 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700878 uint32_t* class_access_flags) {
879 DCHECK(it != nullptr);
880 // These calls use the raw access flags to check whether the whole dex field is valid.
881 uint32_t prev_index = 0;
882 for (; kStatic ? it->HasNextStaticField() : it->HasNextInstanceField(); it->Next()) {
883 uint32_t curr_index = it->GetMemberIndex();
884 if (!CheckOrderAndGetClassFlags(true,
885 kStatic ? "static field" : "instance field",
886 curr_index,
887 prev_index,
888 have_class,
889 class_type_index,
890 class_access_flags)) {
891 return false;
892 }
893 prev_index = curr_index;
894
895 if (!CheckClassDataItemField(curr_index,
896 it->GetRawMemberAccessFlags(),
897 *class_access_flags,
898 *class_type_index,
899 kStatic)) {
900 return false;
901 }
902 }
903
904 return true;
905}
906
907template <bool kDirect>
908bool DexFileVerifier::CheckIntraClassDataItemMethods(
909 ClassDataItemIterator* it,
910 std::unordered_set<uint32_t>* direct_method_indexes,
911 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800912 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700913 uint32_t* class_access_flags) {
914 uint32_t prev_index = 0;
915 for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) {
916 uint32_t curr_index = it->GetMemberIndex();
917 if (!CheckOrderAndGetClassFlags(false,
918 kDirect ? "direct method" : "virtual method",
919 curr_index,
920 prev_index,
921 have_class,
922 class_type_index,
923 class_access_flags)) {
924 return false;
925 }
926 prev_index = curr_index;
927
928 if (!CheckClassDataItemMethod(curr_index,
929 it->GetRawMemberAccessFlags(),
930 *class_access_flags,
931 *class_type_index,
932 it->GetMethodCodeItemOffset(),
933 direct_method_indexes,
934 kDirect)) {
935 return false;
936 }
937 }
938
939 return true;
940}
941
jeffhao10037c82012-01-23 15:06:23 -0800942bool DexFileVerifier::CheckIntraClassDataItem() {
943 ClassDataItemIterator it(*dex_file_, ptr_);
Jeff Haoa574b0e2015-06-04 18:12:26 -0700944 std::unordered_set<uint32_t> direct_method_indexes;
jeffhao10037c82012-01-23 15:06:23 -0800945
Andreas Gampee6215c02015-08-31 18:54:38 -0700946 // This code is complicated by the fact that we don't directly know which class this belongs to.
947 // So we need to explicitly search with the first item we find (either field or method), and then,
948 // as the lookup is expensive, cache the result.
949 bool have_class = false;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800950 dex::TypeIndex class_type_index;
Andreas Gampee6215c02015-08-31 18:54:38 -0700951 uint32_t class_access_flags;
952
953 // Check fields.
954 if (!CheckIntraClassDataItemFields<true>(&it,
955 &have_class,
956 &class_type_index,
957 &class_access_flags)) {
958 return false;
jeffhao10037c82012-01-23 15:06:23 -0800959 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700960 if (!CheckIntraClassDataItemFields<false>(&it,
961 &have_class,
962 &class_type_index,
963 &class_access_flags)) {
964 return false;
jeffhao10037c82012-01-23 15:06:23 -0800965 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700966
967 // Check methods.
968 if (!CheckIntraClassDataItemMethods<true>(&it,
969 &direct_method_indexes,
970 &have_class,
971 &class_type_index,
972 &class_access_flags)) {
973 return false;
jeffhao10037c82012-01-23 15:06:23 -0800974 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700975 if (!CheckIntraClassDataItemMethods<false>(&it,
976 &direct_method_indexes,
977 &have_class,
978 &class_type_index,
979 &class_access_flags)) {
980 return false;
jeffhao10037c82012-01-23 15:06:23 -0800981 }
982
983 ptr_ = it.EndDataPointer();
984 return true;
985}
986
987bool DexFileVerifier::CheckIntraCodeItem() {
988 const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700989 if (!CheckListSize(code_item, 1, sizeof(DexFile::CodeItem), "code")) {
jeffhao10037c82012-01-23 15:06:23 -0800990 return false;
991 }
992
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700993 if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
994 ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
995 code_item->ins_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800996 return false;
997 }
998
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700999 if (UNLIKELY((code_item->outs_size_ > 5) &&
1000 (code_item->outs_size_ > code_item->registers_size_))) {
jeffhao10037c82012-01-23 15:06:23 -08001001 /*
1002 * outs_size can be up to 5, even if registers_size is smaller, since the
1003 * short forms of method invocation allow repetitions of a register multiple
1004 * times within a single parameter list. However, longer parameter lists
1005 * need to be represented in-order in the register file.
1006 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001007 ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
1008 code_item->outs_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -08001009 return false;
1010 }
1011
1012 const uint16_t* insns = code_item->insns_;
1013 uint32_t insns_size = code_item->insns_size_in_code_units_;
1014 if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
1015 return false;
1016 }
1017
1018 // Grab the end of the insns if there are no try_items.
1019 uint32_t try_items_size = code_item->tries_size_;
1020 if (try_items_size == 0) {
Ian Rogers13735952014-10-08 12:43:28 -07001021 ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -08001022 return true;
1023 }
1024
1025 // try_items are 4-byte aligned. Verify the spacer is 0.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001026 if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001027 ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -08001028 return false;
1029 }
1030
1031 const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -08001032 if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
1033 return false;
1034 }
1035
Anestis Bechtsoudis6a8df532015-07-12 12:51:35 -05001036 ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
Andreas Gampebed6daf2016-09-02 18:12:00 -07001037 DECODE_UNSIGNED_CHECKED_FROM(ptr_, handlers_size);
Anestis Bechtsoudis6a8df532015-07-12 12:51:35 -05001038
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001039 if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
1040 ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
jeffhao10037c82012-01-23 15:06:23 -08001041 return false;
1042 }
1043
Ian Rogers700a4022014-05-19 16:49:03 -07001044 std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001045 if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
jeffhao10037c82012-01-23 15:06:23 -08001046 return false;
1047 }
1048
1049 uint32_t last_addr = 0;
1050 while (try_items_size--) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001051 if (UNLIKELY(try_items->start_addr_ < last_addr)) {
1052 ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001053 return false;
1054 }
1055
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001056 if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
1057 ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001058 return false;
1059 }
1060
1061 uint32_t i;
1062 for (i = 0; i < handlers_size; i++) {
1063 if (try_items->handler_off_ == handler_offsets[i]) {
1064 break;
1065 }
1066 }
1067
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001068 if (UNLIKELY(i == handlers_size)) {
1069 ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
jeffhao10037c82012-01-23 15:06:23 -08001070 return false;
1071 }
1072
1073 last_addr = try_items->start_addr_ + try_items->insn_count_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001074 if (UNLIKELY(last_addr > insns_size)) {
1075 ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
jeffhao10037c82012-01-23 15:06:23 -08001076 return false;
1077 }
1078
1079 try_items++;
1080 }
1081
1082 return true;
1083}
1084
1085bool DexFileVerifier::CheckIntraStringDataItem() {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001086 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
Ian Rogers13735952014-10-08 12:43:28 -07001087 const uint8_t* file_end = begin_ + size_;
jeffhao10037c82012-01-23 15:06:23 -08001088
1089 for (uint32_t i = 0; i < size; i++) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001090 CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001091 if (UNLIKELY(ptr_ >= file_end)) {
1092 ErrorStringPrintf("String data would go beyond end-of-file");
jeffhao10037c82012-01-23 15:06:23 -08001093 return false;
1094 }
1095
1096 uint8_t byte = *(ptr_++);
1097
1098 // Switch on the high 4 bits.
1099 switch (byte >> 4) {
1100 case 0x00:
1101 // Special case of bit pattern 0xxx.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001102 if (UNLIKELY(byte == 0)) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001103 CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001104 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001105 return false;
1106 }
1107 break;
1108 case 0x01:
1109 case 0x02:
1110 case 0x03:
1111 case 0x04:
1112 case 0x05:
1113 case 0x06:
1114 case 0x07:
1115 // No extra checks necessary for bit pattern 0xxx.
1116 break;
1117 case 0x08:
1118 case 0x09:
1119 case 0x0a:
1120 case 0x0b:
1121 case 0x0f:
1122 // Illegal bit patterns 10xx or 1111.
1123 // Note: 1111 is valid for normal UTF-8, but not here.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001124 ErrorStringPrintf("Illegal start byte %x in string data", byte);
jeffhao10037c82012-01-23 15:06:23 -08001125 return false;
1126 case 0x0c:
1127 case 0x0d: {
1128 // Bit pattern 110x has an additional byte.
1129 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001130 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1131 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001132 return false;
1133 }
1134 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001135 if (UNLIKELY((value != 0) && (value < 0x80))) {
1136 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001137 return false;
1138 }
1139 break;
1140 }
1141 case 0x0e: {
1142 // Bit pattern 1110 has 2 additional bytes.
1143 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001144 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1145 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001146 return false;
1147 }
1148 uint8_t byte3 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001149 if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
1150 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
jeffhao10037c82012-01-23 15:06:23 -08001151 return false;
1152 }
1153 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001154 if (UNLIKELY(value < 0x800)) {
1155 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001156 return false;
1157 }
1158 break;
1159 }
1160 }
1161 }
1162
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001163 if (UNLIKELY(*(ptr_++) != '\0')) {
1164 ErrorStringPrintf("String longer than indicated size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001165 return false;
1166 }
1167
1168 return true;
1169}
1170
1171bool DexFileVerifier::CheckIntraDebugInfoItem() {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001172 DECODE_UNSIGNED_CHECKED_FROM(ptr_, dummy);
1173 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameters_size);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001174 if (UNLIKELY(parameters_size > 65536)) {
1175 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
jeffhao10037c82012-01-23 15:06:23 -08001176 return false;
1177 }
1178
1179 for (uint32_t j = 0; j < parameters_size; j++) {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001180 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameter_name);
jeffhao10037c82012-01-23 15:06:23 -08001181 if (parameter_name != 0) {
1182 parameter_name--;
1183 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
1184 return false;
1185 }
1186 }
1187 }
1188
1189 while (true) {
1190 uint8_t opcode = *(ptr_++);
1191 switch (opcode) {
1192 case DexFile::DBG_END_SEQUENCE: {
1193 return true;
1194 }
1195 case DexFile::DBG_ADVANCE_PC: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001196 DECODE_UNSIGNED_CHECKED_FROM(ptr_, advance_pc_dummy);
jeffhao10037c82012-01-23 15:06:23 -08001197 break;
1198 }
1199 case DexFile::DBG_ADVANCE_LINE: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001200 DECODE_SIGNED_CHECKED_FROM(ptr_, advance_line_dummy);
jeffhao10037c82012-01-23 15:06:23 -08001201 break;
1202 }
1203 case DexFile::DBG_START_LOCAL: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001204 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001205 if (UNLIKELY(reg_num >= 65536)) {
1206 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001207 return false;
1208 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001209 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001210 if (name_idx != 0) {
1211 name_idx--;
1212 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
1213 return false;
1214 }
1215 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001216 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -08001217 if (type_idx != 0) {
1218 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001219 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001220 return false;
1221 }
1222 }
1223 break;
1224 }
1225 case DexFile::DBG_END_LOCAL:
1226 case DexFile::DBG_RESTART_LOCAL: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001227 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001228 if (UNLIKELY(reg_num >= 65536)) {
1229 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001230 return false;
1231 }
1232 break;
1233 }
1234 case DexFile::DBG_START_LOCAL_EXTENDED: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001235 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001236 if (UNLIKELY(reg_num >= 65536)) {
1237 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001238 return false;
1239 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001240 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001241 if (name_idx != 0) {
1242 name_idx--;
1243 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
1244 return false;
1245 }
1246 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001247 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -08001248 if (type_idx != 0) {
1249 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001250 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001251 return false;
1252 }
1253 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001254 DECODE_UNSIGNED_CHECKED_FROM(ptr_, sig_idx);
jeffhao10037c82012-01-23 15:06:23 -08001255 if (sig_idx != 0) {
1256 sig_idx--;
1257 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
1258 return false;
1259 }
1260 }
1261 break;
1262 }
1263 case DexFile::DBG_SET_FILE: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001264 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001265 if (name_idx != 0) {
1266 name_idx--;
1267 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
1268 return false;
1269 }
1270 }
1271 break;
1272 }
1273 }
1274 }
1275}
1276
1277bool DexFileVerifier::CheckIntraAnnotationItem() {
Ian Rogers13735952014-10-08 12:43:28 -07001278 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "annotation visibility")) {
jeffhao10037c82012-01-23 15:06:23 -08001279 return false;
1280 }
1281
1282 // Check visibility
1283 switch (*(ptr_++)) {
1284 case DexFile::kDexVisibilityBuild:
1285 case DexFile::kDexVisibilityRuntime:
1286 case DexFile::kDexVisibilitySystem:
1287 break;
1288 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001289 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001290 return false;
1291 }
1292
1293 if (!CheckEncodedAnnotation()) {
1294 return false;
1295 }
1296
1297 return true;
1298}
1299
1300bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1301 const DexFile::AnnotationsDirectoryItem* item =
1302 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001303 if (!CheckListSize(item, 1, sizeof(DexFile::AnnotationsDirectoryItem), "annotations_directory")) {
jeffhao10037c82012-01-23 15:06:23 -08001304 return false;
1305 }
1306
1307 // Field annotations follow immediately after the annotations directory.
1308 const DexFile::FieldAnnotationsItem* field_item =
1309 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1310 uint32_t field_count = item->fields_size_;
1311 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
1312 return false;
1313 }
1314
1315 uint32_t last_idx = 0;
1316 for (uint32_t i = 0; i < field_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001317 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1318 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001319 return false;
1320 }
1321 last_idx = field_item->field_idx_;
1322 field_item++;
1323 }
1324
1325 // Method annotations follow immediately after field annotations.
1326 const DexFile::MethodAnnotationsItem* method_item =
1327 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1328 uint32_t method_count = item->methods_size_;
1329 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1330 return false;
1331 }
1332
1333 last_idx = 0;
1334 for (uint32_t i = 0; i < method_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001335 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1336 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1337 last_idx, method_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001338 return false;
1339 }
1340 last_idx = method_item->method_idx_;
1341 method_item++;
1342 }
1343
1344 // Parameter annotations follow immediately after method annotations.
1345 const DexFile::ParameterAnnotationsItem* parameter_item =
1346 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1347 uint32_t parameter_count = item->parameters_size_;
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001348 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001349 "parameter_annotations list")) {
jeffhao10037c82012-01-23 15:06:23 -08001350 return false;
1351 }
1352
1353 last_idx = 0;
1354 for (uint32_t i = 0; i < parameter_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001355 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1356 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1357 last_idx, parameter_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001358 return false;
1359 }
1360 last_idx = parameter_item->method_idx_;
1361 parameter_item++;
1362 }
1363
1364 // Return a pointer to the end of the annotations.
Ian Rogers13735952014-10-08 12:43:28 -07001365 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08001366 return true;
1367}
1368
Andreas Gampeb061cc12014-09-02 10:22:20 -07001369bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
1370 uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001371 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001372 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001373 switch (type) {
1374 case DexFile::kDexTypeClassDataItem:
1375 case DexFile::kDexTypeStringDataItem:
1376 case DexFile::kDexTypeDebugInfoItem:
1377 case DexFile::kDexTypeAnnotationItem:
1378 case DexFile::kDexTypeEncodedArrayItem:
1379 alignment_mask = sizeof(uint8_t) - 1;
1380 break;
1381 default:
1382 alignment_mask = sizeof(uint32_t) - 1;
1383 break;
1384 }
1385
1386 // Iterate through the items in the section.
Andreas Gampeb061cc12014-09-02 10:22:20 -07001387 for (uint32_t i = 0; i < section_count; i++) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001388 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001389
1390 // Check the padding between items.
1391 if (!CheckPadding(offset, aligned_offset)) {
1392 return false;
1393 }
1394
1395 // Check depending on the section type.
1396 switch (type) {
1397 case DexFile::kDexTypeStringIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001398 if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001399 return false;
1400 }
1401 ptr_ += sizeof(DexFile::StringId);
1402 break;
1403 }
1404 case DexFile::kDexTypeTypeIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001405 if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001406 return false;
1407 }
1408 ptr_ += sizeof(DexFile::TypeId);
1409 break;
1410 }
1411 case DexFile::kDexTypeProtoIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001412 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001413 return false;
1414 }
1415 ptr_ += sizeof(DexFile::ProtoId);
1416 break;
1417 }
1418 case DexFile::kDexTypeFieldIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001419 if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001420 return false;
1421 }
1422 ptr_ += sizeof(DexFile::FieldId);
1423 break;
1424 }
1425 case DexFile::kDexTypeMethodIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001426 if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001427 return false;
1428 }
1429 ptr_ += sizeof(DexFile::MethodId);
1430 break;
1431 }
1432 case DexFile::kDexTypeClassDefItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001433 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
jeffhao10037c82012-01-23 15:06:23 -08001434 return false;
1435 }
1436 ptr_ += sizeof(DexFile::ClassDef);
1437 break;
1438 }
1439 case DexFile::kDexTypeTypeList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001440 if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001441 return false;
1442 }
jeffhao10037c82012-01-23 15:06:23 -08001443 break;
1444 }
1445 case DexFile::kDexTypeAnnotationSetRefList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001446 if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001447 return false;
1448 }
jeffhao10037c82012-01-23 15:06:23 -08001449 break;
1450 }
1451 case DexFile::kDexTypeAnnotationSetItem: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001452 if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001453 return false;
1454 }
jeffhao10037c82012-01-23 15:06:23 -08001455 break;
1456 }
1457 case DexFile::kDexTypeClassDataItem: {
1458 if (!CheckIntraClassDataItem()) {
1459 return false;
1460 }
1461 break;
1462 }
1463 case DexFile::kDexTypeCodeItem: {
1464 if (!CheckIntraCodeItem()) {
1465 return false;
1466 }
1467 break;
1468 }
1469 case DexFile::kDexTypeStringDataItem: {
1470 if (!CheckIntraStringDataItem()) {
1471 return false;
1472 }
1473 break;
1474 }
1475 case DexFile::kDexTypeDebugInfoItem: {
1476 if (!CheckIntraDebugInfoItem()) {
1477 return false;
1478 }
1479 break;
1480 }
1481 case DexFile::kDexTypeAnnotationItem: {
1482 if (!CheckIntraAnnotationItem()) {
1483 return false;
1484 }
1485 break;
1486 }
1487 case DexFile::kDexTypeEncodedArrayItem: {
1488 if (!CheckEncodedArray()) {
1489 return false;
1490 }
1491 break;
1492 }
1493 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1494 if (!CheckIntraAnnotationsDirectoryItem()) {
1495 return false;
1496 }
1497 break;
1498 }
1499 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001500 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001501 return false;
1502 }
1503
1504 if (IsDataSectionType(type)) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001505 if (aligned_offset == 0u) {
1506 ErrorStringPrintf("Item %d offset is 0", i);
1507 return false;
1508 }
1509 DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
1510 offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
jeffhao10037c82012-01-23 15:06:23 -08001511 }
1512
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001513 aligned_offset = ptr_ - begin_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001514 if (UNLIKELY(aligned_offset > size_)) {
1515 ErrorStringPrintf("Item %d at ends out of bounds", i);
jeffhao10037c82012-01-23 15:06:23 -08001516 return false;
1517 }
1518
1519 offset = aligned_offset;
1520 }
1521
1522 return true;
1523}
1524
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001525bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001526 uint32_t expected_offset;
1527 uint32_t expected_size;
1528
1529 // Get the expected offset and size from the header.
1530 switch (type) {
1531 case DexFile::kDexTypeStringIdItem:
1532 expected_offset = header_->string_ids_off_;
1533 expected_size = header_->string_ids_size_;
1534 break;
1535 case DexFile::kDexTypeTypeIdItem:
1536 expected_offset = header_->type_ids_off_;
1537 expected_size = header_->type_ids_size_;
1538 break;
1539 case DexFile::kDexTypeProtoIdItem:
1540 expected_offset = header_->proto_ids_off_;
1541 expected_size = header_->proto_ids_size_;
1542 break;
1543 case DexFile::kDexTypeFieldIdItem:
1544 expected_offset = header_->field_ids_off_;
1545 expected_size = header_->field_ids_size_;
1546 break;
1547 case DexFile::kDexTypeMethodIdItem:
1548 expected_offset = header_->method_ids_off_;
1549 expected_size = header_->method_ids_size_;
1550 break;
1551 case DexFile::kDexTypeClassDefItem:
1552 expected_offset = header_->class_defs_off_;
1553 expected_size = header_->class_defs_size_;
1554 break;
1555 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001556 ErrorStringPrintf("Bad type for id section: %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001557 return false;
1558 }
1559
1560 // Check that the offset and size are what were expected from the header.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001561 if (UNLIKELY(offset != expected_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001562 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
jeffhao10037c82012-01-23 15:06:23 -08001563 return false;
1564 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001565 if (UNLIKELY(count != expected_size)) {
1566 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
jeffhao10037c82012-01-23 15:06:23 -08001567 return false;
1568 }
1569
1570 return CheckIntraSectionIterate(offset, count, type);
1571}
1572
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001573bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
1574 size_t data_start = header_->data_off_;
1575 size_t data_end = data_start + header_->data_size_;
jeffhao10037c82012-01-23 15:06:23 -08001576
1577 // Sanity check the offset of the section.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001578 if (UNLIKELY((offset < data_start) || (offset > data_end))) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001579 ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
jeffhao10037c82012-01-23 15:06:23 -08001580 return false;
1581 }
1582
1583 if (!CheckIntraSectionIterate(offset, count, type)) {
1584 return false;
1585 }
1586
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001587 size_t next_offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001588 if (next_offset > data_end) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001589 ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset);
jeffhao10037c82012-01-23 15:06:23 -08001590 return false;
1591 }
1592
1593 return true;
1594}
1595
1596bool DexFileVerifier::CheckIntraSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08001597 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001598 const DexFile::MapItem* item = map->list_;
1599
1600 uint32_t count = map->size_;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001601 size_t offset = 0;
Ian Rogers30fab402012-01-23 15:43:46 -08001602 ptr_ = begin_;
jeffhao10037c82012-01-23 15:06:23 -08001603
1604 // Check the items listed in the map.
1605 while (count--) {
1606 uint32_t section_offset = item->offset_;
1607 uint32_t section_count = item->size_;
1608 uint16_t type = item->type_;
1609
1610 // Check for padding and overlap between items.
1611 if (!CheckPadding(offset, section_offset)) {
1612 return false;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001613 } else if (UNLIKELY(offset > section_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001614 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001615 return false;
1616 }
1617
1618 // Check each item based on its type.
1619 switch (type) {
1620 case DexFile::kDexTypeHeaderItem:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001621 if (UNLIKELY(section_count != 1)) {
1622 ErrorStringPrintf("Multiple header items");
jeffhao10037c82012-01-23 15:06:23 -08001623 return false;
1624 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001625 if (UNLIKELY(section_offset != 0)) {
1626 ErrorStringPrintf("Header at %x, not at start of file", section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001627 return false;
1628 }
Ian Rogers30fab402012-01-23 15:43:46 -08001629 ptr_ = begin_ + header_->header_size_;
jeffhao10037c82012-01-23 15:06:23 -08001630 offset = header_->header_size_;
1631 break;
1632 case DexFile::kDexTypeStringIdItem:
1633 case DexFile::kDexTypeTypeIdItem:
1634 case DexFile::kDexTypeProtoIdItem:
1635 case DexFile::kDexTypeFieldIdItem:
1636 case DexFile::kDexTypeMethodIdItem:
1637 case DexFile::kDexTypeClassDefItem:
1638 if (!CheckIntraIdSection(section_offset, section_count, type)) {
1639 return false;
1640 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001641 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001642 break;
1643 case DexFile::kDexTypeMapList:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001644 if (UNLIKELY(section_count != 1)) {
1645 ErrorStringPrintf("Multiple map list items");
jeffhao10037c82012-01-23 15:06:23 -08001646 return false;
1647 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001648 if (UNLIKELY(section_offset != header_->map_off_)) {
1649 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1650 section_offset, header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001651 return false;
1652 }
1653 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1654 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1655 break;
1656 case DexFile::kDexTypeTypeList:
1657 case DexFile::kDexTypeAnnotationSetRefList:
1658 case DexFile::kDexTypeAnnotationSetItem:
1659 case DexFile::kDexTypeClassDataItem:
1660 case DexFile::kDexTypeCodeItem:
1661 case DexFile::kDexTypeStringDataItem:
1662 case DexFile::kDexTypeDebugInfoItem:
1663 case DexFile::kDexTypeAnnotationItem:
1664 case DexFile::kDexTypeEncodedArrayItem:
1665 case DexFile::kDexTypeAnnotationsDirectoryItem:
1666 if (!CheckIntraDataSection(section_offset, section_count, type)) {
1667 return false;
1668 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001669 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001670 break;
1671 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001672 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001673 return false;
1674 }
1675
1676 item++;
1677 }
1678
1679 return true;
1680}
1681
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001682bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001683 DCHECK_NE(offset, 0u);
1684 auto it = offset_to_type_map_.Find(offset);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001685 if (UNLIKELY(it == offset_to_type_map_.end())) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001686 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
jeffhao10037c82012-01-23 15:06:23 -08001687 return false;
1688 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001689 if (UNLIKELY(it->second != type)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001690 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001691 offset, type, it->second);
jeffhao10037c82012-01-23 15:06:23 -08001692 return false;
1693 }
1694 return true;
1695}
1696
Andreas Gampea5b09a62016-11-17 15:21:22 -08001697dex::TypeIndex DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001698 ClassDataItemIterator it(*dex_file_, ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001699 *success = true;
jeffhao10037c82012-01-23 15:06:23 -08001700
1701 if (it.HasNextStaticField() || it.HasNextInstanceField()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001702 LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001703 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001704 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001705 }
1706
1707 if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001708 LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001709 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001710 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001711 }
1712
Andreas Gampea5b09a62016-11-17 15:21:22 -08001713 return dex::TypeIndex(DexFile::kDexNoIndex16);
jeffhao10037c82012-01-23 15:06:23 -08001714}
1715
Andreas Gampea5b09a62016-11-17 15:21:22 -08001716dex::TypeIndex DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr,
1717 bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001718 const DexFile::AnnotationsDirectoryItem* item =
1719 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001720 *success = true;
1721
jeffhao10037c82012-01-23 15:06:23 -08001722 if (item->fields_size_ != 0) {
1723 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001724 LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001725 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001726 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001727 }
1728
1729 if (item->methods_size_ != 0) {
1730 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001731 LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001732 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001733 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001734 }
1735
1736 if (item->parameters_size_ != 0) {
1737 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001738 LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001739 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001740 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001741 }
1742
Andreas Gampea5b09a62016-11-17 15:21:22 -08001743 return dex::TypeIndex(DexFile::kDexNoIndex16);
jeffhao10037c82012-01-23 15:06:23 -08001744}
1745
1746bool DexFileVerifier::CheckInterStringIdItem() {
1747 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
1748
1749 // Check the map to make sure it has the right offset->type.
1750 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
1751 return false;
1752 }
1753
1754 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001755 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001756 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
1757 const char* prev_str = dex_file_->GetStringData(*prev_item);
1758 const char* str = dex_file_->GetStringData(*item);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001759 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
1760 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
jeffhao10037c82012-01-23 15:06:23 -08001761 return false;
1762 }
1763 }
1764
1765 ptr_ += sizeof(DexFile::StringId);
1766 return true;
1767}
1768
1769bool DexFileVerifier::CheckInterTypeIdItem() {
1770 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001771
1772 LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
jeffhao10037c82012-01-23 15:06:23 -08001773
1774 // Check that the descriptor is a valid type.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001775 if (UNLIKELY(!IsValidDescriptor(descriptor))) {
1776 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001777 return false;
1778 }
1779
1780 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001781 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001782 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001783 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
1784 ErrorStringPrintf("Out-of-order type_ids: %x then %x",
1785 prev_item->descriptor_idx_, item->descriptor_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001786 return false;
1787 }
1788 }
1789
1790 ptr_ += sizeof(DexFile::TypeId);
1791 return true;
1792}
1793
1794bool DexFileVerifier::CheckInterProtoIdItem() {
1795 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001796
1797 LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
1798
jeffhao10037c82012-01-23 15:06:23 -08001799 if (item->parameters_off_ != 0 &&
1800 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
1801 return false;
1802 }
1803
David Sehr28e74ed2016-11-21 12:52:12 -08001804 // Check that return type is representable as a uint16_t;
1805 if (UNLIKELY(!IsValidOrNoTypeId(item->return_type_idx_.index_, item->pad_))) {
1806 ErrorStringPrintf("proto with return type idx outside uint16_t range '%x:%x'",
1807 item->pad_, item->return_type_idx_.index_);
1808 return false;
1809 }
jeffhao10037c82012-01-23 15:06:23 -08001810 // Check the return type and advance the shorty.
Andreas Gampee09269c2014-06-06 18:45:35 -07001811 LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
1812 if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
jeffhao10037c82012-01-23 15:06:23 -08001813 return false;
1814 }
1815 shorty++;
1816
1817 DexFileParameterIterator it(*dex_file_, *item);
1818 while (it.HasNext() && *shorty != '\0') {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001819 if (!CheckIndex(it.GetTypeIdx().index_,
1820 dex_file_->NumTypeIds(),
Andreas Gampebb836e12014-06-13 15:31:40 -07001821 "inter_proto_id_item shorty type_idx")) {
1822 return false;
1823 }
jeffhao10037c82012-01-23 15:06:23 -08001824 const char* descriptor = it.GetDescriptor();
1825 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
1826 return false;
1827 }
1828 it.Next();
1829 shorty++;
1830 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001831 if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
1832 ErrorStringPrintf("Mismatched length for parameters and shorty");
jeffhao10037c82012-01-23 15:06:23 -08001833 return false;
1834 }
1835
1836 // Check ordering between items. This relies on type_ids being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001837 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001838 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001839 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
1840 ErrorStringPrintf("Out-of-order proto_id return types");
jeffhao10037c82012-01-23 15:06:23 -08001841 return false;
1842 } else if (prev->return_type_idx_ == item->return_type_idx_) {
1843 DexFileParameterIterator curr_it(*dex_file_, *item);
1844 DexFileParameterIterator prev_it(*dex_file_, *prev);
1845
1846 while (curr_it.HasNext() && prev_it.HasNext()) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001847 dex::TypeIndex prev_idx = prev_it.GetTypeIdx();
1848 dex::TypeIndex curr_idx = curr_it.GetTypeIdx();
1849 DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
1850 DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
jeffhao10037c82012-01-23 15:06:23 -08001851
1852 if (prev_idx < curr_idx) {
1853 break;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001854 } else if (UNLIKELY(prev_idx > curr_idx)) {
1855 ErrorStringPrintf("Out-of-order proto_id arguments");
jeffhao10037c82012-01-23 15:06:23 -08001856 return false;
1857 }
1858
1859 prev_it.Next();
1860 curr_it.Next();
1861 }
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001862 if (!curr_it.HasNext()) {
1863 // Either a duplicate ProtoId or a ProtoId with a shorter argument list follows
1864 // a ProtoId with a longer one. Both cases are forbidden by the specification.
1865 ErrorStringPrintf("Out-of-order proto_id arguments");
1866 return false;
1867 }
jeffhao10037c82012-01-23 15:06:23 -08001868 }
1869 }
1870
1871 ptr_ += sizeof(DexFile::ProtoId);
1872 return true;
1873}
1874
1875bool DexFileVerifier::CheckInterFieldIdItem() {
1876 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
1877
1878 // Check that the class descriptor is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001879 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
1880 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1881 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001882 return false;
1883 }
1884
1885 // Check that the type descriptor is a valid field name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001886 LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
1887 if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
1888 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001889 return false;
1890 }
1891
1892 // Check that the name is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001893 LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001894 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1895 ErrorStringPrintf("Invalid field name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001896 return false;
1897 }
1898
1899 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001900 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001901 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001902 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1903 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001904 return false;
1905 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001906 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1907 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001908 return false;
1909 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001910 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
1911 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001912 return false;
1913 }
1914 }
1915 }
1916 }
1917
1918 ptr_ += sizeof(DexFile::FieldId);
1919 return true;
1920}
1921
1922bool DexFileVerifier::CheckInterMethodIdItem() {
1923 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
1924
1925 // Check that the class descriptor is a valid reference name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001926 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
1927 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
1928 class_descriptor[0] != '['))) {
1929 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001930 return false;
1931 }
1932
1933 // Check that the name is valid.
Andreas Gampedf10b322014-06-11 21:46:05 -07001934 LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001935 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1936 ErrorStringPrintf("Invalid method name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001937 return false;
1938 }
1939
Andreas Gampedf10b322014-06-11 21:46:05 -07001940 // Check that the proto id is valid.
1941 if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
1942 "inter_method_id_item proto_idx"))) {
1943 return false;
1944 }
1945
jeffhao10037c82012-01-23 15:06:23 -08001946 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001947 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001948 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001949 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1950 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001951 return false;
1952 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001953 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1954 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001955 return false;
1956 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001957 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
1958 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001959 return false;
1960 }
1961 }
1962 }
1963 }
1964
1965 ptr_ += sizeof(DexFile::MethodId);
1966 return true;
1967}
1968
1969bool DexFileVerifier::CheckInterClassDefItem() {
1970 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001971
David Sehr28e74ed2016-11-21 12:52:12 -08001972 // Check that class_idx_ is representable as a uint16_t;
1973 if (UNLIKELY(!IsValidTypeId(item->class_idx_.index_, item->pad1_))) {
1974 ErrorStringPrintf("class with type idx outside uint16_t range '%x:%x'", item->pad1_,
1975 item->class_idx_.index_);
1976 return false;
1977 }
1978 // Check that superclass_idx_ is representable as a uint16_t;
1979 if (UNLIKELY(!IsValidOrNoTypeId(item->superclass_idx_.index_, item->pad2_))) {
1980 ErrorStringPrintf("class with superclass type idx outside uint16_t range '%x:%x'", item->pad2_,
1981 item->superclass_idx_.index_);
1982 return false;
1983 }
Andreas Gampe0ba238d2014-07-29 01:22:07 -07001984 // Check for duplicate class def.
1985 if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001986 ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_.index_);
Andreas Gampe0ba238d2014-07-29 01:22:07 -07001987 return false;
1988 }
1989 defined_classes_.insert(item->class_idx_);
1990
Andreas Gampee09269c2014-06-06 18:45:35 -07001991 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
1992 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1993 ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001994 return false;
1995 }
1996
Andreas Gampeacc2bb62014-07-17 19:26:50 -07001997 // Only allow non-runtime modifiers.
1998 if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
1999 ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
2000 return false;
2001 }
2002
jeffhao10037c82012-01-23 15:06:23 -08002003 if (item->interfaces_off_ != 0 &&
2004 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
2005 return false;
2006 }
2007 if (item->annotations_off_ != 0 &&
2008 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
2009 return false;
2010 }
2011 if (item->class_data_off_ != 0 &&
2012 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
2013 return false;
2014 }
2015 if (item->static_values_off_ != 0 &&
2016 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
2017 return false;
2018 }
2019
Andreas Gampea5b09a62016-11-17 15:21:22 -08002020 if (item->superclass_idx_.IsValid()) {
Roland Levillain621b5ea2016-05-18 11:41:33 +01002021 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2022 // Check that a class does not inherit from itself directly (by having
2023 // the same type idx as its super class).
2024 if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002025 ErrorStringPrintf("Class with same type idx as its superclass: '%d'",
2026 item->class_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002027 return false;
2028 }
2029
2030 // Check that a class is defined after its super class (if the
2031 // latter is defined in the same Dex file).
2032 const DexFile::ClassDef* superclass_def = dex_file_->FindClassDef(item->superclass_idx_);
2033 if (superclass_def != nullptr) {
2034 // The superclass is defined in this Dex file.
2035 if (superclass_def > item) {
2036 // ClassDef item for super class appearing after the class' ClassDef item.
2037 ErrorStringPrintf("Invalid class definition ordering:"
2038 " class with type idx: '%d' defined before"
2039 " superclass with type idx: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002040 item->class_idx_.index_,
2041 item->superclass_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002042 return false;
2043 }
2044 }
2045 }
2046
Andreas Gampee09269c2014-06-06 18:45:35 -07002047 LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
2048 "inter_class_def_item superclass_idx")
2049 if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
2050 ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08002051 return false;
2052 }
2053 }
2054
Roland Levillain621b5ea2016-05-18 11:41:33 +01002055 // Check interfaces.
jeffhao10037c82012-01-23 15:06:23 -08002056 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002057 if (interfaces != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08002058 uint32_t size = interfaces->Size();
jeffhao10037c82012-01-23 15:06:23 -08002059 for (uint32_t i = 0; i < size; i++) {
Roland Levillain621b5ea2016-05-18 11:41:33 +01002060 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2061 // Check that a class does not implement itself directly (by having the
2062 // same type idx as one of its immediate implemented interfaces).
2063 if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) {
2064 ErrorStringPrintf("Class with same type idx as implemented interface: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002065 item->class_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002066 return false;
2067 }
2068
2069 // Check that a class is defined after the interfaces it implements
2070 // (if they are defined in the same Dex file).
2071 const DexFile::ClassDef* interface_def =
2072 dex_file_->FindClassDef(interfaces->GetTypeItem(i).type_idx_);
2073 if (interface_def != nullptr) {
2074 // The interface is defined in this Dex file.
2075 if (interface_def > item) {
2076 // ClassDef item for interface appearing after the class' ClassDef item.
2077 ErrorStringPrintf("Invalid class definition ordering:"
2078 " class with type idx: '%d' defined before"
2079 " implemented interface with type idx: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002080 item->class_idx_.index_,
2081 interfaces->GetTypeItem(i).type_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002082 return false;
2083 }
2084 }
2085 }
2086
2087 // Ensure that the interface refers to a class (not an array nor a primitive type).
Andreas Gampee09269c2014-06-06 18:45:35 -07002088 LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
2089 "inter_class_def_item interface type_idx")
2090 if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
2091 ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08002092 return false;
2093 }
2094 }
2095
2096 /*
2097 * Ensure that there are no duplicates. This is an O(N^2) test, but in
2098 * practice the number of interfaces implemented by any given class is low.
2099 */
2100 for (uint32_t i = 1; i < size; i++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002101 dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_;
jeffhao10037c82012-01-23 15:06:23 -08002102 for (uint32_t j =0; j < i; j++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002103 dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002104 if (UNLIKELY(idx1 == idx2)) {
2105 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
jeffhao10037c82012-01-23 15:06:23 -08002106 return false;
2107 }
2108 }
2109 }
2110 }
2111
2112 // Check that references in class_data_item are to the right class.
2113 if (item->class_data_off_ != 0) {
Ian Rogers13735952014-10-08 12:43:28 -07002114 const uint8_t* data = begin_ + item->class_data_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002115 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002116 dex::TypeIndex data_definer = FindFirstClassDataDefiner(data, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002117 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002118 return false;
2119 }
Andreas Gampea5b09a62016-11-17 15:21:22 -08002120 if (UNLIKELY((data_definer != item->class_idx_) &&
2121 (data_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002122 ErrorStringPrintf("Invalid class_data_item");
jeffhao10037c82012-01-23 15:06:23 -08002123 return false;
2124 }
2125 }
2126
2127 // Check that references in annotations_directory_item are to right class.
2128 if (item->annotations_off_ != 0) {
Andreas Gampeb512c0e2016-02-19 19:45:34 -08002129 // annotations_off_ is supposed to be aligned by 4.
2130 if (!IsAlignedParam(item->annotations_off_, 4)) {
2131 ErrorStringPrintf("Invalid annotations_off_, not aligned by 4");
2132 return false;
2133 }
Ian Rogers13735952014-10-08 12:43:28 -07002134 const uint8_t* data = begin_ + item->annotations_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002135 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002136 dex::TypeIndex annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002137 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002138 return false;
2139 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002140 if (UNLIKELY((annotations_definer != item->class_idx_) &&
Andreas Gampea5b09a62016-11-17 15:21:22 -08002141 (annotations_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002142 ErrorStringPrintf("Invalid annotations_directory_item");
jeffhao10037c82012-01-23 15:06:23 -08002143 return false;
2144 }
2145 }
2146
2147 ptr_ += sizeof(DexFile::ClassDef);
2148 return true;
2149}
2150
2151bool DexFileVerifier::CheckInterAnnotationSetRefList() {
2152 const DexFile::AnnotationSetRefList* list =
2153 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
2154 const DexFile::AnnotationSetRefItem* item = list->list_;
2155 uint32_t count = list->size_;
2156
2157 while (count--) {
2158 if (item->annotations_off_ != 0 &&
2159 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2160 return false;
2161 }
2162 item++;
2163 }
2164
Ian Rogers13735952014-10-08 12:43:28 -07002165 ptr_ = reinterpret_cast<const uint8_t*>(item);
jeffhao10037c82012-01-23 15:06:23 -08002166 return true;
2167}
2168
2169bool DexFileVerifier::CheckInterAnnotationSetItem() {
2170 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
2171 const uint32_t* offsets = set->entries_;
2172 uint32_t count = set->size_;
2173 uint32_t last_idx = 0;
2174
2175 for (uint32_t i = 0; i < count; i++) {
2176 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
2177 return false;
2178 }
2179
2180 // Get the annotation from the offset and the type index for the annotation.
2181 const DexFile::AnnotationItem* annotation =
Ian Rogers30fab402012-01-23 15:43:46 -08002182 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
jeffhao10037c82012-01-23 15:06:23 -08002183 const uint8_t* data = annotation->annotation_;
Andreas Gampebed6daf2016-09-02 18:12:00 -07002184 DECODE_UNSIGNED_CHECKED_FROM(data, idx);
jeffhao10037c82012-01-23 15:06:23 -08002185
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002186 if (UNLIKELY(last_idx >= idx && i != 0)) {
2187 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -08002188 return false;
2189 }
2190
2191 last_idx = idx;
2192 offsets++;
2193 }
2194
Ian Rogers13735952014-10-08 12:43:28 -07002195 ptr_ = reinterpret_cast<const uint8_t*>(offsets);
jeffhao10037c82012-01-23 15:06:23 -08002196 return true;
2197}
2198
2199bool DexFileVerifier::CheckInterClassDataItem() {
2200 ClassDataItemIterator it(*dex_file_, ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002201 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002202 dex::TypeIndex defining_class = FindFirstClassDataDefiner(ptr_, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002203 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002204 return false;
2205 }
jeffhao10037c82012-01-23 15:06:23 -08002206
2207 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002208 LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002209 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002210 ErrorStringPrintf("Mismatched defining class for class_data_item field");
jeffhao10037c82012-01-23 15:06:23 -08002211 return false;
2212 }
2213 }
2214 for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) {
2215 uint32_t code_off = it.GetMethodCodeItemOffset();
2216 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
2217 return false;
2218 }
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002219 LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002220 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002221 ErrorStringPrintf("Mismatched defining class for class_data_item method");
jeffhao10037c82012-01-23 15:06:23 -08002222 return false;
2223 }
2224 }
2225
2226 ptr_ = it.EndDataPointer();
2227 return true;
2228}
2229
2230bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
2231 const DexFile::AnnotationsDirectoryItem* item =
2232 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002233 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002234 dex::TypeIndex defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002235 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002236 return false;
2237 }
jeffhao10037c82012-01-23 15:06:23 -08002238
2239 if (item->class_annotations_off_ != 0 &&
2240 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2241 return false;
2242 }
2243
2244 // Field annotations follow immediately after the annotations directory.
2245 const DexFile::FieldAnnotationsItem* field_item =
2246 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
2247 uint32_t field_count = item->fields_size_;
2248 for (uint32_t i = 0; i < field_count; i++) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002249 LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
2250 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002251 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002252 ErrorStringPrintf("Mismatched defining class for field_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002253 return false;
2254 }
2255 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2256 return false;
2257 }
2258 field_item++;
2259 }
2260
2261 // Method annotations follow immediately after field annotations.
2262 const DexFile::MethodAnnotationsItem* method_item =
2263 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
2264 uint32_t method_count = item->methods_size_;
2265 for (uint32_t i = 0; i < method_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002266 LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002267 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002268 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002269 ErrorStringPrintf("Mismatched defining class for method_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002270 return false;
2271 }
2272 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2273 return false;
2274 }
2275 method_item++;
2276 }
2277
2278 // Parameter annotations follow immediately after method annotations.
2279 const DexFile::ParameterAnnotationsItem* parameter_item =
2280 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
2281 uint32_t parameter_count = item->parameters_size_;
2282 for (uint32_t i = 0; i < parameter_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002283 LOAD_METHOD(parameter_method, parameter_item->method_idx_,
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002284 "inter_annotations_directory_item parameter method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002285 if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002286 ErrorStringPrintf("Mismatched defining class for parameter_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002287 return false;
2288 }
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07002289 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
2290 DexFile::kDexTypeAnnotationSetRefList)) {
jeffhao10037c82012-01-23 15:06:23 -08002291 return false;
2292 }
2293 parameter_item++;
2294 }
2295
Ian Rogers13735952014-10-08 12:43:28 -07002296 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08002297 return true;
2298}
2299
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002300bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08002301 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002302 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08002303 switch (type) {
2304 case DexFile::kDexTypeClassDataItem:
2305 alignment_mask = sizeof(uint8_t) - 1;
2306 break;
2307 default:
2308 alignment_mask = sizeof(uint32_t) - 1;
2309 break;
2310 }
2311
2312 // Iterate through the items in the section.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002313 previous_item_ = nullptr;
jeffhao10037c82012-01-23 15:06:23 -08002314 for (uint32_t i = 0; i < count; i++) {
2315 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
Ian Rogers30fab402012-01-23 15:43:46 -08002316 ptr_ = begin_ + new_offset;
Ian Rogers13735952014-10-08 12:43:28 -07002317 const uint8_t* prev_ptr = ptr_;
jeffhao10037c82012-01-23 15:06:23 -08002318
2319 // Check depending on the section type.
2320 switch (type) {
2321 case DexFile::kDexTypeStringIdItem: {
2322 if (!CheckInterStringIdItem()) {
2323 return false;
2324 }
2325 break;
2326 }
2327 case DexFile::kDexTypeTypeIdItem: {
2328 if (!CheckInterTypeIdItem()) {
2329 return false;
2330 }
2331 break;
2332 }
2333 case DexFile::kDexTypeProtoIdItem: {
2334 if (!CheckInterProtoIdItem()) {
2335 return false;
2336 }
2337 break;
2338 }
2339 case DexFile::kDexTypeFieldIdItem: {
2340 if (!CheckInterFieldIdItem()) {
2341 return false;
2342 }
2343 break;
2344 }
2345 case DexFile::kDexTypeMethodIdItem: {
2346 if (!CheckInterMethodIdItem()) {
2347 return false;
2348 }
2349 break;
2350 }
2351 case DexFile::kDexTypeClassDefItem: {
David Sehr28e74ed2016-11-21 12:52:12 -08002352 // There shouldn't be more class definitions than type ids allow.
2353 // This check should be redundant, since there are checks that the
2354 // class_idx_ is within range and that there is only one definition
2355 // for a given type id.
2356 if (i > kTypeIdLimit) {
2357 ErrorStringPrintf("Too many class definition items");
2358 return false;
2359 }
jeffhao10037c82012-01-23 15:06:23 -08002360 if (!CheckInterClassDefItem()) {
2361 return false;
2362 }
2363 break;
2364 }
2365 case DexFile::kDexTypeAnnotationSetRefList: {
2366 if (!CheckInterAnnotationSetRefList()) {
2367 return false;
2368 }
2369 break;
2370 }
2371 case DexFile::kDexTypeAnnotationSetItem: {
2372 if (!CheckInterAnnotationSetItem()) {
2373 return false;
2374 }
2375 break;
2376 }
2377 case DexFile::kDexTypeClassDataItem: {
David Sehr28e74ed2016-11-21 12:52:12 -08002378 // There shouldn't be more class data than type ids allow.
2379 // This check should be redundant, since there are checks that the
2380 // class_idx_ is within range and that there is only one definition
2381 // for a given type id.
2382 if (i > kTypeIdLimit) {
2383 ErrorStringPrintf("Too many class data items");
2384 return false;
2385 }
jeffhao10037c82012-01-23 15:06:23 -08002386 if (!CheckInterClassDataItem()) {
2387 return false;
2388 }
2389 break;
2390 }
2391 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2392 if (!CheckInterAnnotationsDirectoryItem()) {
2393 return false;
2394 }
2395 break;
2396 }
2397 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002398 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002399 return false;
2400 }
2401
2402 previous_item_ = prev_ptr;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002403 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08002404 }
2405
2406 return true;
2407}
2408
2409bool DexFileVerifier::CheckInterSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08002410 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08002411 const DexFile::MapItem* item = map->list_;
2412 uint32_t count = map->size_;
2413
2414 // Cross check the items listed in the map.
2415 while (count--) {
2416 uint32_t section_offset = item->offset_;
2417 uint32_t section_count = item->size_;
2418 uint16_t type = item->type_;
2419
2420 switch (type) {
2421 case DexFile::kDexTypeHeaderItem:
2422 case DexFile::kDexTypeMapList:
2423 case DexFile::kDexTypeTypeList:
2424 case DexFile::kDexTypeCodeItem:
2425 case DexFile::kDexTypeStringDataItem:
2426 case DexFile::kDexTypeDebugInfoItem:
2427 case DexFile::kDexTypeAnnotationItem:
2428 case DexFile::kDexTypeEncodedArrayItem:
2429 break;
2430 case DexFile::kDexTypeStringIdItem:
2431 case DexFile::kDexTypeTypeIdItem:
2432 case DexFile::kDexTypeProtoIdItem:
2433 case DexFile::kDexTypeFieldIdItem:
2434 case DexFile::kDexTypeMethodIdItem:
2435 case DexFile::kDexTypeClassDefItem:
2436 case DexFile::kDexTypeAnnotationSetRefList:
2437 case DexFile::kDexTypeAnnotationSetItem:
2438 case DexFile::kDexTypeClassDataItem:
2439 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2440 if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2441 return false;
2442 }
2443 break;
2444 }
2445 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002446 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002447 return false;
2448 }
2449
2450 item++;
2451 }
2452
2453 return true;
2454}
2455
2456bool DexFileVerifier::Verify() {
2457 // Check the header.
2458 if (!CheckHeader()) {
2459 return false;
2460 }
2461
2462 // Check the map section.
2463 if (!CheckMap()) {
2464 return false;
2465 }
2466
2467 // Check structure within remaining sections.
2468 if (!CheckIntraSection()) {
2469 return false;
2470 }
2471
2472 // Check references from one section to another.
2473 if (!CheckInterSection()) {
2474 return false;
2475 }
2476
2477 return true;
2478}
2479
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002480void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2481 va_list ap;
2482 va_start(ap, fmt);
2483 DCHECK(failure_reason_.empty()) << failure_reason_;
2484 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2485 StringAppendV(&failure_reason_, fmt, ap);
2486 va_end(ap);
2487}
2488
Andreas Gampee6215c02015-08-31 18:54:38 -07002489// Fields and methods may have only one of public/protected/private.
2490static bool CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags) {
2491 size_t count = (((flags & kAccPublic) == 0) ? 0 : 1) +
2492 (((flags & kAccProtected) == 0) ? 0 : 1) +
2493 (((flags & kAccPrivate) == 0) ? 0 : 1);
2494 return count <= 1;
2495}
2496
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002497// Helper functions to retrieve names from the dex file. We do not want to rely on DexFile
2498// functionality, as we're still verifying the dex file. begin and header correspond to the
2499// underscored variants in the DexFileVerifier.
2500
2501static std::string GetStringOrError(const uint8_t* const begin,
2502 const DexFile::Header* const header,
2503 uint32_t string_idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002504 // The `string_idx` is not guaranteed to be valid yet.
2505 if (header->string_ids_size_ <= string_idx) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002506 return "(error)";
2507 }
2508
2509 const DexFile::StringId* string_id =
2510 reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx;
2511
2512 // Assume that the data is OK at this point. String data has been checked at this point.
2513
2514 const uint8_t* ptr = begin + string_id->string_data_off_;
Andreas Gampebed6daf2016-09-02 18:12:00 -07002515 uint32_t dummy;
2516 if (!DecodeUnsignedLeb128Checked(&ptr, begin + header->file_size_, &dummy)) {
2517 return "(error)";
2518 }
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002519 return reinterpret_cast<const char*>(ptr);
2520}
2521
2522static std::string GetClassOrError(const uint8_t* const begin,
2523 const DexFile::Header* const header,
Andreas Gampea5b09a62016-11-17 15:21:22 -08002524 dex::TypeIndex class_idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002525 // The `class_idx` is either `FieldId::class_idx_` or `MethodId::class_idx_` and
2526 // it has already been checked in `DexFileVerifier::CheckClassDataItemField()`
2527 // or `DexFileVerifier::CheckClassDataItemMethod()`, respectively, to match
2528 // a valid defining class.
Andreas Gampea5b09a62016-11-17 15:21:22 -08002529 CHECK_LT(class_idx.index_, header->type_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002530
2531 const DexFile::TypeId* type_id =
Andreas Gampea5b09a62016-11-17 15:21:22 -08002532 reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx.index_;
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002533
2534 // Assume that the data is OK at this point. Type id offsets have been checked at this point.
2535
2536 return GetStringOrError(begin, header, type_id->descriptor_idx_);
2537}
2538
2539static std::string GetFieldDescriptionOrError(const uint8_t* const begin,
2540 const DexFile::Header* const header,
2541 uint32_t idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002542 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemField()`.
2543 CHECK_LT(idx, header->field_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002544
2545 const DexFile::FieldId* field_id =
2546 reinterpret_cast<const DexFile::FieldId*>(begin + header->field_ids_off_) + idx;
2547
2548 // Assume that the data is OK at this point. Field id offsets have been checked at this point.
2549
2550 std::string class_name = GetClassOrError(begin, header, field_id->class_idx_);
2551 std::string field_name = GetStringOrError(begin, header, field_id->name_idx_);
2552
2553 return class_name + "." + field_name;
2554}
2555
2556static std::string GetMethodDescriptionOrError(const uint8_t* const begin,
2557 const DexFile::Header* const header,
2558 uint32_t idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002559 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemMethod()`.
2560 CHECK_LT(idx, header->method_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002561
2562 const DexFile::MethodId* method_id =
2563 reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) + idx;
2564
2565 // Assume that the data is OK at this point. Method id offsets have been checked at this point.
2566
2567 std::string class_name = GetClassOrError(begin, header, method_id->class_idx_);
2568 std::string method_name = GetStringOrError(begin, header, method_id->name_idx_);
2569
2570 return class_name + "." + method_name;
2571}
2572
2573bool DexFileVerifier::CheckFieldAccessFlags(uint32_t idx,
2574 uint32_t field_access_flags,
Andreas Gampee6215c02015-08-31 18:54:38 -07002575 uint32_t class_access_flags,
2576 std::string* error_msg) {
2577 // Generally sort out >16-bit flags.
2578 if ((field_access_flags & ~kAccJavaFlagsMask) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002579 *error_msg = StringPrintf("Bad field access_flags for %s: %x(%s)",
2580 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2581 field_access_flags,
2582 PrettyJavaAccessFlags(field_access_flags).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002583 return false;
2584 }
2585
2586 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
2587 constexpr uint32_t kFieldAccessFlags = kAccPublic |
2588 kAccPrivate |
2589 kAccProtected |
2590 kAccStatic |
2591 kAccFinal |
2592 kAccVolatile |
2593 kAccTransient |
2594 kAccSynthetic |
2595 kAccEnum;
2596
2597 // Fields may have only one of public/protected/final.
2598 if (!CheckAtMostOneOfPublicProtectedPrivate(field_access_flags)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002599 *error_msg = StringPrintf("Field may have only one of public/protected/private, %s: %x(%s)",
2600 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2601 field_access_flags,
2602 PrettyJavaAccessFlags(field_access_flags).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002603 return false;
2604 }
2605
2606 // Interfaces have a pretty restricted list.
2607 if ((class_access_flags & kAccInterface) != 0) {
2608 // Interface fields must be public final static.
2609 constexpr uint32_t kPublicFinalStatic = kAccPublic | kAccFinal | kAccStatic;
2610 if ((field_access_flags & kPublicFinalStatic) != kPublicFinalStatic) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002611 *error_msg = StringPrintf("Interface field is not public final static, %s: %x(%s)",
2612 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2613 field_access_flags,
2614 PrettyJavaAccessFlags(field_access_flags).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002615 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002616 return false;
2617 } else {
2618 // Allow in older versions, but warn.
2619 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2620 << *error_msg;
2621 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002622 }
2623 // Interface fields may be synthetic, but may not have other flags.
2624 constexpr uint32_t kDisallowed = ~(kPublicFinalStatic | kAccSynthetic);
2625 if ((field_access_flags & kFieldAccessFlags & kDisallowed) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002626 *error_msg = StringPrintf("Interface field has disallowed flag, %s: %x(%s)",
2627 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2628 field_access_flags,
2629 PrettyJavaAccessFlags(field_access_flags).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002630 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002631 return false;
2632 } else {
2633 // Allow in older versions, but warn.
2634 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2635 << *error_msg;
2636 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002637 }
2638 return true;
2639 }
2640
2641 // Volatile fields may not be final.
2642 constexpr uint32_t kVolatileFinal = kAccVolatile | kAccFinal;
2643 if ((field_access_flags & kVolatileFinal) == kVolatileFinal) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002644 *error_msg = StringPrintf("Fields may not be volatile and final: %s",
2645 GetFieldDescriptionOrError(begin_, header_, idx).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002646 return false;
2647 }
2648
2649 return true;
2650}
2651
2652// Try to find the name of the method with the given index. We do not want to rely on DexFile
2653// infrastructure at this point, so do it all by hand. begin and header correspond to begin_ and
2654// header_ of the DexFileVerifier. str will contain the pointer to the method name on success
2655// (flagged by the return value), otherwise error_msg will contain an error string.
2656static bool FindMethodName(uint32_t method_index,
2657 const uint8_t* begin,
2658 const DexFile::Header* header,
2659 const char** str,
2660 std::string* error_msg) {
2661 if (method_index >= header->method_ids_size_) {
2662 *error_msg = "Method index not available for method flags verification";
2663 return false;
2664 }
2665 uint32_t string_idx =
2666 (reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) +
2667 method_index)->name_idx_;
2668 if (string_idx >= header->string_ids_size_) {
2669 *error_msg = "String index not available for method flags verification";
2670 return false;
2671 }
2672 uint32_t string_off =
2673 (reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx)->
2674 string_data_off_;
2675 if (string_off >= header->file_size_) {
2676 *error_msg = "String offset out of bounds for method flags verification";
2677 return false;
2678 }
2679 const uint8_t* str_data_ptr = begin + string_off;
Andreas Gampebed6daf2016-09-02 18:12:00 -07002680 uint32_t dummy;
2681 if (!DecodeUnsignedLeb128Checked(&str_data_ptr, begin + header->file_size_, &dummy)) {
2682 *error_msg = "String size out of bounds for method flags verification";
2683 return false;
2684 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002685 *str = reinterpret_cast<const char*>(str_data_ptr);
2686 return true;
2687}
2688
2689bool DexFileVerifier::CheckMethodAccessFlags(uint32_t method_index,
2690 uint32_t method_access_flags,
2691 uint32_t class_access_flags,
2692 bool has_code,
2693 bool expect_direct,
2694 std::string* error_msg) {
2695 // Generally sort out >16-bit flags, except dex knows Constructor and DeclaredSynchronized.
2696 constexpr uint32_t kAllMethodFlags =
2697 kAccJavaFlagsMask | kAccConstructor | kAccDeclaredSynchronized;
2698 if ((method_access_flags & ~kAllMethodFlags) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002699 *error_msg = StringPrintf("Bad method access_flags for %s: %x",
2700 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
2701 method_access_flags);
Andreas Gampee6215c02015-08-31 18:54:38 -07002702 return false;
2703 }
2704
2705 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
2706 constexpr uint32_t kMethodAccessFlags = kAccPublic |
2707 kAccPrivate |
2708 kAccProtected |
2709 kAccStatic |
2710 kAccFinal |
2711 kAccSynthetic |
2712 kAccSynchronized |
2713 kAccBridge |
2714 kAccVarargs |
2715 kAccNative |
2716 kAccAbstract |
2717 kAccStrict;
2718
2719 // Methods may have only one of public/protected/final.
2720 if (!CheckAtMostOneOfPublicProtectedPrivate(method_access_flags)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002721 *error_msg = StringPrintf("Method may have only one of public/protected/private, %s: %x",
2722 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002723 method_access_flags);
2724 return false;
2725 }
2726
2727 // Try to find the name, to check for constructor properties.
2728 const char* str;
2729 if (!FindMethodName(method_index, begin_, header_, &str, error_msg)) {
2730 return false;
2731 }
2732 bool is_init_by_name = false;
2733 constexpr const char* kInitName = "<init>";
2734 size_t str_offset = (reinterpret_cast<const uint8_t*>(str) - begin_);
2735 if (header_->file_size_ - str_offset >= sizeof(kInitName)) {
2736 is_init_by_name = strcmp(kInitName, str) == 0;
2737 }
2738 bool is_clinit_by_name = false;
2739 constexpr const char* kClinitName = "<clinit>";
2740 if (header_->file_size_ - str_offset >= sizeof(kClinitName)) {
2741 is_clinit_by_name = strcmp(kClinitName, str) == 0;
2742 }
2743 bool is_constructor = is_init_by_name || is_clinit_by_name;
2744
2745 // Only methods named "<clinit>" or "<init>" may be marked constructor. Note: we cannot enforce
2746 // the reverse for backwards compatibility reasons.
2747 if (((method_access_flags & kAccConstructor) != 0) && !is_constructor) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002748 *error_msg =
2749 StringPrintf("Method %" PRIu32 "(%s) is marked constructor, but doesn't match name",
2750 method_index,
2751 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002752 return false;
2753 }
2754 // Check that the static constructor (= static initializer) is named "<clinit>" and that the
2755 // instance constructor is called "<init>".
2756 if (is_constructor) {
2757 bool is_static = (method_access_flags & kAccStatic) != 0;
2758 if (is_static ^ is_clinit_by_name) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002759 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) is not flagged correctly wrt/ static.",
2760 method_index,
2761 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightf0ecae72016-05-06 10:39:06 -07002762 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2763 return false;
2764 } else {
2765 // Allow in older versions, but warn.
2766 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2767 << *error_msg;
2768 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002769 }
2770 }
2771 // Check that static and private methods, as well as constructors, are in the direct methods list,
2772 // and other methods in the virtual methods list.
2773 bool is_direct = (method_access_flags & (kAccStatic | kAccPrivate)) != 0 || is_constructor;
2774 if (is_direct != expect_direct) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002775 *error_msg = StringPrintf("Direct/virtual method %" PRIu32 "(%s) not in expected list %d",
Andreas Gampee6215c02015-08-31 18:54:38 -07002776 method_index,
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002777 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002778 expect_direct);
2779 return false;
2780 }
2781
2782
2783 // From here on out it is easier to mask out the bits we're supposed to ignore.
2784 method_access_flags &= kMethodAccessFlags;
2785
Alex Lightd7c10c22016-03-31 10:03:07 -07002786 // Interfaces are special.
2787 if ((class_access_flags & kAccInterface) != 0) {
Alex Lightb55f1ac2016-04-12 15:50:55 -07002788 // Non-static interface methods must be public or private.
2789 uint32_t desired_flags = (kAccPublic | kAccStatic);
2790 if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2791 desired_flags |= kAccPrivate;
2792 }
2793 if ((method_access_flags & desired_flags) == 0) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002794 *error_msg = StringPrintf("Interface virtual method %" PRIu32 "(%s) is not public",
2795 method_index,
2796 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002797 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002798 return false;
2799 } else {
2800 // Allow in older versions, but warn.
2801 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2802 << *error_msg;
2803 }
2804 }
2805 }
2806
Andreas Gampee6215c02015-08-31 18:54:38 -07002807 // If there aren't any instructions, make sure that's expected.
2808 if (!has_code) {
2809 // Only native or abstract methods may not have code.
2810 if ((method_access_flags & (kAccNative | kAccAbstract)) == 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002811 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has no code, but is not marked native or "
Andreas Gampee6215c02015-08-31 18:54:38 -07002812 "abstract",
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002813 method_index,
2814 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002815 return false;
2816 }
2817 // Constructors must always have code.
2818 if (is_constructor) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002819 *error_msg = StringPrintf("Constructor %u(%s) must not be abstract or native",
2820 method_index,
2821 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightf0ecae72016-05-06 10:39:06 -07002822 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2823 return false;
2824 } else {
2825 // Allow in older versions, but warn.
2826 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2827 << *error_msg;
2828 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002829 }
2830 if ((method_access_flags & kAccAbstract) != 0) {
2831 // Abstract methods are not allowed to have the following flags.
2832 constexpr uint32_t kForbidden =
2833 kAccPrivate | kAccStatic | kAccFinal | kAccNative | kAccStrict | kAccSynchronized;
2834 if ((method_access_flags & kForbidden) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002835 *error_msg = StringPrintf("Abstract method %" PRIu32 "(%s) has disallowed access flags %x",
2836 method_index,
2837 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
2838 method_access_flags);
Andreas Gampee6215c02015-08-31 18:54:38 -07002839 return false;
2840 }
Andreas Gampe97b11352015-12-10 16:23:41 -08002841 // Abstract methods should be in an abstract class or interface.
Andreas Gampee6215c02015-08-31 18:54:38 -07002842 if ((class_access_flags & (kAccInterface | kAccAbstract)) == 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002843 LOG(WARNING) << "Method " << GetMethodDescriptionOrError(begin_, header_, method_index)
Andreas Gampe97b11352015-12-10 16:23:41 -08002844 << " is abstract, but the declaring class is neither abstract nor an "
2845 << "interface in dex file "
2846 << dex_file_->GetLocation();
Andreas Gampee6215c02015-08-31 18:54:38 -07002847 }
2848 }
2849 // Interfaces are special.
2850 if ((class_access_flags & kAccInterface) != 0) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002851 // Interface methods without code must be abstract.
Andreas Gampee6215c02015-08-31 18:54:38 -07002852 if ((method_access_flags & (kAccPublic | kAccAbstract)) != (kAccPublic | kAccAbstract)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002853 *error_msg = StringPrintf("Interface method %" PRIu32 "(%s) is not public and abstract",
2854 method_index,
2855 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002856 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002857 return false;
2858 } else {
2859 // Allow in older versions, but warn.
2860 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2861 << *error_msg;
2862 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002863 }
2864 // At this point, we know the method is public and abstract. This means that all the checks
2865 // for invalid combinations above applies. In addition, interface methods must not be
2866 // protected. This is caught by the check for only-one-of-public-protected-private.
2867 }
2868 return true;
2869 }
2870
2871 // When there's code, the method must not be native or abstract.
2872 if ((method_access_flags & (kAccNative | kAccAbstract)) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002873 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has code, but is marked native or abstract",
2874 method_index,
2875 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002876 return false;
2877 }
2878
Andreas Gampee6215c02015-08-31 18:54:38 -07002879 // Instance constructors must not be synchronized and a few other flags.
2880 if (is_init_by_name) {
2881 static constexpr uint32_t kInitAllowed =
2882 kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic;
2883 if ((method_access_flags & ~kInitAllowed) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002884 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) flagged inappropriately %x",
Andreas Gampee6215c02015-08-31 18:54:38 -07002885 method_index,
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002886 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002887 method_access_flags);
2888 return false;
2889 }
2890 }
2891
2892 return true;
2893}
2894
jeffhao10037c82012-01-23 15:06:23 -08002895} // namespace art