blob: 07f0fcae562696479d05de3b972aad8fe8d7fce7 [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 Gampe8a0128a2016-11-28 07:38:35 -080083const char* DexFileVerifier::CheckLoadStringByIdx(dex::StringIndex idx, const char* error_string) {
84 if (UNLIKELY(!CheckIndex(idx.index_, 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 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -080095 return CheckLoadStringByIdx(dex_file_->GetTypeId(type_idx).descriptor_idx_, error_string);
Andreas Gampee09269c2014-06-06 18:45:35 -070096}
97
98const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070099 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -0700100 return nullptr;
101 }
102 return &dex_file_->GetFieldId(idx);
103}
104
105const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -0700106 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -0700107 return nullptr;
108 }
109 return &dex_file_->GetMethodId(idx);
110}
111
112// Helper macro to load string and return false on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700113#define LOAD_STRING(var, idx, error) \
114 const char* (var) = CheckLoadStringByIdx(idx, error); \
115 if (UNLIKELY((var) == nullptr)) { \
116 return false; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700117 }
118
119// Helper macro to load string by type idx and return false on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700120#define LOAD_STRING_BY_TYPE(var, type_idx, error) \
121 const char* (var) = CheckLoadStringByTypeIdx(type_idx, error); \
122 if (UNLIKELY((var) == nullptr)) { \
123 return false; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700124 }
125
126// Helper macro to load method id. Return last parameter on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700127#define LOAD_METHOD(var, idx, error_string, error_stmt) \
128 const DexFile::MethodId* (var) = CheckLoadMethodId(idx, error_string); \
129 if (UNLIKELY((var) == nullptr)) { \
130 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700131 }
132
133// Helper macro to load method id. Return last parameter on error.
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700134#define LOAD_FIELD(var, idx, fmt, error_stmt) \
135 const DexFile::FieldId* (var) = CheckLoadFieldId(idx, fmt); \
136 if (UNLIKELY((var) == nullptr)) { \
137 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700138 }
139
Aart Bik37d6a3b2016-06-21 18:30:10 -0700140bool DexFileVerifier::Verify(const DexFile* dex_file,
141 const uint8_t* begin,
142 size_t size,
143 const char* location,
144 bool verify_checksum,
145 std::string* error_msg) {
146 std::unique_ptr<DexFileVerifier> verifier(
147 new DexFileVerifier(dex_file, begin, size, location, verify_checksum));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700148 if (!verifier->Verify()) {
149 *error_msg = verifier->FailureReason();
150 return false;
151 }
152 return true;
153}
154
155bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
156 bool is_return_type) {
jeffhao10037c82012-01-23 15:06:23 -0800157 switch (shorty_char) {
158 case 'V':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700159 if (UNLIKELY(!is_return_type)) {
160 ErrorStringPrintf("Invalid use of void");
jeffhao10037c82012-01-23 15:06:23 -0800161 return false;
162 }
Ian Rogersfc787ec2014-10-09 21:56:44 -0700163 FALLTHROUGH_INTENDED;
jeffhao10037c82012-01-23 15:06:23 -0800164 case 'B':
165 case 'C':
166 case 'D':
167 case 'F':
168 case 'I':
169 case 'J':
170 case 'S':
171 case 'Z':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700172 if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
173 ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
174 shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800175 return false;
176 }
177 break;
178 case 'L':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700179 if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
180 ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800181 return false;
182 }
183 break;
184 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700185 ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
jeffhao10037c82012-01-23 15:06:23 -0800186 return false;
187 }
188 return true;
189}
190
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700191bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700192 const char* label) {
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700193 // Check that size is not 0.
194 CHECK_NE(elem_size, 0U);
195
Ian Rogers13735952014-10-08 12:43:28 -0700196 const uint8_t* range_start = reinterpret_cast<const uint8_t*>(start);
197 const uint8_t* file_start = reinterpret_cast<const uint8_t*>(begin_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700198
199 // Check for overflow.
200 uintptr_t max = 0 - 1;
201 size_t available_bytes_till_end_of_mem = max - reinterpret_cast<uintptr_t>(start);
202 size_t max_count = available_bytes_till_end_of_mem / elem_size;
203 if (max_count < count) {
204 ErrorStringPrintf("Overflow in range for %s: %zx for %zu@%zu", label,
205 static_cast<size_t>(range_start - file_start),
206 count, elem_size);
207 return false;
208 }
209
Ian Rogers13735952014-10-08 12:43:28 -0700210 const uint8_t* range_end = range_start + count * elem_size;
211 const uint8_t* file_end = file_start + size_;
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700212 if (UNLIKELY((range_start < file_start) || (range_end > file_end))) {
213 // Note: these two tests are enough as we make sure above that there's no overflow.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800214 ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
Ian Rogerse3d55812014-06-11 13:00:44 -0700215 static_cast<size_t>(range_start - file_start),
216 static_cast<size_t>(range_end - file_start));
jeffhao10037c82012-01-23 15:06:23 -0800217 return false;
218 }
219 return true;
220}
221
Ian Rogers13735952014-10-08 12:43:28 -0700222bool DexFileVerifier::CheckList(size_t element_size, const char* label, const uint8_t* *ptr) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700223 // Check that the list is available. The first 4B are the count.
224 if (!CheckListSize(*ptr, 1, 4U, label)) {
225 return false;
226 }
227
228 uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
229 if (count > 0) {
230 if (!CheckListSize(*ptr + 4, count, element_size, label)) {
231 return false;
232 }
233 }
234
235 *ptr += 4 + count * element_size;
236 return true;
237}
238
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700239bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
240 if (UNLIKELY(field >= limit)) {
241 ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
jeffhao10037c82012-01-23 15:06:23 -0800242 return false;
243 }
244 return true;
245}
246
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800247bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset,
248 uint32_t size,
249 size_t alignment,
250 const char* label) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700251 if (size == 0) {
252 if (offset != 0) {
253 ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
254 return false;
255 }
256 }
257 if (size_ <= offset) {
258 ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
259 return false;
260 }
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800261 if (alignment != 0 && !IsAlignedParam(offset, alignment)) {
262 ErrorStringPrintf("Offset(%d) should be aligned by %zu for %s.", offset, alignment, label);
263 return false;
264 }
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700265 return true;
266}
267
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100268bool DexFileVerifier::CheckSizeLimit(uint32_t size, uint32_t limit, const char* label) {
269 if (size > limit) {
270 ErrorStringPrintf("Size(%u) should not exceed limit(%u) for %s.", size, limit, label);
271 return false;
272 }
273 return true;
274}
275
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700276bool DexFileVerifier::CheckHeader() {
jeffhaof6174e82012-01-31 16:14:17 -0800277 // Check file size from the header.
278 uint32_t expected_size = header_->file_size_;
279 if (size_ != expected_size) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700280 ErrorStringPrintf("Bad file size (%zd, expected %ud)", size_, expected_size);
jeffhao10037c82012-01-23 15:06:23 -0800281 return false;
282 }
283
284 // Compute and verify the checksum in the header.
285 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
286 const uint32_t non_sum = sizeof(header_->magic_) + sizeof(header_->checksum_);
Ian Rogers13735952014-10-08 12:43:28 -0700287 const uint8_t* non_sum_ptr = reinterpret_cast<const uint8_t*>(header_) + non_sum;
jeffhaof6174e82012-01-31 16:14:17 -0800288 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
jeffhao10037c82012-01-23 15:06:23 -0800289 if (adler_checksum != header_->checksum_) {
Aart Bik37d6a3b2016-06-21 18:30:10 -0700290 if (verify_checksum_) {
291 ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
292 return false;
293 } else {
294 LOG(WARNING) << StringPrintf(
295 "Ignoring bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
296 }
jeffhao10037c82012-01-23 15:06:23 -0800297 }
298
299 // Check the contents of the header.
300 if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700301 ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
jeffhao10037c82012-01-23 15:06:23 -0800302 return false;
303 }
304
305 if (header_->header_size_ != sizeof(DexFile::Header)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700306 ErrorStringPrintf("Bad header size: %ud", header_->header_size_);
jeffhao10037c82012-01-23 15:06:23 -0800307 return false;
308 }
309
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700310 // Check that all offsets are inside the file.
311 bool result =
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800312 CheckValidOffsetAndSize(header_->link_off_,
313 header_->link_size_,
314 0 /* unaligned */,
315 "link") &&
316 CheckValidOffsetAndSize(header_->map_off_,
317 header_->map_off_,
318 4,
319 "map") &&
320 CheckValidOffsetAndSize(header_->string_ids_off_,
321 header_->string_ids_size_,
322 4,
323 "string-ids") &&
324 CheckValidOffsetAndSize(header_->type_ids_off_,
325 header_->type_ids_size_,
326 4,
327 "type-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100328 CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800329 CheckValidOffsetAndSize(header_->proto_ids_off_,
330 header_->proto_ids_size_,
331 4,
332 "proto-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100333 CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800334 CheckValidOffsetAndSize(header_->field_ids_off_,
335 header_->field_ids_size_,
336 4,
337 "field-ids") &&
338 CheckValidOffsetAndSize(header_->method_ids_off_,
339 header_->method_ids_size_,
340 4,
341 "method-ids") &&
342 CheckValidOffsetAndSize(header_->class_defs_off_,
343 header_->class_defs_size_,
344 4,
345 "class-defs") &&
346 CheckValidOffsetAndSize(header_->data_off_,
347 header_->data_size_,
348 0, // Unaligned, spec doesn't talk about it, even though size
349 // is supposed to be a multiple of 4.
350 "data");
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700351 return result;
jeffhao10037c82012-01-23 15:06:23 -0800352}
353
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700354bool DexFileVerifier::CheckMap() {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700355 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ +
356 header_->map_off_);
357 // Check that map list content is available.
358 if (!CheckListSize(map, 1, sizeof(DexFile::MapList), "maplist content")) {
359 return false;
360 }
361
jeffhao10037c82012-01-23 15:06:23 -0800362 const DexFile::MapItem* item = map->list_;
363
364 uint32_t count = map->size_;
365 uint32_t last_offset = 0;
366 uint32_t data_item_count = 0;
367 uint32_t data_items_left = header_->data_size_;
368 uint32_t used_bits = 0;
369
370 // Sanity check the size of the map list.
371 if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
372 return false;
373 }
374
375 // Check the items listed in the map.
376 for (uint32_t i = 0; i < count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700377 if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
378 ErrorStringPrintf("Out of order map item: %x then %x", last_offset, item->offset_);
jeffhao10037c82012-01-23 15:06:23 -0800379 return false;
380 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700381 if (UNLIKELY(item->offset_ >= header_->file_size_)) {
382 ErrorStringPrintf("Map item after end of file: %x, size %x",
383 item->offset_, header_->file_size_);
jeffhao10037c82012-01-23 15:06:23 -0800384 return false;
385 }
386
387 if (IsDataSectionType(item->type_)) {
388 uint32_t icount = item->size_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700389 if (UNLIKELY(icount > data_items_left)) {
390 ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
jeffhao10037c82012-01-23 15:06:23 -0800391 return false;
392 }
393 data_items_left -= icount;
394 data_item_count += icount;
395 }
396
397 uint32_t bit = MapTypeToBitMask(item->type_);
398
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700399 if (UNLIKELY(bit == 0)) {
400 ErrorStringPrintf("Unknown map section type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800401 return false;
402 }
403
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700404 if (UNLIKELY((used_bits & bit) != 0)) {
405 ErrorStringPrintf("Duplicate map section of type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800406 return false;
407 }
408
409 used_bits |= bit;
410 last_offset = item->offset_;
411 item++;
412 }
413
414 // Check for missing sections in the map.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700415 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
416 ErrorStringPrintf("Map is missing header entry");
jeffhao10037c82012-01-23 15:06:23 -0800417 return false;
418 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700419 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
420 ErrorStringPrintf("Map is missing map_list entry");
jeffhao10037c82012-01-23 15:06:23 -0800421 return false;
422 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700423 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
424 ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
425 ErrorStringPrintf("Map is missing string_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800426 return false;
427 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700428 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
429 ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
430 ErrorStringPrintf("Map is missing type_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800431 return false;
432 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700433 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
434 ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
435 ErrorStringPrintf("Map is missing proto_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800436 return false;
437 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700438 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
439 ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
440 ErrorStringPrintf("Map is missing field_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800441 return false;
442 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700443 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
444 ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
445 ErrorStringPrintf("Map is missing method_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800446 return false;
447 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700448 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
449 ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
450 ErrorStringPrintf("Map is missing class_defs entry");
jeffhao10037c82012-01-23 15:06:23 -0800451 return false;
452 }
jeffhao10037c82012-01-23 15:06:23 -0800453 return true;
454}
455
456uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
457 uint32_t result = 0;
Ian Rogers13735952014-10-08 12:43:28 -0700458 if (LIKELY(CheckListSize(ptr_, size, sizeof(uint8_t), "encoded_value"))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700459 for (uint32_t i = 0; i < size; i++) {
460 result |= ((uint32_t) *(ptr_++)) << (i * 8);
461 }
jeffhao10037c82012-01-23 15:06:23 -0800462 }
jeffhao10037c82012-01-23 15:06:23 -0800463 return result;
464}
465
Andreas Gampebed6daf2016-09-02 18:12:00 -0700466
467#define DECODE_UNSIGNED_CHECKED_FROM_WITH_ERROR_VALUE(ptr, var, error_value) \
468 uint32_t var; \
Andreas Gampe44fd2352016-11-03 08:21:21 -0700469 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700470 return error_value; \
471 }
472
Andreas Gampe44fd2352016-11-03 08:21:21 -0700473#define DECODE_UNSIGNED_CHECKED_FROM(ptr, var) \
474 uint32_t var; \
475 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
476 ErrorStringPrintf("Read out of bounds"); \
477 return false; \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700478 }
479
Andreas Gampe44fd2352016-11-03 08:21:21 -0700480#define DECODE_SIGNED_CHECKED_FROM(ptr, var) \
481 int32_t var; \
482 if (!DecodeSignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
483 ErrorStringPrintf("Read out of bounds"); \
484 return false; \
Andreas Gampebed6daf2016-09-02 18:12:00 -0700485 }
486
jeffhao10037c82012-01-23 15:06:23 -0800487bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700488 uint32_t* handler_offsets, uint32_t handlers_size) {
Ian Rogers13735952014-10-08 12:43:28 -0700489 const uint8_t* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -0800490
491 for (uint32_t i = 0; i < handlers_size; i++) {
492 bool catch_all;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800493 size_t offset = ptr_ - handlers_base;
Andreas Gampebed6daf2016-09-02 18:12:00 -0700494 DECODE_SIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800495
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700496 if (UNLIKELY((size < -65536) || (size > 65536))) {
497 ErrorStringPrintf("Invalid exception handler size: %d", size);
jeffhao10037c82012-01-23 15:06:23 -0800498 return false;
499 }
500
501 if (size <= 0) {
502 catch_all = true;
503 size = -size;
504 } else {
505 catch_all = false;
506 }
507
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800508 handler_offsets[i] = static_cast<uint32_t>(offset);
jeffhao10037c82012-01-23 15:06:23 -0800509
510 while (size-- > 0) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700511 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -0800512 if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
513 return false;
514 }
515
Andreas Gampebed6daf2016-09-02 18:12:00 -0700516 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700517 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
518 ErrorStringPrintf("Invalid handler addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800519 return false;
520 }
521 }
522
523 if (catch_all) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700524 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700525 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
526 ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800527 return false;
528 }
529 }
530 }
531
532 return true;
533}
534
Andreas Gampee6215c02015-08-31 18:54:38 -0700535bool DexFileVerifier::CheckClassDataItemField(uint32_t idx,
536 uint32_t access_flags,
537 uint32_t class_access_flags,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800538 dex::TypeIndex class_type_index,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700539 bool expect_static) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700540 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800541 if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
542 return false;
543 }
544
Andreas Gampee6215c02015-08-31 18:54:38 -0700545 // Check that it's the right class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800546 dex::TypeIndex my_class_index =
Andreas Gampee6215c02015-08-31 18:54:38 -0700547 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)->
548 class_idx_;
549 if (class_type_index != my_class_index) {
550 ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800551 my_class_index.index_,
552 class_type_index.index_);
Andreas Gampee6215c02015-08-31 18:54:38 -0700553 return false;
554 }
555
556 // Check that it falls into the right class-data list.
jeffhao10037c82012-01-23 15:06:23 -0800557 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700558 if (UNLIKELY(is_static != expect_static)) {
559 ErrorStringPrintf("Static/instance field not in expected list");
jeffhao10037c82012-01-23 15:06:23 -0800560 return false;
561 }
562
Andreas Gampee6215c02015-08-31 18:54:38 -0700563 // Check field access flags.
564 std::string error_msg;
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800565 if (!CheckFieldAccessFlags(idx, access_flags, class_access_flags, &error_msg)) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700566 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800567 return false;
568 }
569
570 return true;
571}
572
Andreas Gampee6215c02015-08-31 18:54:38 -0700573bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx,
574 uint32_t access_flags,
575 uint32_t class_access_flags,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800576 dex::TypeIndex class_type_index,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700577 uint32_t code_offset,
Andreas Gampee6215c02015-08-31 18:54:38 -0700578 std::unordered_set<uint32_t>* direct_method_indexes,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700579 bool expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700580 DCHECK(direct_method_indexes != nullptr);
581 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800582 if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
583 return false;
584 }
585
Andreas Gampee6215c02015-08-31 18:54:38 -0700586 // Check that it's the right class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800587 dex::TypeIndex my_class_index =
Andreas Gampee6215c02015-08-31 18:54:38 -0700588 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)->
589 class_idx_;
590 if (class_type_index != my_class_index) {
Jeff Hao608f2ce2016-10-19 11:17:11 -0700591 ErrorStringPrintf("Method's class index unexpected, %" PRIu16 " vs %" PRIu16,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800592 my_class_index.index_,
593 class_type_index.index_);
jeffhao10037c82012-01-23 15:06:23 -0800594 return false;
595 }
596
Andreas Gampee6215c02015-08-31 18:54:38 -0700597 // Check that it's not defined as both direct and virtual.
Jeff Haoa574b0e2015-06-04 18:12:26 -0700598 if (expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700599 direct_method_indexes->insert(idx);
600 } else if (direct_method_indexes->find(idx) != direct_method_indexes->end()) {
Jeff Haoa574b0e2015-06-04 18:12:26 -0700601 ErrorStringPrintf("Found virtual method with same index as direct method: %d", idx);
602 return false;
603 }
604
Andreas Gampee6215c02015-08-31 18:54:38 -0700605 // Check method access flags.
606 bool has_code = (code_offset != 0);
607 std::string error_msg;
608 if (!CheckMethodAccessFlags(idx,
609 access_flags,
610 class_access_flags,
611 has_code,
612 expect_direct,
613 &error_msg)) {
614 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800615 return false;
616 }
617
618 return true;
619}
620
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800621bool DexFileVerifier::CheckPadding(size_t offset, uint32_t aligned_offset) {
jeffhao10037c82012-01-23 15:06:23 -0800622 if (offset < aligned_offset) {
Ian Rogers13735952014-10-08 12:43:28 -0700623 if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(uint8_t), "section")) {
jeffhao10037c82012-01-23 15:06:23 -0800624 return false;
625 }
626 while (offset < aligned_offset) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700627 if (UNLIKELY(*ptr_ != '\0')) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800628 ErrorStringPrintf("Non-zero padding %x before section start at %zx", *ptr_, offset);
jeffhao10037c82012-01-23 15:06:23 -0800629 return false;
630 }
631 ptr_++;
632 offset++;
633 }
634 }
635 return true;
636}
637
638bool DexFileVerifier::CheckEncodedValue() {
Ian Rogers13735952014-10-08 12:43:28 -0700639 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "encoded_value header")) {
jeffhao10037c82012-01-23 15:06:23 -0800640 return false;
641 }
642
643 uint8_t header_byte = *(ptr_++);
644 uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
645 uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
646
647 switch (value_type) {
648 case DexFile::kDexAnnotationByte:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700649 if (UNLIKELY(value_arg != 0)) {
650 ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800651 return false;
652 }
653 ptr_++;
654 break;
655 case DexFile::kDexAnnotationShort:
656 case DexFile::kDexAnnotationChar:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700657 if (UNLIKELY(value_arg > 1)) {
658 ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800659 return false;
660 }
661 ptr_ += value_arg + 1;
662 break;
663 case DexFile::kDexAnnotationInt:
664 case DexFile::kDexAnnotationFloat:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700665 if (UNLIKELY(value_arg > 3)) {
666 ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800667 return false;
668 }
669 ptr_ += value_arg + 1;
670 break;
671 case DexFile::kDexAnnotationLong:
672 case DexFile::kDexAnnotationDouble:
673 ptr_ += value_arg + 1;
674 break;
675 case DexFile::kDexAnnotationString: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700676 if (UNLIKELY(value_arg > 3)) {
677 ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800678 return false;
679 }
680 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
681 if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
682 return false;
683 }
684 break;
685 }
686 case DexFile::kDexAnnotationType: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700687 if (UNLIKELY(value_arg > 3)) {
688 ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800689 return false;
690 }
691 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
692 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
693 return false;
694 }
695 break;
696 }
697 case DexFile::kDexAnnotationField:
698 case DexFile::kDexAnnotationEnum: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700699 if (UNLIKELY(value_arg > 3)) {
700 ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800701 return false;
702 }
703 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
704 if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
705 return false;
706 }
707 break;
708 }
709 case DexFile::kDexAnnotationMethod: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700710 if (UNLIKELY(value_arg > 3)) {
711 ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800712 return false;
713 }
714 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
715 if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
716 return false;
717 }
718 break;
719 }
720 case DexFile::kDexAnnotationArray:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700721 if (UNLIKELY(value_arg != 0)) {
722 ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800723 return false;
724 }
725 if (!CheckEncodedArray()) {
726 return false;
727 }
728 break;
729 case DexFile::kDexAnnotationAnnotation:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700730 if (UNLIKELY(value_arg != 0)) {
731 ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800732 return false;
733 }
734 if (!CheckEncodedAnnotation()) {
735 return false;
736 }
737 break;
738 case DexFile::kDexAnnotationNull:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700739 if (UNLIKELY(value_arg != 0)) {
740 ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800741 return false;
742 }
743 break;
744 case DexFile::kDexAnnotationBoolean:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700745 if (UNLIKELY(value_arg > 1)) {
746 ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800747 return false;
748 }
749 break;
750 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700751 ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
jeffhao10037c82012-01-23 15:06:23 -0800752 return false;
753 }
754
755 return true;
756}
757
758bool DexFileVerifier::CheckEncodedArray() {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700759 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800760
761 while (size--) {
762 if (!CheckEncodedValue()) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700763 failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800764 return false;
765 }
766 }
767 return true;
768}
769
770bool DexFileVerifier::CheckEncodedAnnotation() {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700771 DECODE_UNSIGNED_CHECKED_FROM(ptr_, anno_idx);
772 if (!CheckIndex(anno_idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -0800773 return false;
774 }
775
Andreas Gampebed6daf2016-09-02 18:12:00 -0700776 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
jeffhao10037c82012-01-23 15:06:23 -0800777 uint32_t last_idx = 0;
778
779 for (uint32_t i = 0; i < size; i++) {
Andreas Gampebed6daf2016-09-02 18:12:00 -0700780 DECODE_UNSIGNED_CHECKED_FROM(ptr_, idx);
jeffhao10037c82012-01-23 15:06:23 -0800781 if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
782 return false;
783 }
784
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700785 if (UNLIKELY(last_idx >= idx && i != 0)) {
786 ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
787 last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -0800788 return false;
789 }
790
791 if (!CheckEncodedValue()) {
792 return false;
793 }
794
795 last_idx = idx;
796 }
797 return true;
798}
799
Andreas Gampee6215c02015-08-31 18:54:38 -0700800bool DexFileVerifier::FindClassFlags(uint32_t index,
801 bool is_field,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800802 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700803 uint32_t* class_access_flags) {
804 DCHECK(class_type_index != nullptr);
805 DCHECK(class_access_flags != nullptr);
806
807 // First check if the index is valid.
808 if (index >= (is_field ? header_->field_ids_size_ : header_->method_ids_size_)) {
809 return false;
810 }
811
812 // Next get the type index.
813 if (is_field) {
814 *class_type_index =
815 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + index)->
816 class_idx_;
817 } else {
818 *class_type_index =
819 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + index)->
820 class_idx_;
821 }
822
823 // Check if that is valid.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800824 if (class_type_index->index_ >= header_->type_ids_size_) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700825 return false;
826 }
827
828 // Now search for the class def. This is basically a specialized version of the DexFile code, as
829 // we should not trust that this is a valid DexFile just yet.
830 const DexFile::ClassDef* class_def_begin =
831 reinterpret_cast<const DexFile::ClassDef*>(begin_ + header_->class_defs_off_);
832 for (size_t i = 0; i < header_->class_defs_size_; ++i) {
833 const DexFile::ClassDef* class_def = class_def_begin + i;
834 if (class_def->class_idx_ == *class_type_index) {
835 *class_access_flags = class_def->access_flags_;
836 return true;
837 }
838 }
839
840 // Didn't find the class-def, not defined here...
841 return false;
842}
843
844bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field,
845 const char* type_descr,
846 uint32_t curr_index,
847 uint32_t prev_index,
848 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800849 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700850 uint32_t* class_access_flags) {
851 if (curr_index < prev_index) {
852 ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32,
853 type_descr,
854 prev_index,
855 curr_index);
856 return false;
857 }
858
859 if (!*have_class) {
860 *have_class = FindClassFlags(curr_index, is_field, class_type_index, class_access_flags);
861 if (!*have_class) {
862 // Should have really found one.
863 ErrorStringPrintf("could not find declaring class for %s index %" PRIu32,
864 type_descr,
865 curr_index);
866 return false;
867 }
868 }
869 return true;
870}
871
872template <bool kStatic>
873bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it,
874 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800875 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700876 uint32_t* class_access_flags) {
877 DCHECK(it != nullptr);
878 // These calls use the raw access flags to check whether the whole dex field is valid.
879 uint32_t prev_index = 0;
880 for (; kStatic ? it->HasNextStaticField() : it->HasNextInstanceField(); it->Next()) {
881 uint32_t curr_index = it->GetMemberIndex();
882 if (!CheckOrderAndGetClassFlags(true,
883 kStatic ? "static field" : "instance field",
884 curr_index,
885 prev_index,
886 have_class,
887 class_type_index,
888 class_access_flags)) {
889 return false;
890 }
891 prev_index = curr_index;
892
893 if (!CheckClassDataItemField(curr_index,
894 it->GetRawMemberAccessFlags(),
895 *class_access_flags,
896 *class_type_index,
897 kStatic)) {
898 return false;
899 }
900 }
901
902 return true;
903}
904
905template <bool kDirect>
906bool DexFileVerifier::CheckIntraClassDataItemMethods(
907 ClassDataItemIterator* it,
908 std::unordered_set<uint32_t>* direct_method_indexes,
909 bool* have_class,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800910 dex::TypeIndex* class_type_index,
Andreas Gampee6215c02015-08-31 18:54:38 -0700911 uint32_t* class_access_flags) {
912 uint32_t prev_index = 0;
913 for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) {
914 uint32_t curr_index = it->GetMemberIndex();
915 if (!CheckOrderAndGetClassFlags(false,
916 kDirect ? "direct method" : "virtual method",
917 curr_index,
918 prev_index,
919 have_class,
920 class_type_index,
921 class_access_flags)) {
922 return false;
923 }
924 prev_index = curr_index;
925
926 if (!CheckClassDataItemMethod(curr_index,
927 it->GetRawMemberAccessFlags(),
928 *class_access_flags,
929 *class_type_index,
930 it->GetMethodCodeItemOffset(),
931 direct_method_indexes,
932 kDirect)) {
933 return false;
934 }
935 }
936
937 return true;
938}
939
jeffhao10037c82012-01-23 15:06:23 -0800940bool DexFileVerifier::CheckIntraClassDataItem() {
941 ClassDataItemIterator it(*dex_file_, ptr_);
Jeff Haoa574b0e2015-06-04 18:12:26 -0700942 std::unordered_set<uint32_t> direct_method_indexes;
jeffhao10037c82012-01-23 15:06:23 -0800943
Andreas Gampee6215c02015-08-31 18:54:38 -0700944 // This code is complicated by the fact that we don't directly know which class this belongs to.
945 // So we need to explicitly search with the first item we find (either field or method), and then,
946 // as the lookup is expensive, cache the result.
947 bool have_class = false;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800948 dex::TypeIndex class_type_index;
Andreas Gampee6215c02015-08-31 18:54:38 -0700949 uint32_t class_access_flags;
950
951 // Check fields.
952 if (!CheckIntraClassDataItemFields<true>(&it,
953 &have_class,
954 &class_type_index,
955 &class_access_flags)) {
956 return false;
jeffhao10037c82012-01-23 15:06:23 -0800957 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700958 if (!CheckIntraClassDataItemFields<false>(&it,
959 &have_class,
960 &class_type_index,
961 &class_access_flags)) {
962 return false;
jeffhao10037c82012-01-23 15:06:23 -0800963 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700964
965 // Check methods.
966 if (!CheckIntraClassDataItemMethods<true>(&it,
967 &direct_method_indexes,
968 &have_class,
969 &class_type_index,
970 &class_access_flags)) {
971 return false;
jeffhao10037c82012-01-23 15:06:23 -0800972 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700973 if (!CheckIntraClassDataItemMethods<false>(&it,
974 &direct_method_indexes,
975 &have_class,
976 &class_type_index,
977 &class_access_flags)) {
978 return false;
jeffhao10037c82012-01-23 15:06:23 -0800979 }
980
981 ptr_ = it.EndDataPointer();
982 return true;
983}
984
985bool DexFileVerifier::CheckIntraCodeItem() {
986 const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700987 if (!CheckListSize(code_item, 1, sizeof(DexFile::CodeItem), "code")) {
jeffhao10037c82012-01-23 15:06:23 -0800988 return false;
989 }
990
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700991 if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
992 ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
993 code_item->ins_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800994 return false;
995 }
996
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700997 if (UNLIKELY((code_item->outs_size_ > 5) &&
998 (code_item->outs_size_ > code_item->registers_size_))) {
jeffhao10037c82012-01-23 15:06:23 -0800999 /*
1000 * outs_size can be up to 5, even if registers_size is smaller, since the
1001 * short forms of method invocation allow repetitions of a register multiple
1002 * times within a single parameter list. However, longer parameter lists
1003 * need to be represented in-order in the register file.
1004 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001005 ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
1006 code_item->outs_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -08001007 return false;
1008 }
1009
1010 const uint16_t* insns = code_item->insns_;
1011 uint32_t insns_size = code_item->insns_size_in_code_units_;
1012 if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
1013 return false;
1014 }
1015
1016 // Grab the end of the insns if there are no try_items.
1017 uint32_t try_items_size = code_item->tries_size_;
1018 if (try_items_size == 0) {
Ian Rogers13735952014-10-08 12:43:28 -07001019 ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -08001020 return true;
1021 }
1022
1023 // try_items are 4-byte aligned. Verify the spacer is 0.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001024 if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001025 ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -08001026 return false;
1027 }
1028
1029 const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -08001030 if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
1031 return false;
1032 }
1033
Anestis Bechtsoudis6a8df532015-07-12 12:51:35 -05001034 ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
Andreas Gampebed6daf2016-09-02 18:12:00 -07001035 DECODE_UNSIGNED_CHECKED_FROM(ptr_, handlers_size);
Anestis Bechtsoudis6a8df532015-07-12 12:51:35 -05001036
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001037 if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
1038 ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
jeffhao10037c82012-01-23 15:06:23 -08001039 return false;
1040 }
1041
Ian Rogers700a4022014-05-19 16:49:03 -07001042 std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001043 if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
jeffhao10037c82012-01-23 15:06:23 -08001044 return false;
1045 }
1046
1047 uint32_t last_addr = 0;
1048 while (try_items_size--) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001049 if (UNLIKELY(try_items->start_addr_ < last_addr)) {
1050 ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001051 return false;
1052 }
1053
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001054 if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
1055 ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001056 return false;
1057 }
1058
1059 uint32_t i;
1060 for (i = 0; i < handlers_size; i++) {
1061 if (try_items->handler_off_ == handler_offsets[i]) {
1062 break;
1063 }
1064 }
1065
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001066 if (UNLIKELY(i == handlers_size)) {
1067 ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
jeffhao10037c82012-01-23 15:06:23 -08001068 return false;
1069 }
1070
1071 last_addr = try_items->start_addr_ + try_items->insn_count_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001072 if (UNLIKELY(last_addr > insns_size)) {
1073 ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
jeffhao10037c82012-01-23 15:06:23 -08001074 return false;
1075 }
1076
1077 try_items++;
1078 }
1079
1080 return true;
1081}
1082
1083bool DexFileVerifier::CheckIntraStringDataItem() {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001084 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
Ian Rogers13735952014-10-08 12:43:28 -07001085 const uint8_t* file_end = begin_ + size_;
jeffhao10037c82012-01-23 15:06:23 -08001086
1087 for (uint32_t i = 0; i < size; i++) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001088 CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001089 if (UNLIKELY(ptr_ >= file_end)) {
1090 ErrorStringPrintf("String data would go beyond end-of-file");
jeffhao10037c82012-01-23 15:06:23 -08001091 return false;
1092 }
1093
1094 uint8_t byte = *(ptr_++);
1095
1096 // Switch on the high 4 bits.
1097 switch (byte >> 4) {
1098 case 0x00:
1099 // Special case of bit pattern 0xxx.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001100 if (UNLIKELY(byte == 0)) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001101 CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001102 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001103 return false;
1104 }
1105 break;
1106 case 0x01:
1107 case 0x02:
1108 case 0x03:
1109 case 0x04:
1110 case 0x05:
1111 case 0x06:
1112 case 0x07:
1113 // No extra checks necessary for bit pattern 0xxx.
1114 break;
1115 case 0x08:
1116 case 0x09:
1117 case 0x0a:
1118 case 0x0b:
1119 case 0x0f:
1120 // Illegal bit patterns 10xx or 1111.
1121 // Note: 1111 is valid for normal UTF-8, but not here.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001122 ErrorStringPrintf("Illegal start byte %x in string data", byte);
jeffhao10037c82012-01-23 15:06:23 -08001123 return false;
1124 case 0x0c:
1125 case 0x0d: {
1126 // Bit pattern 110x has an additional byte.
1127 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001128 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1129 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001130 return false;
1131 }
1132 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001133 if (UNLIKELY((value != 0) && (value < 0x80))) {
1134 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001135 return false;
1136 }
1137 break;
1138 }
1139 case 0x0e: {
1140 // Bit pattern 1110 has 2 additional bytes.
1141 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001142 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1143 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001144 return false;
1145 }
1146 uint8_t byte3 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001147 if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
1148 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
jeffhao10037c82012-01-23 15:06:23 -08001149 return false;
1150 }
1151 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001152 if (UNLIKELY(value < 0x800)) {
1153 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001154 return false;
1155 }
1156 break;
1157 }
1158 }
1159 }
1160
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001161 if (UNLIKELY(*(ptr_++) != '\0')) {
1162 ErrorStringPrintf("String longer than indicated size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001163 return false;
1164 }
1165
1166 return true;
1167}
1168
1169bool DexFileVerifier::CheckIntraDebugInfoItem() {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001170 DECODE_UNSIGNED_CHECKED_FROM(ptr_, dummy);
1171 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameters_size);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001172 if (UNLIKELY(parameters_size > 65536)) {
1173 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
jeffhao10037c82012-01-23 15:06:23 -08001174 return false;
1175 }
1176
1177 for (uint32_t j = 0; j < parameters_size; j++) {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001178 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameter_name);
jeffhao10037c82012-01-23 15:06:23 -08001179 if (parameter_name != 0) {
1180 parameter_name--;
1181 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
1182 return false;
1183 }
1184 }
1185 }
1186
1187 while (true) {
1188 uint8_t opcode = *(ptr_++);
1189 switch (opcode) {
1190 case DexFile::DBG_END_SEQUENCE: {
1191 return true;
1192 }
1193 case DexFile::DBG_ADVANCE_PC: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001194 DECODE_UNSIGNED_CHECKED_FROM(ptr_, advance_pc_dummy);
jeffhao10037c82012-01-23 15:06:23 -08001195 break;
1196 }
1197 case DexFile::DBG_ADVANCE_LINE: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001198 DECODE_SIGNED_CHECKED_FROM(ptr_, advance_line_dummy);
jeffhao10037c82012-01-23 15:06:23 -08001199 break;
1200 }
1201 case DexFile::DBG_START_LOCAL: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001202 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001203 if (UNLIKELY(reg_num >= 65536)) {
1204 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001205 return false;
1206 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001207 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001208 if (name_idx != 0) {
1209 name_idx--;
1210 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
1211 return false;
1212 }
1213 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001214 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -08001215 if (type_idx != 0) {
1216 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001217 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001218 return false;
1219 }
1220 }
1221 break;
1222 }
1223 case DexFile::DBG_END_LOCAL:
1224 case DexFile::DBG_RESTART_LOCAL: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001225 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001226 if (UNLIKELY(reg_num >= 65536)) {
1227 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001228 return false;
1229 }
1230 break;
1231 }
1232 case DexFile::DBG_START_LOCAL_EXTENDED: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001233 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001234 if (UNLIKELY(reg_num >= 65536)) {
1235 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001236 return false;
1237 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001238 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001239 if (name_idx != 0) {
1240 name_idx--;
1241 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
1242 return false;
1243 }
1244 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001245 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
jeffhao10037c82012-01-23 15:06:23 -08001246 if (type_idx != 0) {
1247 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001248 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001249 return false;
1250 }
1251 }
Andreas Gampebed6daf2016-09-02 18:12:00 -07001252 DECODE_UNSIGNED_CHECKED_FROM(ptr_, sig_idx);
jeffhao10037c82012-01-23 15:06:23 -08001253 if (sig_idx != 0) {
1254 sig_idx--;
1255 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
1256 return false;
1257 }
1258 }
1259 break;
1260 }
1261 case DexFile::DBG_SET_FILE: {
Andreas Gampebed6daf2016-09-02 18:12:00 -07001262 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
jeffhao10037c82012-01-23 15:06:23 -08001263 if (name_idx != 0) {
1264 name_idx--;
1265 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
1266 return false;
1267 }
1268 }
1269 break;
1270 }
1271 }
1272 }
1273}
1274
1275bool DexFileVerifier::CheckIntraAnnotationItem() {
Ian Rogers13735952014-10-08 12:43:28 -07001276 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "annotation visibility")) {
jeffhao10037c82012-01-23 15:06:23 -08001277 return false;
1278 }
1279
1280 // Check visibility
1281 switch (*(ptr_++)) {
1282 case DexFile::kDexVisibilityBuild:
1283 case DexFile::kDexVisibilityRuntime:
1284 case DexFile::kDexVisibilitySystem:
1285 break;
1286 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001287 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001288 return false;
1289 }
1290
1291 if (!CheckEncodedAnnotation()) {
1292 return false;
1293 }
1294
1295 return true;
1296}
1297
1298bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1299 const DexFile::AnnotationsDirectoryItem* item =
1300 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001301 if (!CheckListSize(item, 1, sizeof(DexFile::AnnotationsDirectoryItem), "annotations_directory")) {
jeffhao10037c82012-01-23 15:06:23 -08001302 return false;
1303 }
1304
1305 // Field annotations follow immediately after the annotations directory.
1306 const DexFile::FieldAnnotationsItem* field_item =
1307 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1308 uint32_t field_count = item->fields_size_;
1309 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
1310 return false;
1311 }
1312
1313 uint32_t last_idx = 0;
1314 for (uint32_t i = 0; i < field_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001315 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1316 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001317 return false;
1318 }
1319 last_idx = field_item->field_idx_;
1320 field_item++;
1321 }
1322
1323 // Method annotations follow immediately after field annotations.
1324 const DexFile::MethodAnnotationsItem* method_item =
1325 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1326 uint32_t method_count = item->methods_size_;
1327 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1328 return false;
1329 }
1330
1331 last_idx = 0;
1332 for (uint32_t i = 0; i < method_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001333 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1334 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1335 last_idx, method_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001336 return false;
1337 }
1338 last_idx = method_item->method_idx_;
1339 method_item++;
1340 }
1341
1342 // Parameter annotations follow immediately after method annotations.
1343 const DexFile::ParameterAnnotationsItem* parameter_item =
1344 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1345 uint32_t parameter_count = item->parameters_size_;
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001346 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001347 "parameter_annotations list")) {
jeffhao10037c82012-01-23 15:06:23 -08001348 return false;
1349 }
1350
1351 last_idx = 0;
1352 for (uint32_t i = 0; i < parameter_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001353 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1354 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1355 last_idx, parameter_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001356 return false;
1357 }
1358 last_idx = parameter_item->method_idx_;
1359 parameter_item++;
1360 }
1361
1362 // Return a pointer to the end of the annotations.
Ian Rogers13735952014-10-08 12:43:28 -07001363 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08001364 return true;
1365}
1366
Andreas Gampeb061cc12014-09-02 10:22:20 -07001367bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
1368 uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001369 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001370 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001371 switch (type) {
1372 case DexFile::kDexTypeClassDataItem:
1373 case DexFile::kDexTypeStringDataItem:
1374 case DexFile::kDexTypeDebugInfoItem:
1375 case DexFile::kDexTypeAnnotationItem:
1376 case DexFile::kDexTypeEncodedArrayItem:
1377 alignment_mask = sizeof(uint8_t) - 1;
1378 break;
1379 default:
1380 alignment_mask = sizeof(uint32_t) - 1;
1381 break;
1382 }
1383
1384 // Iterate through the items in the section.
Andreas Gampeb061cc12014-09-02 10:22:20 -07001385 for (uint32_t i = 0; i < section_count; i++) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001386 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001387
1388 // Check the padding between items.
1389 if (!CheckPadding(offset, aligned_offset)) {
1390 return false;
1391 }
1392
1393 // Check depending on the section type.
1394 switch (type) {
1395 case DexFile::kDexTypeStringIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001396 if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001397 return false;
1398 }
1399 ptr_ += sizeof(DexFile::StringId);
1400 break;
1401 }
1402 case DexFile::kDexTypeTypeIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001403 if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001404 return false;
1405 }
1406 ptr_ += sizeof(DexFile::TypeId);
1407 break;
1408 }
1409 case DexFile::kDexTypeProtoIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001410 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001411 return false;
1412 }
1413 ptr_ += sizeof(DexFile::ProtoId);
1414 break;
1415 }
1416 case DexFile::kDexTypeFieldIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001417 if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001418 return false;
1419 }
1420 ptr_ += sizeof(DexFile::FieldId);
1421 break;
1422 }
1423 case DexFile::kDexTypeMethodIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001424 if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001425 return false;
1426 }
1427 ptr_ += sizeof(DexFile::MethodId);
1428 break;
1429 }
1430 case DexFile::kDexTypeClassDefItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001431 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
jeffhao10037c82012-01-23 15:06:23 -08001432 return false;
1433 }
1434 ptr_ += sizeof(DexFile::ClassDef);
1435 break;
1436 }
1437 case DexFile::kDexTypeTypeList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001438 if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001439 return false;
1440 }
jeffhao10037c82012-01-23 15:06:23 -08001441 break;
1442 }
1443 case DexFile::kDexTypeAnnotationSetRefList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001444 if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001445 return false;
1446 }
jeffhao10037c82012-01-23 15:06:23 -08001447 break;
1448 }
1449 case DexFile::kDexTypeAnnotationSetItem: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001450 if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001451 return false;
1452 }
jeffhao10037c82012-01-23 15:06:23 -08001453 break;
1454 }
1455 case DexFile::kDexTypeClassDataItem: {
1456 if (!CheckIntraClassDataItem()) {
1457 return false;
1458 }
1459 break;
1460 }
1461 case DexFile::kDexTypeCodeItem: {
1462 if (!CheckIntraCodeItem()) {
1463 return false;
1464 }
1465 break;
1466 }
1467 case DexFile::kDexTypeStringDataItem: {
1468 if (!CheckIntraStringDataItem()) {
1469 return false;
1470 }
1471 break;
1472 }
1473 case DexFile::kDexTypeDebugInfoItem: {
1474 if (!CheckIntraDebugInfoItem()) {
1475 return false;
1476 }
1477 break;
1478 }
1479 case DexFile::kDexTypeAnnotationItem: {
1480 if (!CheckIntraAnnotationItem()) {
1481 return false;
1482 }
1483 break;
1484 }
1485 case DexFile::kDexTypeEncodedArrayItem: {
1486 if (!CheckEncodedArray()) {
1487 return false;
1488 }
1489 break;
1490 }
1491 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1492 if (!CheckIntraAnnotationsDirectoryItem()) {
1493 return false;
1494 }
1495 break;
1496 }
1497 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001498 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001499 return false;
1500 }
1501
1502 if (IsDataSectionType(type)) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001503 if (aligned_offset == 0u) {
1504 ErrorStringPrintf("Item %d offset is 0", i);
1505 return false;
1506 }
1507 DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
1508 offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
jeffhao10037c82012-01-23 15:06:23 -08001509 }
1510
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001511 aligned_offset = ptr_ - begin_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001512 if (UNLIKELY(aligned_offset > size_)) {
1513 ErrorStringPrintf("Item %d at ends out of bounds", i);
jeffhao10037c82012-01-23 15:06:23 -08001514 return false;
1515 }
1516
1517 offset = aligned_offset;
1518 }
1519
1520 return true;
1521}
1522
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001523bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001524 uint32_t expected_offset;
1525 uint32_t expected_size;
1526
1527 // Get the expected offset and size from the header.
1528 switch (type) {
1529 case DexFile::kDexTypeStringIdItem:
1530 expected_offset = header_->string_ids_off_;
1531 expected_size = header_->string_ids_size_;
1532 break;
1533 case DexFile::kDexTypeTypeIdItem:
1534 expected_offset = header_->type_ids_off_;
1535 expected_size = header_->type_ids_size_;
1536 break;
1537 case DexFile::kDexTypeProtoIdItem:
1538 expected_offset = header_->proto_ids_off_;
1539 expected_size = header_->proto_ids_size_;
1540 break;
1541 case DexFile::kDexTypeFieldIdItem:
1542 expected_offset = header_->field_ids_off_;
1543 expected_size = header_->field_ids_size_;
1544 break;
1545 case DexFile::kDexTypeMethodIdItem:
1546 expected_offset = header_->method_ids_off_;
1547 expected_size = header_->method_ids_size_;
1548 break;
1549 case DexFile::kDexTypeClassDefItem:
1550 expected_offset = header_->class_defs_off_;
1551 expected_size = header_->class_defs_size_;
1552 break;
1553 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001554 ErrorStringPrintf("Bad type for id section: %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001555 return false;
1556 }
1557
1558 // Check that the offset and size are what were expected from the header.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001559 if (UNLIKELY(offset != expected_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001560 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
jeffhao10037c82012-01-23 15:06:23 -08001561 return false;
1562 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001563 if (UNLIKELY(count != expected_size)) {
1564 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
jeffhao10037c82012-01-23 15:06:23 -08001565 return false;
1566 }
1567
1568 return CheckIntraSectionIterate(offset, count, type);
1569}
1570
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001571bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
1572 size_t data_start = header_->data_off_;
1573 size_t data_end = data_start + header_->data_size_;
jeffhao10037c82012-01-23 15:06:23 -08001574
1575 // Sanity check the offset of the section.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001576 if (UNLIKELY((offset < data_start) || (offset > data_end))) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001577 ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
jeffhao10037c82012-01-23 15:06:23 -08001578 return false;
1579 }
1580
1581 if (!CheckIntraSectionIterate(offset, count, type)) {
1582 return false;
1583 }
1584
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001585 size_t next_offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001586 if (next_offset > data_end) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001587 ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset);
jeffhao10037c82012-01-23 15:06:23 -08001588 return false;
1589 }
1590
1591 return true;
1592}
1593
1594bool DexFileVerifier::CheckIntraSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08001595 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001596 const DexFile::MapItem* item = map->list_;
1597
1598 uint32_t count = map->size_;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001599 size_t offset = 0;
Ian Rogers30fab402012-01-23 15:43:46 -08001600 ptr_ = begin_;
jeffhao10037c82012-01-23 15:06:23 -08001601
1602 // Check the items listed in the map.
1603 while (count--) {
1604 uint32_t section_offset = item->offset_;
1605 uint32_t section_count = item->size_;
1606 uint16_t type = item->type_;
1607
1608 // Check for padding and overlap between items.
1609 if (!CheckPadding(offset, section_offset)) {
1610 return false;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001611 } else if (UNLIKELY(offset > section_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001612 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001613 return false;
1614 }
1615
1616 // Check each item based on its type.
1617 switch (type) {
1618 case DexFile::kDexTypeHeaderItem:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001619 if (UNLIKELY(section_count != 1)) {
1620 ErrorStringPrintf("Multiple header items");
jeffhao10037c82012-01-23 15:06:23 -08001621 return false;
1622 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001623 if (UNLIKELY(section_offset != 0)) {
1624 ErrorStringPrintf("Header at %x, not at start of file", section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001625 return false;
1626 }
Ian Rogers30fab402012-01-23 15:43:46 -08001627 ptr_ = begin_ + header_->header_size_;
jeffhao10037c82012-01-23 15:06:23 -08001628 offset = header_->header_size_;
1629 break;
1630 case DexFile::kDexTypeStringIdItem:
1631 case DexFile::kDexTypeTypeIdItem:
1632 case DexFile::kDexTypeProtoIdItem:
1633 case DexFile::kDexTypeFieldIdItem:
1634 case DexFile::kDexTypeMethodIdItem:
1635 case DexFile::kDexTypeClassDefItem:
1636 if (!CheckIntraIdSection(section_offset, section_count, type)) {
1637 return false;
1638 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001639 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001640 break;
1641 case DexFile::kDexTypeMapList:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001642 if (UNLIKELY(section_count != 1)) {
1643 ErrorStringPrintf("Multiple map list items");
jeffhao10037c82012-01-23 15:06:23 -08001644 return false;
1645 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001646 if (UNLIKELY(section_offset != header_->map_off_)) {
1647 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1648 section_offset, header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001649 return false;
1650 }
1651 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1652 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1653 break;
1654 case DexFile::kDexTypeTypeList:
1655 case DexFile::kDexTypeAnnotationSetRefList:
1656 case DexFile::kDexTypeAnnotationSetItem:
1657 case DexFile::kDexTypeClassDataItem:
1658 case DexFile::kDexTypeCodeItem:
1659 case DexFile::kDexTypeStringDataItem:
1660 case DexFile::kDexTypeDebugInfoItem:
1661 case DexFile::kDexTypeAnnotationItem:
1662 case DexFile::kDexTypeEncodedArrayItem:
1663 case DexFile::kDexTypeAnnotationsDirectoryItem:
1664 if (!CheckIntraDataSection(section_offset, section_count, type)) {
1665 return false;
1666 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001667 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001668 break;
1669 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001670 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001671 return false;
1672 }
1673
1674 item++;
1675 }
1676
1677 return true;
1678}
1679
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001680bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001681 DCHECK_NE(offset, 0u);
1682 auto it = offset_to_type_map_.Find(offset);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001683 if (UNLIKELY(it == offset_to_type_map_.end())) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001684 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
jeffhao10037c82012-01-23 15:06:23 -08001685 return false;
1686 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001687 if (UNLIKELY(it->second != type)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001688 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001689 offset, type, it->second);
jeffhao10037c82012-01-23 15:06:23 -08001690 return false;
1691 }
1692 return true;
1693}
1694
Andreas Gampea5b09a62016-11-17 15:21:22 -08001695dex::TypeIndex DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001696 ClassDataItemIterator it(*dex_file_, ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001697 *success = true;
jeffhao10037c82012-01-23 15:06:23 -08001698
1699 if (it.HasNextStaticField() || it.HasNextInstanceField()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001700 LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001701 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001702 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001703 }
1704
1705 if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001706 LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001707 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001708 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001709 }
1710
Andreas Gampea5b09a62016-11-17 15:21:22 -08001711 return dex::TypeIndex(DexFile::kDexNoIndex16);
jeffhao10037c82012-01-23 15:06:23 -08001712}
1713
Andreas Gampea5b09a62016-11-17 15:21:22 -08001714dex::TypeIndex DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr,
1715 bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001716 const DexFile::AnnotationsDirectoryItem* item =
1717 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001718 *success = true;
1719
jeffhao10037c82012-01-23 15:06:23 -08001720 if (item->fields_size_ != 0) {
1721 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001722 LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001723 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001724 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001725 }
1726
1727 if (item->methods_size_ != 0) {
1728 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001729 LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001730 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001731 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001732 }
1733
1734 if (item->parameters_size_ != 0) {
1735 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001736 LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampea5b09a62016-11-17 15:21:22 -08001737 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
Andreas Gampee09269c2014-06-06 18:45:35 -07001738 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001739 }
1740
Andreas Gampea5b09a62016-11-17 15:21:22 -08001741 return dex::TypeIndex(DexFile::kDexNoIndex16);
jeffhao10037c82012-01-23 15:06:23 -08001742}
1743
1744bool DexFileVerifier::CheckInterStringIdItem() {
1745 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
1746
1747 // Check the map to make sure it has the right offset->type.
1748 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
1749 return false;
1750 }
1751
1752 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001753 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001754 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
1755 const char* prev_str = dex_file_->GetStringData(*prev_item);
1756 const char* str = dex_file_->GetStringData(*item);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001757 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
1758 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
jeffhao10037c82012-01-23 15:06:23 -08001759 return false;
1760 }
1761 }
1762
1763 ptr_ += sizeof(DexFile::StringId);
1764 return true;
1765}
1766
1767bool DexFileVerifier::CheckInterTypeIdItem() {
1768 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001769
1770 LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
jeffhao10037c82012-01-23 15:06:23 -08001771
1772 // Check that the descriptor is a valid type.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001773 if (UNLIKELY(!IsValidDescriptor(descriptor))) {
1774 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001775 return false;
1776 }
1777
1778 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001779 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001780 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001781 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
1782 ErrorStringPrintf("Out-of-order type_ids: %x then %x",
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001783 prev_item->descriptor_idx_.index_,
1784 item->descriptor_idx_.index_);
jeffhao10037c82012-01-23 15:06:23 -08001785 return false;
1786 }
1787 }
1788
1789 ptr_ += sizeof(DexFile::TypeId);
1790 return true;
1791}
1792
1793bool DexFileVerifier::CheckInterProtoIdItem() {
1794 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001795
1796 LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
1797
jeffhao10037c82012-01-23 15:06:23 -08001798 if (item->parameters_off_ != 0 &&
1799 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
1800 return false;
1801 }
1802
David Sehr28e74ed2016-11-21 12:52:12 -08001803 // Check that return type is representable as a uint16_t;
1804 if (UNLIKELY(!IsValidOrNoTypeId(item->return_type_idx_.index_, item->pad_))) {
1805 ErrorStringPrintf("proto with return type idx outside uint16_t range '%x:%x'",
1806 item->pad_, item->return_type_idx_.index_);
1807 return false;
1808 }
jeffhao10037c82012-01-23 15:06:23 -08001809 // Check the return type and advance the shorty.
Andreas Gampee09269c2014-06-06 18:45:35 -07001810 LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
1811 if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
jeffhao10037c82012-01-23 15:06:23 -08001812 return false;
1813 }
1814 shorty++;
1815
1816 DexFileParameterIterator it(*dex_file_, *item);
1817 while (it.HasNext() && *shorty != '\0') {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001818 if (!CheckIndex(it.GetTypeIdx().index_,
1819 dex_file_->NumTypeIds(),
Andreas Gampebb836e12014-06-13 15:31:40 -07001820 "inter_proto_id_item shorty type_idx")) {
1821 return false;
1822 }
jeffhao10037c82012-01-23 15:06:23 -08001823 const char* descriptor = it.GetDescriptor();
1824 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
1825 return false;
1826 }
1827 it.Next();
1828 shorty++;
1829 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001830 if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
1831 ErrorStringPrintf("Mismatched length for parameters and shorty");
jeffhao10037c82012-01-23 15:06:23 -08001832 return false;
1833 }
1834
1835 // Check ordering between items. This relies on type_ids being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001836 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001837 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001838 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
1839 ErrorStringPrintf("Out-of-order proto_id return types");
jeffhao10037c82012-01-23 15:06:23 -08001840 return false;
1841 } else if (prev->return_type_idx_ == item->return_type_idx_) {
1842 DexFileParameterIterator curr_it(*dex_file_, *item);
1843 DexFileParameterIterator prev_it(*dex_file_, *prev);
1844
1845 while (curr_it.HasNext() && prev_it.HasNext()) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001846 dex::TypeIndex prev_idx = prev_it.GetTypeIdx();
1847 dex::TypeIndex curr_idx = curr_it.GetTypeIdx();
1848 DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
1849 DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
jeffhao10037c82012-01-23 15:06:23 -08001850
1851 if (prev_idx < curr_idx) {
1852 break;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001853 } else if (UNLIKELY(prev_idx > curr_idx)) {
1854 ErrorStringPrintf("Out-of-order proto_id arguments");
jeffhao10037c82012-01-23 15:06:23 -08001855 return false;
1856 }
1857
1858 prev_it.Next();
1859 curr_it.Next();
1860 }
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001861 if (!curr_it.HasNext()) {
1862 // Either a duplicate ProtoId or a ProtoId with a shorter argument list follows
1863 // a ProtoId with a longer one. Both cases are forbidden by the specification.
1864 ErrorStringPrintf("Out-of-order proto_id arguments");
1865 return false;
1866 }
jeffhao10037c82012-01-23 15:06:23 -08001867 }
1868 }
1869
1870 ptr_ += sizeof(DexFile::ProtoId);
1871 return true;
1872}
1873
1874bool DexFileVerifier::CheckInterFieldIdItem() {
1875 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
1876
1877 // Check that the class descriptor is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001878 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
1879 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1880 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001881 return false;
1882 }
1883
1884 // Check that the type descriptor is a valid field name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001885 LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
1886 if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
1887 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001888 return false;
1889 }
1890
1891 // Check that the name is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001892 LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001893 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1894 ErrorStringPrintf("Invalid field name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001895 return false;
1896 }
1897
1898 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001899 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001900 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001901 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1902 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001903 return false;
1904 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001905 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1906 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001907 return false;
1908 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001909 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
1910 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001911 return false;
1912 }
1913 }
1914 }
1915 }
1916
1917 ptr_ += sizeof(DexFile::FieldId);
1918 return true;
1919}
1920
1921bool DexFileVerifier::CheckInterMethodIdItem() {
1922 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
1923
1924 // Check that the class descriptor is a valid reference name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001925 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
1926 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
1927 class_descriptor[0] != '['))) {
1928 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001929 return false;
1930 }
1931
1932 // Check that the name is valid.
Andreas Gampedf10b322014-06-11 21:46:05 -07001933 LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001934 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1935 ErrorStringPrintf("Invalid method name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001936 return false;
1937 }
1938
Andreas Gampedf10b322014-06-11 21:46:05 -07001939 // Check that the proto id is valid.
1940 if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
1941 "inter_method_id_item proto_idx"))) {
1942 return false;
1943 }
1944
jeffhao10037c82012-01-23 15:06:23 -08001945 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001946 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001947 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001948 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1949 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001950 return false;
1951 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001952 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1953 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001954 return false;
1955 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001956 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
1957 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001958 return false;
1959 }
1960 }
1961 }
1962 }
1963
1964 ptr_ += sizeof(DexFile::MethodId);
1965 return true;
1966}
1967
1968bool DexFileVerifier::CheckInterClassDefItem() {
1969 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001970
David Sehr28e74ed2016-11-21 12:52:12 -08001971 // Check that class_idx_ is representable as a uint16_t;
1972 if (UNLIKELY(!IsValidTypeId(item->class_idx_.index_, item->pad1_))) {
1973 ErrorStringPrintf("class with type idx outside uint16_t range '%x:%x'", item->pad1_,
1974 item->class_idx_.index_);
1975 return false;
1976 }
1977 // Check that superclass_idx_ is representable as a uint16_t;
1978 if (UNLIKELY(!IsValidOrNoTypeId(item->superclass_idx_.index_, item->pad2_))) {
1979 ErrorStringPrintf("class with superclass type idx outside uint16_t range '%x:%x'", item->pad2_,
1980 item->superclass_idx_.index_);
1981 return false;
1982 }
Andreas Gampe0ba238d2014-07-29 01:22:07 -07001983 // Check for duplicate class def.
1984 if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001985 ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_.index_);
Andreas Gampe0ba238d2014-07-29 01:22:07 -07001986 return false;
1987 }
1988 defined_classes_.insert(item->class_idx_);
1989
Andreas Gampee09269c2014-06-06 18:45:35 -07001990 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
1991 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1992 ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001993 return false;
1994 }
1995
Andreas Gampeacc2bb62014-07-17 19:26:50 -07001996 // Only allow non-runtime modifiers.
1997 if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
1998 ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
1999 return false;
2000 }
2001
jeffhao10037c82012-01-23 15:06:23 -08002002 if (item->interfaces_off_ != 0 &&
2003 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
2004 return false;
2005 }
2006 if (item->annotations_off_ != 0 &&
2007 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
2008 return false;
2009 }
2010 if (item->class_data_off_ != 0 &&
2011 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
2012 return false;
2013 }
2014 if (item->static_values_off_ != 0 &&
2015 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
2016 return false;
2017 }
2018
Andreas Gampea5b09a62016-11-17 15:21:22 -08002019 if (item->superclass_idx_.IsValid()) {
Roland Levillain621b5ea2016-05-18 11:41:33 +01002020 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2021 // Check that a class does not inherit from itself directly (by having
2022 // the same type idx as its super class).
2023 if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002024 ErrorStringPrintf("Class with same type idx as its superclass: '%d'",
2025 item->class_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002026 return false;
2027 }
2028
2029 // Check that a class is defined after its super class (if the
2030 // latter is defined in the same Dex file).
2031 const DexFile::ClassDef* superclass_def = dex_file_->FindClassDef(item->superclass_idx_);
2032 if (superclass_def != nullptr) {
2033 // The superclass is defined in this Dex file.
2034 if (superclass_def > item) {
2035 // ClassDef item for super class appearing after the class' ClassDef item.
2036 ErrorStringPrintf("Invalid class definition ordering:"
2037 " class with type idx: '%d' defined before"
2038 " superclass with type idx: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002039 item->class_idx_.index_,
2040 item->superclass_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002041 return false;
2042 }
2043 }
2044 }
2045
Andreas Gampee09269c2014-06-06 18:45:35 -07002046 LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
2047 "inter_class_def_item superclass_idx")
2048 if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
2049 ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08002050 return false;
2051 }
2052 }
2053
Roland Levillain621b5ea2016-05-18 11:41:33 +01002054 // Check interfaces.
jeffhao10037c82012-01-23 15:06:23 -08002055 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002056 if (interfaces != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08002057 uint32_t size = interfaces->Size();
jeffhao10037c82012-01-23 15:06:23 -08002058 for (uint32_t i = 0; i < size; i++) {
Roland Levillain621b5ea2016-05-18 11:41:33 +01002059 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2060 // Check that a class does not implement itself directly (by having the
2061 // same type idx as one of its immediate implemented interfaces).
2062 if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) {
2063 ErrorStringPrintf("Class with same type idx as implemented interface: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002064 item->class_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002065 return false;
2066 }
2067
2068 // Check that a class is defined after the interfaces it implements
2069 // (if they are defined in the same Dex file).
2070 const DexFile::ClassDef* interface_def =
2071 dex_file_->FindClassDef(interfaces->GetTypeItem(i).type_idx_);
2072 if (interface_def != nullptr) {
2073 // The interface is defined in this Dex file.
2074 if (interface_def > item) {
2075 // ClassDef item for interface appearing after the class' ClassDef item.
2076 ErrorStringPrintf("Invalid class definition ordering:"
2077 " class with type idx: '%d' defined before"
2078 " implemented interface with type idx: '%d'",
Andreas Gampea5b09a62016-11-17 15:21:22 -08002079 item->class_idx_.index_,
2080 interfaces->GetTypeItem(i).type_idx_.index_);
Roland Levillain621b5ea2016-05-18 11:41:33 +01002081 return false;
2082 }
2083 }
2084 }
2085
2086 // Ensure that the interface refers to a class (not an array nor a primitive type).
Andreas Gampee09269c2014-06-06 18:45:35 -07002087 LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
2088 "inter_class_def_item interface type_idx")
2089 if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
2090 ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08002091 return false;
2092 }
2093 }
2094
2095 /*
2096 * Ensure that there are no duplicates. This is an O(N^2) test, but in
2097 * practice the number of interfaces implemented by any given class is low.
2098 */
2099 for (uint32_t i = 1; i < size; i++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002100 dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_;
jeffhao10037c82012-01-23 15:06:23 -08002101 for (uint32_t j =0; j < i; j++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -08002102 dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002103 if (UNLIKELY(idx1 == idx2)) {
2104 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
jeffhao10037c82012-01-23 15:06:23 -08002105 return false;
2106 }
2107 }
2108 }
2109 }
2110
2111 // Check that references in class_data_item are to the right class.
2112 if (item->class_data_off_ != 0) {
Ian Rogers13735952014-10-08 12:43:28 -07002113 const uint8_t* data = begin_ + item->class_data_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002114 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002115 dex::TypeIndex data_definer = FindFirstClassDataDefiner(data, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002116 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002117 return false;
2118 }
Andreas Gampea5b09a62016-11-17 15:21:22 -08002119 if (UNLIKELY((data_definer != item->class_idx_) &&
2120 (data_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002121 ErrorStringPrintf("Invalid class_data_item");
jeffhao10037c82012-01-23 15:06:23 -08002122 return false;
2123 }
2124 }
2125
2126 // Check that references in annotations_directory_item are to right class.
2127 if (item->annotations_off_ != 0) {
Andreas Gampeb512c0e2016-02-19 19:45:34 -08002128 // annotations_off_ is supposed to be aligned by 4.
2129 if (!IsAlignedParam(item->annotations_off_, 4)) {
2130 ErrorStringPrintf("Invalid annotations_off_, not aligned by 4");
2131 return false;
2132 }
Ian Rogers13735952014-10-08 12:43:28 -07002133 const uint8_t* data = begin_ + item->annotations_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002134 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002135 dex::TypeIndex annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002136 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002137 return false;
2138 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002139 if (UNLIKELY((annotations_definer != item->class_idx_) &&
Andreas Gampea5b09a62016-11-17 15:21:22 -08002140 (annotations_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002141 ErrorStringPrintf("Invalid annotations_directory_item");
jeffhao10037c82012-01-23 15:06:23 -08002142 return false;
2143 }
2144 }
2145
2146 ptr_ += sizeof(DexFile::ClassDef);
2147 return true;
2148}
2149
2150bool DexFileVerifier::CheckInterAnnotationSetRefList() {
2151 const DexFile::AnnotationSetRefList* list =
2152 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
2153 const DexFile::AnnotationSetRefItem* item = list->list_;
2154 uint32_t count = list->size_;
2155
2156 while (count--) {
2157 if (item->annotations_off_ != 0 &&
2158 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2159 return false;
2160 }
2161 item++;
2162 }
2163
Ian Rogers13735952014-10-08 12:43:28 -07002164 ptr_ = reinterpret_cast<const uint8_t*>(item);
jeffhao10037c82012-01-23 15:06:23 -08002165 return true;
2166}
2167
2168bool DexFileVerifier::CheckInterAnnotationSetItem() {
2169 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
2170 const uint32_t* offsets = set->entries_;
2171 uint32_t count = set->size_;
2172 uint32_t last_idx = 0;
2173
2174 for (uint32_t i = 0; i < count; i++) {
2175 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
2176 return false;
2177 }
2178
2179 // Get the annotation from the offset and the type index for the annotation.
2180 const DexFile::AnnotationItem* annotation =
Ian Rogers30fab402012-01-23 15:43:46 -08002181 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
jeffhao10037c82012-01-23 15:06:23 -08002182 const uint8_t* data = annotation->annotation_;
Andreas Gampebed6daf2016-09-02 18:12:00 -07002183 DECODE_UNSIGNED_CHECKED_FROM(data, idx);
jeffhao10037c82012-01-23 15:06:23 -08002184
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002185 if (UNLIKELY(last_idx >= idx && i != 0)) {
2186 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -08002187 return false;
2188 }
2189
2190 last_idx = idx;
2191 offsets++;
2192 }
2193
Ian Rogers13735952014-10-08 12:43:28 -07002194 ptr_ = reinterpret_cast<const uint8_t*>(offsets);
jeffhao10037c82012-01-23 15:06:23 -08002195 return true;
2196}
2197
2198bool DexFileVerifier::CheckInterClassDataItem() {
2199 ClassDataItemIterator it(*dex_file_, ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002200 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002201 dex::TypeIndex defining_class = FindFirstClassDataDefiner(ptr_, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002202 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002203 return false;
2204 }
jeffhao10037c82012-01-23 15:06:23 -08002205
2206 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002207 LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002208 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002209 ErrorStringPrintf("Mismatched defining class for class_data_item field");
jeffhao10037c82012-01-23 15:06:23 -08002210 return false;
2211 }
2212 }
2213 for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) {
2214 uint32_t code_off = it.GetMethodCodeItemOffset();
2215 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
2216 return false;
2217 }
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002218 LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002219 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002220 ErrorStringPrintf("Mismatched defining class for class_data_item method");
jeffhao10037c82012-01-23 15:06:23 -08002221 return false;
2222 }
2223 }
2224
2225 ptr_ = it.EndDataPointer();
2226 return true;
2227}
2228
2229bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
2230 const DexFile::AnnotationsDirectoryItem* item =
2231 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002232 bool success;
Andreas Gampea5b09a62016-11-17 15:21:22 -08002233 dex::TypeIndex defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002234 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002235 return false;
2236 }
jeffhao10037c82012-01-23 15:06:23 -08002237
2238 if (item->class_annotations_off_ != 0 &&
2239 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2240 return false;
2241 }
2242
2243 // Field annotations follow immediately after the annotations directory.
2244 const DexFile::FieldAnnotationsItem* field_item =
2245 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
2246 uint32_t field_count = item->fields_size_;
2247 for (uint32_t i = 0; i < field_count; i++) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002248 LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
2249 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002250 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002251 ErrorStringPrintf("Mismatched defining class for field_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002252 return false;
2253 }
2254 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2255 return false;
2256 }
2257 field_item++;
2258 }
2259
2260 // Method annotations follow immediately after field annotations.
2261 const DexFile::MethodAnnotationsItem* method_item =
2262 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
2263 uint32_t method_count = item->methods_size_;
2264 for (uint32_t i = 0; i < method_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002265 LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002266 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002267 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002268 ErrorStringPrintf("Mismatched defining class for method_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002269 return false;
2270 }
2271 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2272 return false;
2273 }
2274 method_item++;
2275 }
2276
2277 // Parameter annotations follow immediately after method annotations.
2278 const DexFile::ParameterAnnotationsItem* parameter_item =
2279 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
2280 uint32_t parameter_count = item->parameters_size_;
2281 for (uint32_t i = 0; i < parameter_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002282 LOAD_METHOD(parameter_method, parameter_item->method_idx_,
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002283 "inter_annotations_directory_item parameter method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002284 if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002285 ErrorStringPrintf("Mismatched defining class for parameter_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002286 return false;
2287 }
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07002288 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
2289 DexFile::kDexTypeAnnotationSetRefList)) {
jeffhao10037c82012-01-23 15:06:23 -08002290 return false;
2291 }
2292 parameter_item++;
2293 }
2294
Ian Rogers13735952014-10-08 12:43:28 -07002295 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08002296 return true;
2297}
2298
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002299bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08002300 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002301 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08002302 switch (type) {
2303 case DexFile::kDexTypeClassDataItem:
2304 alignment_mask = sizeof(uint8_t) - 1;
2305 break;
2306 default:
2307 alignment_mask = sizeof(uint32_t) - 1;
2308 break;
2309 }
2310
2311 // Iterate through the items in the section.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002312 previous_item_ = nullptr;
jeffhao10037c82012-01-23 15:06:23 -08002313 for (uint32_t i = 0; i < count; i++) {
2314 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
Ian Rogers30fab402012-01-23 15:43:46 -08002315 ptr_ = begin_ + new_offset;
Ian Rogers13735952014-10-08 12:43:28 -07002316 const uint8_t* prev_ptr = ptr_;
jeffhao10037c82012-01-23 15:06:23 -08002317
2318 // Check depending on the section type.
2319 switch (type) {
2320 case DexFile::kDexTypeStringIdItem: {
2321 if (!CheckInterStringIdItem()) {
2322 return false;
2323 }
2324 break;
2325 }
2326 case DexFile::kDexTypeTypeIdItem: {
2327 if (!CheckInterTypeIdItem()) {
2328 return false;
2329 }
2330 break;
2331 }
2332 case DexFile::kDexTypeProtoIdItem: {
2333 if (!CheckInterProtoIdItem()) {
2334 return false;
2335 }
2336 break;
2337 }
2338 case DexFile::kDexTypeFieldIdItem: {
2339 if (!CheckInterFieldIdItem()) {
2340 return false;
2341 }
2342 break;
2343 }
2344 case DexFile::kDexTypeMethodIdItem: {
2345 if (!CheckInterMethodIdItem()) {
2346 return false;
2347 }
2348 break;
2349 }
2350 case DexFile::kDexTypeClassDefItem: {
David Sehr28e74ed2016-11-21 12:52:12 -08002351 // There shouldn't be more class definitions than type ids allow.
2352 // This check should be redundant, since there are checks that the
2353 // class_idx_ is within range and that there is only one definition
2354 // for a given type id.
2355 if (i > kTypeIdLimit) {
2356 ErrorStringPrintf("Too many class definition items");
2357 return false;
2358 }
jeffhao10037c82012-01-23 15:06:23 -08002359 if (!CheckInterClassDefItem()) {
2360 return false;
2361 }
2362 break;
2363 }
2364 case DexFile::kDexTypeAnnotationSetRefList: {
2365 if (!CheckInterAnnotationSetRefList()) {
2366 return false;
2367 }
2368 break;
2369 }
2370 case DexFile::kDexTypeAnnotationSetItem: {
2371 if (!CheckInterAnnotationSetItem()) {
2372 return false;
2373 }
2374 break;
2375 }
2376 case DexFile::kDexTypeClassDataItem: {
David Sehr28e74ed2016-11-21 12:52:12 -08002377 // There shouldn't be more class data than type ids allow.
2378 // This check should be redundant, since there are checks that the
2379 // class_idx_ is within range and that there is only one definition
2380 // for a given type id.
2381 if (i > kTypeIdLimit) {
2382 ErrorStringPrintf("Too many class data items");
2383 return false;
2384 }
jeffhao10037c82012-01-23 15:06:23 -08002385 if (!CheckInterClassDataItem()) {
2386 return false;
2387 }
2388 break;
2389 }
2390 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2391 if (!CheckInterAnnotationsDirectoryItem()) {
2392 return false;
2393 }
2394 break;
2395 }
2396 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002397 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002398 return false;
2399 }
2400
2401 previous_item_ = prev_ptr;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002402 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08002403 }
2404
2405 return true;
2406}
2407
2408bool DexFileVerifier::CheckInterSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08002409 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08002410 const DexFile::MapItem* item = map->list_;
2411 uint32_t count = map->size_;
2412
2413 // Cross check the items listed in the map.
2414 while (count--) {
2415 uint32_t section_offset = item->offset_;
2416 uint32_t section_count = item->size_;
2417 uint16_t type = item->type_;
2418
2419 switch (type) {
2420 case DexFile::kDexTypeHeaderItem:
2421 case DexFile::kDexTypeMapList:
2422 case DexFile::kDexTypeTypeList:
2423 case DexFile::kDexTypeCodeItem:
2424 case DexFile::kDexTypeStringDataItem:
2425 case DexFile::kDexTypeDebugInfoItem:
2426 case DexFile::kDexTypeAnnotationItem:
2427 case DexFile::kDexTypeEncodedArrayItem:
2428 break;
2429 case DexFile::kDexTypeStringIdItem:
2430 case DexFile::kDexTypeTypeIdItem:
2431 case DexFile::kDexTypeProtoIdItem:
2432 case DexFile::kDexTypeFieldIdItem:
2433 case DexFile::kDexTypeMethodIdItem:
2434 case DexFile::kDexTypeClassDefItem:
2435 case DexFile::kDexTypeAnnotationSetRefList:
2436 case DexFile::kDexTypeAnnotationSetItem:
2437 case DexFile::kDexTypeClassDataItem:
2438 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2439 if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2440 return false;
2441 }
2442 break;
2443 }
2444 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002445 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002446 return false;
2447 }
2448
2449 item++;
2450 }
2451
2452 return true;
2453}
2454
2455bool DexFileVerifier::Verify() {
2456 // Check the header.
2457 if (!CheckHeader()) {
2458 return false;
2459 }
2460
2461 // Check the map section.
2462 if (!CheckMap()) {
2463 return false;
2464 }
2465
2466 // Check structure within remaining sections.
2467 if (!CheckIntraSection()) {
2468 return false;
2469 }
2470
2471 // Check references from one section to another.
2472 if (!CheckInterSection()) {
2473 return false;
2474 }
2475
2476 return true;
2477}
2478
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002479void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2480 va_list ap;
2481 va_start(ap, fmt);
2482 DCHECK(failure_reason_.empty()) << failure_reason_;
2483 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2484 StringAppendV(&failure_reason_, fmt, ap);
2485 va_end(ap);
2486}
2487
Andreas Gampee6215c02015-08-31 18:54:38 -07002488// Fields and methods may have only one of public/protected/private.
2489static bool CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags) {
2490 size_t count = (((flags & kAccPublic) == 0) ? 0 : 1) +
2491 (((flags & kAccProtected) == 0) ? 0 : 1) +
2492 (((flags & kAccPrivate) == 0) ? 0 : 1);
2493 return count <= 1;
2494}
2495
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002496// Helper functions to retrieve names from the dex file. We do not want to rely on DexFile
2497// functionality, as we're still verifying the dex file. begin and header correspond to the
2498// underscored variants in the DexFileVerifier.
2499
2500static std::string GetStringOrError(const uint8_t* const begin,
2501 const DexFile::Header* const header,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08002502 dex::StringIndex string_idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002503 // The `string_idx` is not guaranteed to be valid yet.
Andreas Gampe8a0128a2016-11-28 07:38:35 -08002504 if (header->string_ids_size_ <= string_idx.index_) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002505 return "(error)";
2506 }
2507
2508 const DexFile::StringId* string_id =
Andreas Gampe8a0128a2016-11-28 07:38:35 -08002509 reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_)
2510 + string_idx.index_;
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002511
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_) +
Andreas Gampe8a0128a2016-11-28 07:38:35 -08002667 method_index)->name_idx_.index_;
Andreas Gampee6215c02015-08-31 18:54:38 -07002668 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