1 /*
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 */
16
17 #include "dex_file_verifier.h"
18
19 #include <inttypes.h>
20
21 #include <limits>
22 #include <memory>
23
24 #include "android-base/stringprintf.h"
25
26 #include "base/leb128.h"
27 #include "code_item_accessors-inl.h"
28 #include "descriptors_names.h"
29 #include "dex_file-inl.h"
30 #include "modifiers.h"
31 #include "utf-inl.h"
32
33 namespace art {
34
35 using android::base::StringAppendV;
36 using android::base::StringPrintf;
37
38 static constexpr uint32_t kTypeIdLimit = std::numeric_limits<uint16_t>::max();
39
IsValidOrNoTypeId(uint16_t low,uint16_t high)40 static bool IsValidOrNoTypeId(uint16_t low, uint16_t high) {
41 return (high == 0) || ((high == 0xffffU) && (low == 0xffffU));
42 }
43
IsValidTypeId(uint16_t low ATTRIBUTE_UNUSED,uint16_t high)44 static bool IsValidTypeId(uint16_t low ATTRIBUTE_UNUSED, uint16_t high) {
45 return (high == 0);
46 }
47
MapTypeToBitMask(DexFile::MapItemType map_item_type)48 static uint32_t MapTypeToBitMask(DexFile::MapItemType map_item_type) {
49 switch (map_item_type) {
50 case DexFile::kDexTypeHeaderItem: return 1 << 0;
51 case DexFile::kDexTypeStringIdItem: return 1 << 1;
52 case DexFile::kDexTypeTypeIdItem: return 1 << 2;
53 case DexFile::kDexTypeProtoIdItem: return 1 << 3;
54 case DexFile::kDexTypeFieldIdItem: return 1 << 4;
55 case DexFile::kDexTypeMethodIdItem: return 1 << 5;
56 case DexFile::kDexTypeClassDefItem: return 1 << 6;
57 case DexFile::kDexTypeCallSiteIdItem: return 1 << 7;
58 case DexFile::kDexTypeMethodHandleItem: return 1 << 8;
59 case DexFile::kDexTypeMapList: return 1 << 9;
60 case DexFile::kDexTypeTypeList: return 1 << 10;
61 case DexFile::kDexTypeAnnotationSetRefList: return 1 << 11;
62 case DexFile::kDexTypeAnnotationSetItem: return 1 << 12;
63 case DexFile::kDexTypeClassDataItem: return 1 << 13;
64 case DexFile::kDexTypeCodeItem: return 1 << 14;
65 case DexFile::kDexTypeStringDataItem: return 1 << 15;
66 case DexFile::kDexTypeDebugInfoItem: return 1 << 16;
67 case DexFile::kDexTypeAnnotationItem: return 1 << 17;
68 case DexFile::kDexTypeEncodedArrayItem: return 1 << 18;
69 case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 19;
70 }
71 return 0;
72 }
73
IsDataSectionType(DexFile::MapItemType map_item_type)74 static bool IsDataSectionType(DexFile::MapItemType map_item_type) {
75 switch (map_item_type) {
76 case DexFile::kDexTypeHeaderItem:
77 case DexFile::kDexTypeStringIdItem:
78 case DexFile::kDexTypeTypeIdItem:
79 case DexFile::kDexTypeProtoIdItem:
80 case DexFile::kDexTypeFieldIdItem:
81 case DexFile::kDexTypeMethodIdItem:
82 case DexFile::kDexTypeClassDefItem:
83 return false;
84 case DexFile::kDexTypeCallSiteIdItem:
85 case DexFile::kDexTypeMethodHandleItem:
86 case DexFile::kDexTypeMapList:
87 case DexFile::kDexTypeTypeList:
88 case DexFile::kDexTypeAnnotationSetRefList:
89 case DexFile::kDexTypeAnnotationSetItem:
90 case DexFile::kDexTypeClassDataItem:
91 case DexFile::kDexTypeCodeItem:
92 case DexFile::kDexTypeStringDataItem:
93 case DexFile::kDexTypeDebugInfoItem:
94 case DexFile::kDexTypeAnnotationItem:
95 case DexFile::kDexTypeEncodedArrayItem:
96 case DexFile::kDexTypeAnnotationsDirectoryItem:
97 return true;
98 }
99 return true;
100 }
101
CheckLoadStringByIdx(dex::StringIndex idx,const char * error_string)102 const char* DexFileVerifier::CheckLoadStringByIdx(dex::StringIndex idx, const char* error_string) {
103 if (UNLIKELY(!CheckIndex(idx.index_, dex_file_->NumStringIds(), error_string))) {
104 return nullptr;
105 }
106 return dex_file_->StringDataByIdx(idx);
107 }
108
109 // Try to find the name of the method with the given index. We do not want to rely on DexFile
110 // infrastructure at this point, so do it all by hand. begin and header correspond to begin_ and
111 // header_ of the DexFileVerifier. str will contain the pointer to the method name on success
112 // (flagged by the return value), otherwise error_msg will contain an error string.
FindMethodName(uint32_t method_index,const uint8_t * begin,const DexFile::Header * header,const char ** str,std::string * error_msg)113 static bool FindMethodName(uint32_t method_index,
114 const uint8_t* begin,
115 const DexFile::Header* header,
116 const char** str,
117 std::string* error_msg) {
118 if (method_index >= header->method_ids_size_) {
119 *error_msg = "Method index not available for method flags verification";
120 return false;
121 }
122 uint32_t string_idx =
123 (reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) +
124 method_index)->name_idx_.index_;
125 if (string_idx >= header->string_ids_size_) {
126 *error_msg = "String index not available for method flags verification";
127 return false;
128 }
129 uint32_t string_off =
130 (reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx)->
131 string_data_off_;
132 if (string_off >= header->file_size_) {
133 *error_msg = "String offset out of bounds for method flags verification";
134 return false;
135 }
136 const uint8_t* str_data_ptr = begin + string_off;
137 uint32_t dummy;
138 if (!DecodeUnsignedLeb128Checked(&str_data_ptr, begin + header->file_size_, &dummy)) {
139 *error_msg = "String size out of bounds for method flags verification";
140 return false;
141 }
142 *str = reinterpret_cast<const char*>(str_data_ptr);
143 return true;
144 }
145
146 // Gets constructor flags based on the |method_name|. Returns true if
147 // method_name is either <clinit> or <init> and sets
148 // |constructor_flags_by_name| appropriately. Otherwise set
149 // |constructor_flags_by_name| to zero and returns whether
150 // |method_name| is valid.
GetConstructorFlagsForMethodName(const char * method_name,uint32_t * constructor_flags_by_name)151 bool GetConstructorFlagsForMethodName(const char* method_name,
152 uint32_t* constructor_flags_by_name) {
153 if (method_name[0] != '<') {
154 *constructor_flags_by_name = 0;
155 return true;
156 }
157 if (strcmp(method_name + 1, "clinit>") == 0) {
158 *constructor_flags_by_name = kAccStatic | kAccConstructor;
159 return true;
160 }
161 if (strcmp(method_name + 1, "init>") == 0) {
162 *constructor_flags_by_name = kAccConstructor;
163 return true;
164 }
165 *constructor_flags_by_name = 0;
166 return false;
167 }
168
CheckLoadStringByTypeIdx(dex::TypeIndex type_idx,const char * error_string)169 const char* DexFileVerifier::CheckLoadStringByTypeIdx(dex::TypeIndex type_idx,
170 const char* error_string) {
171 if (UNLIKELY(!CheckIndex(type_idx.index_, dex_file_->NumTypeIds(), error_string))) {
172 return nullptr;
173 }
174 return CheckLoadStringByIdx(dex_file_->GetTypeId(type_idx).descriptor_idx_, error_string);
175 }
176
CheckLoadFieldId(uint32_t idx,const char * error_string)177 const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
178 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
179 return nullptr;
180 }
181 return &dex_file_->GetFieldId(idx);
182 }
183
CheckLoadMethodId(uint32_t idx,const char * err_string)184 const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
185 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
186 return nullptr;
187 }
188 return &dex_file_->GetMethodId(idx);
189 }
190
CheckLoadProtoId(uint32_t idx,const char * err_string)191 const DexFile::ProtoId* DexFileVerifier::CheckLoadProtoId(uint32_t idx, const char* err_string) {
192 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumProtoIds(), err_string))) {
193 return nullptr;
194 }
195 return &dex_file_->GetProtoId(idx);
196 }
197
198 // Helper macro to load string and return false on error.
199 #define LOAD_STRING(var, idx, error) \
200 const char* (var) = CheckLoadStringByIdx(idx, error); \
201 if (UNLIKELY((var) == nullptr)) { \
202 return false; \
203 }
204
205 // Helper macro to load string by type idx and return false on error.
206 #define LOAD_STRING_BY_TYPE(var, type_idx, error) \
207 const char* (var) = CheckLoadStringByTypeIdx(type_idx, error); \
208 if (UNLIKELY((var) == nullptr)) { \
209 return false; \
210 }
211
212 // Helper macro to load method id. Return last parameter on error.
213 #define LOAD_METHOD(var, idx, error_string, error_stmt) \
214 const DexFile::MethodId* (var) = CheckLoadMethodId(idx, error_string); \
215 if (UNLIKELY((var) == nullptr)) { \
216 error_stmt; \
217 }
218
219 // Helper macro to load method id. Return last parameter on error.
220 #define LOAD_FIELD(var, idx, fmt, error_stmt) \
221 const DexFile::FieldId* (var) = CheckLoadFieldId(idx, fmt); \
222 if (UNLIKELY((var) == nullptr)) { \
223 error_stmt; \
224 }
225
Verify(const DexFile * dex_file,const uint8_t * begin,size_t size,const char * location,bool verify_checksum,std::string * error_msg)226 bool DexFileVerifier::Verify(const DexFile* dex_file,
227 const uint8_t* begin,
228 size_t size,
229 const char* location,
230 bool verify_checksum,
231 std::string* error_msg) {
232 std::unique_ptr<DexFileVerifier> verifier(
233 new DexFileVerifier(dex_file, begin, size, location, verify_checksum));
234 if (!verifier->Verify()) {
235 *error_msg = verifier->FailureReason();
236 return false;
237 }
238 return true;
239 }
240
CheckShortyDescriptorMatch(char shorty_char,const char * descriptor,bool is_return_type)241 bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
242 bool is_return_type) {
243 switch (shorty_char) {
244 case 'V':
245 if (UNLIKELY(!is_return_type)) {
246 ErrorStringPrintf("Invalid use of void");
247 return false;
248 }
249 FALLTHROUGH_INTENDED;
250 case 'B':
251 case 'C':
252 case 'D':
253 case 'F':
254 case 'I':
255 case 'J':
256 case 'S':
257 case 'Z':
258 if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
259 ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
260 shorty_char, descriptor);
261 return false;
262 }
263 break;
264 case 'L':
265 if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
266 ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
267 return false;
268 }
269 break;
270 default:
271 ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
272 return false;
273 }
274 return true;
275 }
276
CheckListSize(const void * start,size_t count,size_t elem_size,const char * label)277 bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
278 const char* label) {
279 // Check that size is not 0.
280 CHECK_NE(elem_size, 0U);
281
282 const uint8_t* range_start = reinterpret_cast<const uint8_t*>(start);
283 const uint8_t* file_start = reinterpret_cast<const uint8_t*>(begin_);
284
285 // Check for overflow.
286 uintptr_t max = 0 - 1;
287 size_t available_bytes_till_end_of_mem = max - reinterpret_cast<uintptr_t>(start);
288 size_t max_count = available_bytes_till_end_of_mem / elem_size;
289 if (max_count < count) {
290 ErrorStringPrintf("Overflow in range for %s: %zx for %zu@%zu", label,
291 static_cast<size_t>(range_start - file_start),
292 count, elem_size);
293 return false;
294 }
295
296 const uint8_t* range_end = range_start + count * elem_size;
297 const uint8_t* file_end = file_start + size_;
298 if (UNLIKELY((range_start < file_start) || (range_end > file_end))) {
299 // Note: these two tests are enough as we make sure above that there's no overflow.
300 ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
301 static_cast<size_t>(range_start - file_start),
302 static_cast<size_t>(range_end - file_start));
303 return false;
304 }
305 return true;
306 }
307
CheckList(size_t element_size,const char * label,const uint8_t ** ptr)308 bool DexFileVerifier::CheckList(size_t element_size, const char* label, const uint8_t* *ptr) {
309 // Check that the list is available. The first 4B are the count.
310 if (!CheckListSize(*ptr, 1, 4U, label)) {
311 return false;
312 }
313
314 uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
315 if (count > 0) {
316 if (!CheckListSize(*ptr + 4, count, element_size, label)) {
317 return false;
318 }
319 }
320
321 *ptr += 4 + count * element_size;
322 return true;
323 }
324
CheckIndex(uint32_t field,uint32_t limit,const char * label)325 bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
326 if (UNLIKELY(field >= limit)) {
327 ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
328 return false;
329 }
330 return true;
331 }
332
CheckValidOffsetAndSize(uint32_t offset,uint32_t size,size_t alignment,const char * label)333 bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset,
334 uint32_t size,
335 size_t alignment,
336 const char* label) {
337 if (size == 0) {
338 if (offset != 0) {
339 ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
340 return false;
341 }
342 }
343 if (size_ <= offset) {
344 ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
345 return false;
346 }
347 if (alignment != 0 && !IsAlignedParam(offset, alignment)) {
348 ErrorStringPrintf("Offset(%d) should be aligned by %zu for %s.", offset, alignment, label);
349 return false;
350 }
351 return true;
352 }
353
CheckSizeLimit(uint32_t size,uint32_t limit,const char * label)354 bool DexFileVerifier::CheckSizeLimit(uint32_t size, uint32_t limit, const char* label) {
355 if (size > limit) {
356 ErrorStringPrintf("Size(%u) should not exceed limit(%u) for %s.", size, limit, label);
357 return false;
358 }
359 return true;
360 }
361
CheckHeader()362 bool DexFileVerifier::CheckHeader() {
363 // Check file size from the header.
364 uint32_t expected_size = header_->file_size_;
365 if (size_ != expected_size) {
366 ErrorStringPrintf("Bad file size (%zd, expected %u)", size_, expected_size);
367 return false;
368 }
369
370 uint32_t adler_checksum = dex_file_->CalculateChecksum();
371 // Compute and verify the checksum in the header.
372 if (adler_checksum != header_->checksum_) {
373 if (verify_checksum_) {
374 ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
375 return false;
376 } else {
377 LOG(WARNING) << StringPrintf(
378 "Ignoring bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
379 }
380 }
381
382 // Check the contents of the header.
383 if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
384 ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
385 return false;
386 }
387
388 const uint32_t expected_header_size = dex_file_->IsCompactDexFile()
389 ? sizeof(CompactDexFile::Header)
390 : sizeof(StandardDexFile::Header);
391
392 if (header_->header_size_ != expected_header_size) {
393 ErrorStringPrintf("Bad header size: %ud expected %ud",
394 header_->header_size_,
395 expected_header_size);
396 return false;
397 }
398
399 // Check that all offsets are inside the file.
400 bool result =
401 CheckValidOffsetAndSize(header_->link_off_,
402 header_->link_size_,
403 0 /* unaligned */,
404 "link") &&
405 CheckValidOffsetAndSize(header_->map_off_,
406 header_->map_off_,
407 4,
408 "map") &&
409 CheckValidOffsetAndSize(header_->string_ids_off_,
410 header_->string_ids_size_,
411 4,
412 "string-ids") &&
413 CheckValidOffsetAndSize(header_->type_ids_off_,
414 header_->type_ids_size_,
415 4,
416 "type-ids") &&
417 CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") &&
418 CheckValidOffsetAndSize(header_->proto_ids_off_,
419 header_->proto_ids_size_,
420 4,
421 "proto-ids") &&
422 CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") &&
423 CheckValidOffsetAndSize(header_->field_ids_off_,
424 header_->field_ids_size_,
425 4,
426 "field-ids") &&
427 CheckValidOffsetAndSize(header_->method_ids_off_,
428 header_->method_ids_size_,
429 4,
430 "method-ids") &&
431 CheckValidOffsetAndSize(header_->class_defs_off_,
432 header_->class_defs_size_,
433 4,
434 "class-defs") &&
435 CheckValidOffsetAndSize(header_->data_off_,
436 header_->data_size_,
437 0, // Unaligned, spec doesn't talk about it, even though size
438 // is supposed to be a multiple of 4.
439 "data");
440 return result;
441 }
442
CheckMap()443 bool DexFileVerifier::CheckMap() {
444 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ +
445 header_->map_off_);
446 // Check that map list content is available.
447 if (!CheckListSize(map, 1, sizeof(DexFile::MapList), "maplist content")) {
448 return false;
449 }
450
451 const DexFile::MapItem* item = map->list_;
452
453 uint32_t count = map->size_;
454 uint32_t last_offset = 0;
455 uint32_t last_type = 0;
456 uint32_t data_item_count = 0;
457 uint32_t data_items_left = header_->data_size_;
458 uint32_t used_bits = 0;
459
460 // Sanity check the size of the map list.
461 if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
462 return false;
463 }
464
465 // Check the items listed in the map.
466 for (uint32_t i = 0; i < count; i++) {
467 if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
468 ErrorStringPrintf("Out of order map item: %x then %x for type %x last type was %x",
469 last_offset,
470 item->offset_,
471 static_cast<uint32_t>(item->type_),
472 last_type);
473 return false;
474 }
475 if (UNLIKELY(item->offset_ >= header_->file_size_)) {
476 ErrorStringPrintf("Map item after end of file: %x, size %x",
477 item->offset_, header_->file_size_);
478 return false;
479 }
480
481 DexFile::MapItemType item_type = static_cast<DexFile::MapItemType>(item->type_);
482 if (IsDataSectionType(item_type)) {
483 uint32_t icount = item->size_;
484 if (UNLIKELY(icount > data_items_left)) {
485 ErrorStringPrintf("Too many items in data section: %ud item_type %zx",
486 data_item_count + icount,
487 static_cast<size_t>(item_type));
488 return false;
489 }
490 data_items_left -= icount;
491 data_item_count += icount;
492 }
493
494 uint32_t bit = MapTypeToBitMask(item_type);
495
496 if (UNLIKELY(bit == 0)) {
497 ErrorStringPrintf("Unknown map section type %x", item->type_);
498 return false;
499 }
500
501 if (UNLIKELY((used_bits & bit) != 0)) {
502 ErrorStringPrintf("Duplicate map section of type %x", item->type_);
503 return false;
504 }
505
506 used_bits |= bit;
507 last_offset = item->offset_;
508 last_type = item->type_;
509 item++;
510 }
511
512 // Check for missing sections in the map.
513 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
514 ErrorStringPrintf("Map is missing header entry");
515 return false;
516 }
517 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
518 ErrorStringPrintf("Map is missing map_list entry");
519 return false;
520 }
521 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
522 ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
523 ErrorStringPrintf("Map is missing string_ids entry");
524 return false;
525 }
526 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
527 ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
528 ErrorStringPrintf("Map is missing type_ids entry");
529 return false;
530 }
531 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
532 ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
533 ErrorStringPrintf("Map is missing proto_ids entry");
534 return false;
535 }
536 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
537 ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
538 ErrorStringPrintf("Map is missing field_ids entry");
539 return false;
540 }
541 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
542 ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
543 ErrorStringPrintf("Map is missing method_ids entry");
544 return false;
545 }
546 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
547 ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
548 ErrorStringPrintf("Map is missing class_defs entry");
549 return false;
550 }
551 return true;
552 }
553
ReadUnsignedLittleEndian(uint32_t size)554 uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
555 uint32_t result = 0;
556 if (LIKELY(CheckListSize(ptr_, size, sizeof(uint8_t), "encoded_value"))) {
557 for (uint32_t i = 0; i < size; i++) {
558 result |= ((uint32_t) *(ptr_++)) << (i * 8);
559 }
560 }
561 return result;
562 }
563
564
565 #define DECODE_UNSIGNED_CHECKED_FROM_WITH_ERROR_VALUE(ptr, var, error_value) \
566 uint32_t var; \
567 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
568 return error_value; \
569 }
570
571 #define DECODE_UNSIGNED_CHECKED_FROM(ptr, var) \
572 uint32_t var; \
573 if (!DecodeUnsignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
574 ErrorStringPrintf("Read out of bounds"); \
575 return false; \
576 }
577
578 #define DECODE_SIGNED_CHECKED_FROM(ptr, var) \
579 int32_t var; \
580 if (!DecodeSignedLeb128Checked(&(ptr), begin_ + size_, &(var))) { \
581 ErrorStringPrintf("Read out of bounds"); \
582 return false; \
583 }
584
CheckAndGetHandlerOffsets(const DexFile::CodeItem * code_item,uint32_t * handler_offsets,uint32_t handlers_size)585 bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
586 uint32_t* handler_offsets, uint32_t handlers_size) {
587 CodeItemDataAccessor accessor(*dex_file_, code_item);
588 const uint8_t* handlers_base = accessor.GetCatchHandlerData();
589
590 for (uint32_t i = 0; i < handlers_size; i++) {
591 bool catch_all;
592 size_t offset = ptr_ - handlers_base;
593 DECODE_SIGNED_CHECKED_FROM(ptr_, size);
594
595 if (UNLIKELY((size < -65536) || (size > 65536))) {
596 ErrorStringPrintf("Invalid exception handler size: %d", size);
597 return false;
598 }
599
600 if (size <= 0) {
601 catch_all = true;
602 size = -size;
603 } else {
604 catch_all = false;
605 }
606
607 handler_offsets[i] = static_cast<uint32_t>(offset);
608
609 while (size-- > 0) {
610 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
611 if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
612 return false;
613 }
614
615 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
616 if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
617 ErrorStringPrintf("Invalid handler addr: %x", addr);
618 return false;
619 }
620 }
621
622 if (catch_all) {
623 DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
624 if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
625 ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
626 return false;
627 }
628 }
629 }
630
631 return true;
632 }
633
CheckClassDataItemField(uint32_t idx,uint32_t access_flags,uint32_t class_access_flags,dex::TypeIndex class_type_index,bool expect_static)634 bool DexFileVerifier::CheckClassDataItemField(uint32_t idx,
635 uint32_t access_flags,
636 uint32_t class_access_flags,
637 dex::TypeIndex class_type_index,
638 bool expect_static) {
639 // Check for overflow.
640 if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
641 return false;
642 }
643
644 // Check that it's the right class.
645 dex::TypeIndex my_class_index =
646 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)->
647 class_idx_;
648 if (class_type_index != my_class_index) {
649 ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16,
650 my_class_index.index_,
651 class_type_index.index_);
652 return false;
653 }
654
655 // Check that it falls into the right class-data list.
656 bool is_static = (access_flags & kAccStatic) != 0;
657 if (UNLIKELY(is_static != expect_static)) {
658 ErrorStringPrintf("Static/instance field not in expected list");
659 return false;
660 }
661
662 // Check field access flags.
663 std::string error_msg;
664 if (!CheckFieldAccessFlags(idx, access_flags, class_access_flags, &error_msg)) {
665 ErrorStringPrintf("%s", error_msg.c_str());
666 return false;
667 }
668
669 return true;
670 }
671
CheckClassDataItemMethod(uint32_t idx,uint32_t access_flags,uint32_t class_access_flags,dex::TypeIndex class_type_index,uint32_t code_offset,std::unordered_set<uint32_t> * direct_method_indexes,bool expect_direct)672 bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx,
673 uint32_t access_flags,
674 uint32_t class_access_flags,
675 dex::TypeIndex class_type_index,
676 uint32_t code_offset,
677 std::unordered_set<uint32_t>* direct_method_indexes,
678 bool expect_direct) {
679 DCHECK(direct_method_indexes != nullptr);
680 // Check for overflow.
681 if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
682 return false;
683 }
684
685 // Check that it's the right class.
686 dex::TypeIndex my_class_index =
687 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)->
688 class_idx_;
689 if (class_type_index != my_class_index) {
690 ErrorStringPrintf("Method's class index unexpected, %" PRIu16 " vs %" PRIu16,
691 my_class_index.index_,
692 class_type_index.index_);
693 return false;
694 }
695
696 // Check that it's not defined as both direct and virtual.
697 if (expect_direct) {
698 direct_method_indexes->insert(idx);
699 } else if (direct_method_indexes->find(idx) != direct_method_indexes->end()) {
700 ErrorStringPrintf("Found virtual method with same index as direct method: %d", idx);
701 return false;
702 }
703
704 std::string error_msg;
705 const char* method_name;
706 if (!FindMethodName(idx, begin_, header_, &method_name, &error_msg)) {
707 ErrorStringPrintf("%s", error_msg.c_str());
708 return false;
709 }
710
711 uint32_t constructor_flags_by_name = 0;
712 if (!GetConstructorFlagsForMethodName(method_name, &constructor_flags_by_name)) {
713 ErrorStringPrintf("Bad method name: %s", method_name);
714 return false;
715 }
716
717 bool has_code = (code_offset != 0);
718 if (!CheckMethodAccessFlags(idx,
719 access_flags,
720 class_access_flags,
721 constructor_flags_by_name,
722 has_code,
723 expect_direct,
724 &error_msg)) {
725 ErrorStringPrintf("%s", error_msg.c_str());
726 return false;
727 }
728
729 if (constructor_flags_by_name != 0) {
730 if (!CheckConstructorProperties(idx, constructor_flags_by_name)) {
731 DCHECK(FailureReasonIsSet());
732 return false;
733 }
734 }
735
736 return true;
737 }
738
CheckPadding(size_t offset,uint32_t aligned_offset,DexFile::MapItemType type)739 bool DexFileVerifier::CheckPadding(size_t offset,
740 uint32_t aligned_offset,
741 DexFile::MapItemType type) {
742 if (offset < aligned_offset) {
743 if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(uint8_t), "section")) {
744 return false;
745 }
746 while (offset < aligned_offset) {
747 if (UNLIKELY(*ptr_ != '\0')) {
748 ErrorStringPrintf("Non-zero padding %x before section of type %zu at offset 0x%zx",
749 *ptr_,
750 static_cast<size_t>(type),
751 offset);
752 return false;
753 }
754 ptr_++;
755 offset++;
756 }
757 }
758 return true;
759 }
760
CheckEncodedValue()761 bool DexFileVerifier::CheckEncodedValue() {
762 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "encoded_value header")) {
763 return false;
764 }
765
766 uint8_t header_byte = *(ptr_++);
767 uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
768 uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
769
770 switch (value_type) {
771 case DexFile::kDexAnnotationByte:
772 if (UNLIKELY(value_arg != 0)) {
773 ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
774 return false;
775 }
776 ptr_++;
777 break;
778 case DexFile::kDexAnnotationShort:
779 case DexFile::kDexAnnotationChar:
780 if (UNLIKELY(value_arg > 1)) {
781 ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
782 return false;
783 }
784 ptr_ += value_arg + 1;
785 break;
786 case DexFile::kDexAnnotationInt:
787 case DexFile::kDexAnnotationFloat:
788 if (UNLIKELY(value_arg > 3)) {
789 ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
790 return false;
791 }
792 ptr_ += value_arg + 1;
793 break;
794 case DexFile::kDexAnnotationLong:
795 case DexFile::kDexAnnotationDouble:
796 ptr_ += value_arg + 1;
797 break;
798 case DexFile::kDexAnnotationString: {
799 if (UNLIKELY(value_arg > 3)) {
800 ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
801 return false;
802 }
803 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
804 if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
805 return false;
806 }
807 break;
808 }
809 case DexFile::kDexAnnotationType: {
810 if (UNLIKELY(value_arg > 3)) {
811 ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
812 return false;
813 }
814 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
815 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
816 return false;
817 }
818 break;
819 }
820 case DexFile::kDexAnnotationField:
821 case DexFile::kDexAnnotationEnum: {
822 if (UNLIKELY(value_arg > 3)) {
823 ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
824 return false;
825 }
826 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
827 if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
828 return false;
829 }
830 break;
831 }
832 case DexFile::kDexAnnotationMethod: {
833 if (UNLIKELY(value_arg > 3)) {
834 ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
835 return false;
836 }
837 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
838 if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
839 return false;
840 }
841 break;
842 }
843 case DexFile::kDexAnnotationArray:
844 if (UNLIKELY(value_arg != 0)) {
845 ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
846 return false;
847 }
848 if (!CheckEncodedArray()) {
849 return false;
850 }
851 break;
852 case DexFile::kDexAnnotationAnnotation:
853 if (UNLIKELY(value_arg != 0)) {
854 ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
855 return false;
856 }
857 if (!CheckEncodedAnnotation()) {
858 return false;
859 }
860 break;
861 case DexFile::kDexAnnotationNull:
862 if (UNLIKELY(value_arg != 0)) {
863 ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
864 return false;
865 }
866 break;
867 case DexFile::kDexAnnotationBoolean:
868 if (UNLIKELY(value_arg > 1)) {
869 ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
870 return false;
871 }
872 break;
873 case DexFile::kDexAnnotationMethodType: {
874 if (UNLIKELY(value_arg > 3)) {
875 ErrorStringPrintf("Bad encoded_value method type size %x", value_arg);
876 return false;
877 }
878 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
879 if (!CheckIndex(idx, header_->proto_ids_size_, "method_type value")) {
880 return false;
881 }
882 break;
883 }
884 case DexFile::kDexAnnotationMethodHandle: {
885 if (UNLIKELY(value_arg > 3)) {
886 ErrorStringPrintf("Bad encoded_value method handle size %x", value_arg);
887 return false;
888 }
889 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
890 if (!CheckIndex(idx, dex_file_->NumMethodHandles(), "method_handle value")) {
891 return false;
892 }
893 break;
894 }
895 default:
896 ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
897 return false;
898 }
899
900 return true;
901 }
902
CheckEncodedArray()903 bool DexFileVerifier::CheckEncodedArray() {
904 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
905
906 while (size--) {
907 if (!CheckEncodedValue()) {
908 failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
909 return false;
910 }
911 }
912 return true;
913 }
914
CheckEncodedAnnotation()915 bool DexFileVerifier::CheckEncodedAnnotation() {
916 DECODE_UNSIGNED_CHECKED_FROM(ptr_, anno_idx);
917 if (!CheckIndex(anno_idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
918 return false;
919 }
920
921 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
922 uint32_t last_idx = 0;
923
924 for (uint32_t i = 0; i < size; i++) {
925 DECODE_UNSIGNED_CHECKED_FROM(ptr_, idx);
926 if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
927 return false;
928 }
929
930 if (UNLIKELY(last_idx >= idx && i != 0)) {
931 ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
932 last_idx, idx);
933 return false;
934 }
935
936 if (!CheckEncodedValue()) {
937 return false;
938 }
939
940 last_idx = idx;
941 }
942 return true;
943 }
944
FindClassIndexAndDef(uint32_t index,bool is_field,dex::TypeIndex * class_type_index,const DexFile::ClassDef ** output_class_def)945 bool DexFileVerifier::FindClassIndexAndDef(uint32_t index,
946 bool is_field,
947 dex::TypeIndex* class_type_index,
948 const DexFile::ClassDef** output_class_def) {
949 DCHECK(class_type_index != nullptr);
950 DCHECK(output_class_def != nullptr);
951
952 // First check if the index is valid.
953 if (index >= (is_field ? header_->field_ids_size_ : header_->method_ids_size_)) {
954 return false;
955 }
956
957 // Next get the type index.
958 if (is_field) {
959 *class_type_index =
960 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + index)->
961 class_idx_;
962 } else {
963 *class_type_index =
964 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + index)->
965 class_idx_;
966 }
967
968 // Check if that is valid.
969 if (class_type_index->index_ >= header_->type_ids_size_) {
970 return false;
971 }
972
973 // Now search for the class def. This is basically a specialized version of the DexFile code, as
974 // we should not trust that this is a valid DexFile just yet.
975 const DexFile::ClassDef* class_def_begin =
976 reinterpret_cast<const DexFile::ClassDef*>(begin_ + header_->class_defs_off_);
977 for (size_t i = 0; i < header_->class_defs_size_; ++i) {
978 const DexFile::ClassDef* class_def = class_def_begin + i;
979 if (class_def->class_idx_ == *class_type_index) {
980 *output_class_def = class_def;
981 return true;
982 }
983 }
984
985 // Didn't find the class-def, not defined here...
986 return false;
987 }
988
CheckOrderAndGetClassDef(bool is_field,const char * type_descr,uint32_t curr_index,uint32_t prev_index,bool * have_class,dex::TypeIndex * class_type_index,const DexFile::ClassDef ** class_def)989 bool DexFileVerifier::CheckOrderAndGetClassDef(bool is_field,
990 const char* type_descr,
991 uint32_t curr_index,
992 uint32_t prev_index,
993 bool* have_class,
994 dex::TypeIndex* class_type_index,
995 const DexFile::ClassDef** class_def) {
996 if (curr_index < prev_index) {
997 ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32,
998 type_descr,
999 prev_index,
1000 curr_index);
1001 return false;
1002 }
1003
1004 if (!*have_class) {
1005 *have_class = FindClassIndexAndDef(curr_index, is_field, class_type_index, class_def);
1006 if (!*have_class) {
1007 // Should have really found one.
1008 ErrorStringPrintf("could not find declaring class for %s index %" PRIu32,
1009 type_descr,
1010 curr_index);
1011 return false;
1012 }
1013 }
1014 return true;
1015 }
1016
CheckStaticFieldTypes(const DexFile::ClassDef * class_def)1017 bool DexFileVerifier::CheckStaticFieldTypes(const DexFile::ClassDef* class_def) {
1018 if (class_def == nullptr) {
1019 return true;
1020 }
1021
1022 ClassDataItemIterator field_it(*dex_file_, ptr_);
1023 EncodedStaticFieldValueIterator array_it(*dex_file_, *class_def);
1024
1025 for (; field_it.HasNextStaticField() && array_it.HasNext(); field_it.Next(), array_it.Next()) {
1026 uint32_t index = field_it.GetMemberIndex();
1027 const DexFile::TypeId& type_id = dex_file_->GetTypeId(dex_file_->GetFieldId(index).type_idx_);
1028 const char* field_type_name =
1029 dex_file_->GetStringData(dex_file_->GetStringId(type_id.descriptor_idx_));
1030 Primitive::Type field_type = Primitive::GetType(field_type_name[0]);
1031 EncodedArrayValueIterator::ValueType array_type = array_it.GetValueType();
1032 // Ensure this matches RuntimeEncodedStaticFieldValueIterator.
1033 switch (array_type) {
1034 case EncodedArrayValueIterator::ValueType::kBoolean:
1035 if (field_type != Primitive::kPrimBoolean) {
1036 ErrorStringPrintf("unexpected static field initial value type: 'Z' vs '%c'",
1037 field_type_name[0]);
1038 return false;
1039 }
1040 break;
1041 case EncodedArrayValueIterator::ValueType::kByte:
1042 if (field_type != Primitive::kPrimByte) {
1043 ErrorStringPrintf("unexpected static field initial value type: 'B' vs '%c'",
1044 field_type_name[0]);
1045 return false;
1046 }
1047 break;
1048 case EncodedArrayValueIterator::ValueType::kShort:
1049 if (field_type != Primitive::kPrimShort) {
1050 ErrorStringPrintf("unexpected static field initial value type: 'S' vs '%c'",
1051 field_type_name[0]);
1052 return false;
1053 }
1054 break;
1055 case EncodedArrayValueIterator::ValueType::kChar:
1056 if (field_type != Primitive::kPrimChar) {
1057 ErrorStringPrintf("unexpected static field initial value type: 'C' vs '%c'",
1058 field_type_name[0]);
1059 return false;
1060 }
1061 break;
1062 case EncodedArrayValueIterator::ValueType::kInt:
1063 if (field_type != Primitive::kPrimInt) {
1064 ErrorStringPrintf("unexpected static field initial value type: 'I' vs '%c'",
1065 field_type_name[0]);
1066 return false;
1067 }
1068 break;
1069 case EncodedArrayValueIterator::ValueType::kLong:
1070 if (field_type != Primitive::kPrimLong) {
1071 ErrorStringPrintf("unexpected static field initial value type: 'J' vs '%c'",
1072 field_type_name[0]);
1073 return false;
1074 }
1075 break;
1076 case EncodedArrayValueIterator::ValueType::kFloat:
1077 if (field_type != Primitive::kPrimFloat) {
1078 ErrorStringPrintf("unexpected static field initial value type: 'F' vs '%c'",
1079 field_type_name[0]);
1080 return false;
1081 }
1082 break;
1083 case EncodedArrayValueIterator::ValueType::kDouble:
1084 if (field_type != Primitive::kPrimDouble) {
1085 ErrorStringPrintf("unexpected static field initial value type: 'D' vs '%c'",
1086 field_type_name[0]);
1087 return false;
1088 }
1089 break;
1090 case EncodedArrayValueIterator::ValueType::kNull:
1091 case EncodedArrayValueIterator::ValueType::kString:
1092 case EncodedArrayValueIterator::ValueType::kType:
1093 if (field_type != Primitive::kPrimNot) {
1094 ErrorStringPrintf("unexpected static field initial value type: 'L' vs '%c'",
1095 field_type_name[0]);
1096 return false;
1097 }
1098 break;
1099 default:
1100 ErrorStringPrintf("unexpected static field initial value type: %x", array_type);
1101 return false;
1102 }
1103 }
1104
1105 if (array_it.HasNext()) {
1106 ErrorStringPrintf("too many static field initial values");
1107 return false;
1108 }
1109 return true;
1110 }
1111
1112 template <bool kStatic>
CheckIntraClassDataItemFields(ClassDataItemIterator * it,bool * have_class,dex::TypeIndex * class_type_index,const DexFile::ClassDef ** class_def)1113 bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it,
1114 bool* have_class,
1115 dex::TypeIndex* class_type_index,
1116 const DexFile::ClassDef** class_def) {
1117 DCHECK(it != nullptr);
1118 // These calls use the raw access flags to check whether the whole dex field is valid.
1119 uint32_t prev_index = 0;
1120 for (; kStatic ? it->HasNextStaticField() : it->HasNextInstanceField(); it->Next()) {
1121 uint32_t curr_index = it->GetMemberIndex();
1122 if (!CheckOrderAndGetClassDef(true,
1123 kStatic ? "static field" : "instance field",
1124 curr_index,
1125 prev_index,
1126 have_class,
1127 class_type_index,
1128 class_def)) {
1129 return false;
1130 }
1131 DCHECK(class_def != nullptr);
1132 if (!CheckClassDataItemField(curr_index,
1133 it->GetRawMemberAccessFlags(),
1134 (*class_def)->access_flags_,
1135 *class_type_index,
1136 kStatic)) {
1137 return false;
1138 }
1139
1140 prev_index = curr_index;
1141 }
1142
1143 return true;
1144 }
1145
1146 template <bool kDirect>
CheckIntraClassDataItemMethods(ClassDataItemIterator * it,std::unordered_set<uint32_t> * direct_method_indexes,bool * have_class,dex::TypeIndex * class_type_index,const DexFile::ClassDef ** class_def)1147 bool DexFileVerifier::CheckIntraClassDataItemMethods(
1148 ClassDataItemIterator* it,
1149 std::unordered_set<uint32_t>* direct_method_indexes,
1150 bool* have_class,
1151 dex::TypeIndex* class_type_index,
1152 const DexFile::ClassDef** class_def) {
1153 uint32_t prev_index = 0;
1154 for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) {
1155 uint32_t curr_index = it->GetMemberIndex();
1156 if (!CheckOrderAndGetClassDef(false,
1157 kDirect ? "direct method" : "virtual method",
1158 curr_index,
1159 prev_index,
1160 have_class,
1161 class_type_index,
1162 class_def)) {
1163 return false;
1164 }
1165 DCHECK(class_def != nullptr);
1166 if (!CheckClassDataItemMethod(curr_index,
1167 it->GetRawMemberAccessFlags(),
1168 (*class_def)->access_flags_,
1169 *class_type_index,
1170 it->GetMethodCodeItemOffset(),
1171 direct_method_indexes,
1172 kDirect)) {
1173 return false;
1174 }
1175
1176 prev_index = curr_index;
1177 }
1178
1179 return true;
1180 }
1181
CheckIntraClassDataItem()1182 bool DexFileVerifier::CheckIntraClassDataItem() {
1183 ClassDataItemIterator it(*dex_file_, ptr_);
1184 std::unordered_set<uint32_t> direct_method_indexes;
1185
1186 // This code is complicated by the fact that we don't directly know which class this belongs to.
1187 // So we need to explicitly search with the first item we find (either field or method), and then,
1188 // as the lookup is expensive, cache the result.
1189 bool have_class = false;
1190 dex::TypeIndex class_type_index;
1191 const DexFile::ClassDef* class_def = nullptr;
1192
1193 // Check fields.
1194 if (!CheckIntraClassDataItemFields<true>(&it,
1195 &have_class,
1196 &class_type_index,
1197 &class_def)) {
1198 return false;
1199 }
1200 if (!CheckIntraClassDataItemFields<false>(&it,
1201 &have_class,
1202 &class_type_index,
1203 &class_def)) {
1204 return false;
1205 }
1206
1207 // Check methods.
1208 if (!CheckIntraClassDataItemMethods<true>(&it,
1209 &direct_method_indexes,
1210 &have_class,
1211 &class_type_index,
1212 &class_def)) {
1213 return false;
1214 }
1215 if (!CheckIntraClassDataItemMethods<false>(&it,
1216 &direct_method_indexes,
1217 &have_class,
1218 &class_type_index,
1219 &class_def)) {
1220 return false;
1221 }
1222
1223 const uint8_t* end_ptr = it.EndDataPointer();
1224
1225 // Check static field types against initial static values in encoded array.
1226 if (!CheckStaticFieldTypes(class_def)) {
1227 return false;
1228 }
1229
1230 ptr_ = end_ptr;
1231 return true;
1232 }
1233
CheckIntraCodeItem()1234 bool DexFileVerifier::CheckIntraCodeItem() {
1235 const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
1236 if (!CheckListSize(code_item, 1, sizeof(DexFile::CodeItem), "code")) {
1237 return false;
1238 }
1239
1240 CodeItemDataAccessor accessor(*dex_file_, code_item);
1241 if (UNLIKELY(accessor.InsSize() > accessor.RegistersSize())) {
1242 ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
1243 accessor.InsSize(), accessor.RegistersSize());
1244 return false;
1245 }
1246
1247 if (UNLIKELY(accessor.OutsSize() > 5 && accessor.OutsSize() > accessor.RegistersSize())) {
1248 /*
1249 * outs_size can be up to 5, even if registers_size is smaller, since the
1250 * short forms of method invocation allow repetitions of a register multiple
1251 * times within a single parameter list. However, longer parameter lists
1252 * need to be represented in-order in the register file.
1253 */
1254 ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
1255 accessor.OutsSize(), accessor.RegistersSize());
1256 return false;
1257 }
1258
1259 const uint16_t* insns = accessor.Insns();
1260 uint32_t insns_size = accessor.InsnsSizeInCodeUnits();
1261 if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
1262 return false;
1263 }
1264
1265 // Grab the end of the insns if there are no try_items.
1266 uint32_t try_items_size = accessor.TriesSize();
1267 if (try_items_size == 0) {
1268 ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
1269 return true;
1270 }
1271
1272 // try_items are 4-byte aligned. Verify the spacer is 0.
1273 if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
1274 ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
1275 return false;
1276 }
1277
1278 const DexFile::TryItem* try_items = accessor.TryItems().begin();
1279 if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
1280 return false;
1281 }
1282
1283 ptr_ = accessor.GetCatchHandlerData();
1284 DECODE_UNSIGNED_CHECKED_FROM(ptr_, handlers_size);
1285
1286 if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
1287 ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
1288 return false;
1289 }
1290
1291 std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
1292 if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
1293 return false;
1294 }
1295
1296 uint32_t last_addr = 0;
1297 while (try_items_size--) {
1298 if (UNLIKELY(try_items->start_addr_ < last_addr)) {
1299 ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
1300 return false;
1301 }
1302
1303 if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
1304 ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
1305 return false;
1306 }
1307
1308 uint32_t i;
1309 for (i = 0; i < handlers_size; i++) {
1310 if (try_items->handler_off_ == handler_offsets[i]) {
1311 break;
1312 }
1313 }
1314
1315 if (UNLIKELY(i == handlers_size)) {
1316 ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
1317 return false;
1318 }
1319
1320 last_addr = try_items->start_addr_ + try_items->insn_count_;
1321 if (UNLIKELY(last_addr > insns_size)) {
1322 ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
1323 return false;
1324 }
1325
1326 try_items++;
1327 }
1328
1329 return true;
1330 }
1331
CheckIntraStringDataItem()1332 bool DexFileVerifier::CheckIntraStringDataItem() {
1333 DECODE_UNSIGNED_CHECKED_FROM(ptr_, size);
1334 const uint8_t* file_end = begin_ + size_;
1335
1336 for (uint32_t i = 0; i < size; i++) {
1337 CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
1338 if (UNLIKELY(ptr_ >= file_end)) {
1339 ErrorStringPrintf("String data would go beyond end-of-file");
1340 return false;
1341 }
1342
1343 uint8_t byte = *(ptr_++);
1344
1345 // Switch on the high 4 bits.
1346 switch (byte >> 4) {
1347 case 0x00:
1348 // Special case of bit pattern 0xxx.
1349 if (UNLIKELY(byte == 0)) {
1350 CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
1351 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
1352 return false;
1353 }
1354 break;
1355 case 0x01:
1356 case 0x02:
1357 case 0x03:
1358 case 0x04:
1359 case 0x05:
1360 case 0x06:
1361 case 0x07:
1362 // No extra checks necessary for bit pattern 0xxx.
1363 break;
1364 case 0x08:
1365 case 0x09:
1366 case 0x0a:
1367 case 0x0b:
1368 case 0x0f:
1369 // Illegal bit patterns 10xx or 1111.
1370 // Note: 1111 is valid for normal UTF-8, but not here.
1371 ErrorStringPrintf("Illegal start byte %x in string data", byte);
1372 return false;
1373 case 0x0c:
1374 case 0x0d: {
1375 // Bit pattern 110x has an additional byte.
1376 uint8_t byte2 = *(ptr_++);
1377 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1378 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
1379 return false;
1380 }
1381 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
1382 if (UNLIKELY((value != 0) && (value < 0x80))) {
1383 ErrorStringPrintf("Illegal representation for value %x in string data", value);
1384 return false;
1385 }
1386 break;
1387 }
1388 case 0x0e: {
1389 // Bit pattern 1110 has 2 additional bytes.
1390 uint8_t byte2 = *(ptr_++);
1391 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1392 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
1393 return false;
1394 }
1395 uint8_t byte3 = *(ptr_++);
1396 if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
1397 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
1398 return false;
1399 }
1400 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
1401 if (UNLIKELY(value < 0x800)) {
1402 ErrorStringPrintf("Illegal representation for value %x in string data", value);
1403 return false;
1404 }
1405 break;
1406 }
1407 }
1408 }
1409
1410 if (UNLIKELY(*(ptr_++) != '\0')) {
1411 ErrorStringPrintf("String longer than indicated size %x", size);
1412 return false;
1413 }
1414
1415 return true;
1416 }
1417
CheckIntraDebugInfoItem()1418 bool DexFileVerifier::CheckIntraDebugInfoItem() {
1419 DECODE_UNSIGNED_CHECKED_FROM(ptr_, dummy);
1420 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameters_size);
1421 if (UNLIKELY(parameters_size > 65536)) {
1422 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
1423 return false;
1424 }
1425
1426 for (uint32_t j = 0; j < parameters_size; j++) {
1427 DECODE_UNSIGNED_CHECKED_FROM(ptr_, parameter_name);
1428 if (parameter_name != 0) {
1429 parameter_name--;
1430 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
1431 return false;
1432 }
1433 }
1434 }
1435
1436 while (true) {
1437 uint8_t opcode = *(ptr_++);
1438 switch (opcode) {
1439 case DexFile::DBG_END_SEQUENCE: {
1440 return true;
1441 }
1442 case DexFile::DBG_ADVANCE_PC: {
1443 DECODE_UNSIGNED_CHECKED_FROM(ptr_, advance_pc_dummy);
1444 break;
1445 }
1446 case DexFile::DBG_ADVANCE_LINE: {
1447 DECODE_SIGNED_CHECKED_FROM(ptr_, advance_line_dummy);
1448 break;
1449 }
1450 case DexFile::DBG_START_LOCAL: {
1451 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1452 if (UNLIKELY(reg_num >= 65536)) {
1453 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1454 return false;
1455 }
1456 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1457 if (name_idx != 0) {
1458 name_idx--;
1459 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
1460 return false;
1461 }
1462 }
1463 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
1464 if (type_idx != 0) {
1465 type_idx--;
1466 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL type_idx")) {
1467 return false;
1468 }
1469 }
1470 break;
1471 }
1472 case DexFile::DBG_END_LOCAL:
1473 case DexFile::DBG_RESTART_LOCAL: {
1474 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1475 if (UNLIKELY(reg_num >= 65536)) {
1476 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1477 return false;
1478 }
1479 break;
1480 }
1481 case DexFile::DBG_START_LOCAL_EXTENDED: {
1482 DECODE_UNSIGNED_CHECKED_FROM(ptr_, reg_num);
1483 if (UNLIKELY(reg_num >= 65536)) {
1484 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
1485 return false;
1486 }
1487 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1488 if (name_idx != 0) {
1489 name_idx--;
1490 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
1491 return false;
1492 }
1493 }
1494 DECODE_UNSIGNED_CHECKED_FROM(ptr_, type_idx);
1495 if (type_idx != 0) {
1496 type_idx--;
1497 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
1498 return false;
1499 }
1500 }
1501 DECODE_UNSIGNED_CHECKED_FROM(ptr_, sig_idx);
1502 if (sig_idx != 0) {
1503 sig_idx--;
1504 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
1505 return false;
1506 }
1507 }
1508 break;
1509 }
1510 case DexFile::DBG_SET_FILE: {
1511 DECODE_UNSIGNED_CHECKED_FROM(ptr_, name_idx);
1512 if (name_idx != 0) {
1513 name_idx--;
1514 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
1515 return false;
1516 }
1517 }
1518 break;
1519 }
1520 }
1521 }
1522 }
1523
CheckIntraAnnotationItem()1524 bool DexFileVerifier::CheckIntraAnnotationItem() {
1525 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "annotation visibility")) {
1526 return false;
1527 }
1528
1529 // Check visibility
1530 switch (*(ptr_++)) {
1531 case DexFile::kDexVisibilityBuild:
1532 case DexFile::kDexVisibilityRuntime:
1533 case DexFile::kDexVisibilitySystem:
1534 break;
1535 default:
1536 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
1537 return false;
1538 }
1539
1540 if (!CheckEncodedAnnotation()) {
1541 return false;
1542 }
1543
1544 return true;
1545 }
1546
CheckIntraAnnotationsDirectoryItem()1547 bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1548 const DexFile::AnnotationsDirectoryItem* item =
1549 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
1550 if (!CheckListSize(item, 1, sizeof(DexFile::AnnotationsDirectoryItem), "annotations_directory")) {
1551 return false;
1552 }
1553
1554 // Field annotations follow immediately after the annotations directory.
1555 const DexFile::FieldAnnotationsItem* field_item =
1556 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1557 uint32_t field_count = item->fields_size_;
1558 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
1559 return false;
1560 }
1561
1562 uint32_t last_idx = 0;
1563 for (uint32_t i = 0; i < field_count; i++) {
1564 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1565 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
1566 return false;
1567 }
1568 last_idx = field_item->field_idx_;
1569 field_item++;
1570 }
1571
1572 // Method annotations follow immediately after field annotations.
1573 const DexFile::MethodAnnotationsItem* method_item =
1574 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1575 uint32_t method_count = item->methods_size_;
1576 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1577 return false;
1578 }
1579
1580 last_idx = 0;
1581 for (uint32_t i = 0; i < method_count; i++) {
1582 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1583 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1584 last_idx, method_item->method_idx_);
1585 return false;
1586 }
1587 last_idx = method_item->method_idx_;
1588 method_item++;
1589 }
1590
1591 // Parameter annotations follow immediately after method annotations.
1592 const DexFile::ParameterAnnotationsItem* parameter_item =
1593 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1594 uint32_t parameter_count = item->parameters_size_;
1595 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
1596 "parameter_annotations list")) {
1597 return false;
1598 }
1599
1600 last_idx = 0;
1601 for (uint32_t i = 0; i < parameter_count; i++) {
1602 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1603 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1604 last_idx, parameter_item->method_idx_);
1605 return false;
1606 }
1607 last_idx = parameter_item->method_idx_;
1608 parameter_item++;
1609 }
1610
1611 // Return a pointer to the end of the annotations.
1612 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
1613 return true;
1614 }
1615
CheckIntraSectionIterate(size_t offset,uint32_t section_count,DexFile::MapItemType type)1616 bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
1617 DexFile::MapItemType type) {
1618 // Get the right alignment mask for the type of section.
1619 size_t alignment_mask;
1620 switch (type) {
1621 case DexFile::kDexTypeClassDataItem:
1622 case DexFile::kDexTypeStringDataItem:
1623 case DexFile::kDexTypeDebugInfoItem:
1624 case DexFile::kDexTypeAnnotationItem:
1625 case DexFile::kDexTypeEncodedArrayItem:
1626 alignment_mask = sizeof(uint8_t) - 1;
1627 break;
1628 default:
1629 alignment_mask = sizeof(uint32_t) - 1;
1630 break;
1631 }
1632
1633 // Iterate through the items in the section.
1634 for (uint32_t i = 0; i < section_count; i++) {
1635 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
1636
1637 // Check the padding between items.
1638 if (!CheckPadding(offset, aligned_offset, type)) {
1639 return false;
1640 }
1641
1642 // Check depending on the section type.
1643 const uint8_t* start_ptr = ptr_;
1644 switch (type) {
1645 case DexFile::kDexTypeStringIdItem: {
1646 if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
1647 return false;
1648 }
1649 ptr_ += sizeof(DexFile::StringId);
1650 break;
1651 }
1652 case DexFile::kDexTypeTypeIdItem: {
1653 if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
1654 return false;
1655 }
1656 ptr_ += sizeof(DexFile::TypeId);
1657 break;
1658 }
1659 case DexFile::kDexTypeProtoIdItem: {
1660 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
1661 return false;
1662 }
1663 ptr_ += sizeof(DexFile::ProtoId);
1664 break;
1665 }
1666 case DexFile::kDexTypeFieldIdItem: {
1667 if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
1668 return false;
1669 }
1670 ptr_ += sizeof(DexFile::FieldId);
1671 break;
1672 }
1673 case DexFile::kDexTypeMethodIdItem: {
1674 if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
1675 return false;
1676 }
1677 ptr_ += sizeof(DexFile::MethodId);
1678 break;
1679 }
1680 case DexFile::kDexTypeClassDefItem: {
1681 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
1682 return false;
1683 }
1684 ptr_ += sizeof(DexFile::ClassDef);
1685 break;
1686 }
1687 case DexFile::kDexTypeCallSiteIdItem: {
1688 if (!CheckListSize(ptr_, 1, sizeof(DexFile::CallSiteIdItem), "call_site_ids")) {
1689 return false;
1690 }
1691 ptr_ += sizeof(DexFile::CallSiteIdItem);
1692 break;
1693 }
1694 case DexFile::kDexTypeMethodHandleItem: {
1695 if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodHandleItem), "method_handles")) {
1696 return false;
1697 }
1698 ptr_ += sizeof(DexFile::MethodHandleItem);
1699 break;
1700 }
1701 case DexFile::kDexTypeTypeList: {
1702 if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
1703 return false;
1704 }
1705 break;
1706 }
1707 case DexFile::kDexTypeAnnotationSetRefList: {
1708 if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
1709 return false;
1710 }
1711 break;
1712 }
1713 case DexFile::kDexTypeAnnotationSetItem: {
1714 if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
1715 return false;
1716 }
1717 break;
1718 }
1719 case DexFile::kDexTypeClassDataItem: {
1720 if (!CheckIntraClassDataItem()) {
1721 return false;
1722 }
1723 break;
1724 }
1725 case DexFile::kDexTypeCodeItem: {
1726 if (!CheckIntraCodeItem()) {
1727 return false;
1728 }
1729 break;
1730 }
1731 case DexFile::kDexTypeStringDataItem: {
1732 if (!CheckIntraStringDataItem()) {
1733 return false;
1734 }
1735 break;
1736 }
1737 case DexFile::kDexTypeDebugInfoItem: {
1738 if (!CheckIntraDebugInfoItem()) {
1739 return false;
1740 }
1741 break;
1742 }
1743 case DexFile::kDexTypeAnnotationItem: {
1744 if (!CheckIntraAnnotationItem()) {
1745 return false;
1746 }
1747 break;
1748 }
1749 case DexFile::kDexTypeEncodedArrayItem: {
1750 if (!CheckEncodedArray()) {
1751 return false;
1752 }
1753 break;
1754 }
1755 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1756 if (!CheckIntraAnnotationsDirectoryItem()) {
1757 return false;
1758 }
1759 break;
1760 }
1761 case DexFile::kDexTypeHeaderItem:
1762 case DexFile::kDexTypeMapList:
1763 break;
1764 }
1765
1766 if (start_ptr == ptr_) {
1767 ErrorStringPrintf("Unknown map item type %x", type);
1768 return false;
1769 }
1770
1771 if (IsDataSectionType(type)) {
1772 if (aligned_offset == 0u) {
1773 ErrorStringPrintf("Item %d offset is 0", i);
1774 return false;
1775 }
1776 DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
1777 offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
1778 }
1779
1780 aligned_offset = ptr_ - begin_;
1781 if (UNLIKELY(aligned_offset > size_)) {
1782 ErrorStringPrintf("Item %d at ends out of bounds", i);
1783 return false;
1784 }
1785
1786 offset = aligned_offset;
1787 }
1788
1789 return true;
1790 }
1791
CheckIntraIdSection(size_t offset,uint32_t count,DexFile::MapItemType type)1792 bool DexFileVerifier::CheckIntraIdSection(size_t offset,
1793 uint32_t count,
1794 DexFile::MapItemType type) {
1795 uint32_t expected_offset;
1796 uint32_t expected_size;
1797
1798 // Get the expected offset and size from the header.
1799 switch (type) {
1800 case DexFile::kDexTypeStringIdItem:
1801 expected_offset = header_->string_ids_off_;
1802 expected_size = header_->string_ids_size_;
1803 break;
1804 case DexFile::kDexTypeTypeIdItem:
1805 expected_offset = header_->type_ids_off_;
1806 expected_size = header_->type_ids_size_;
1807 break;
1808 case DexFile::kDexTypeProtoIdItem:
1809 expected_offset = header_->proto_ids_off_;
1810 expected_size = header_->proto_ids_size_;
1811 break;
1812 case DexFile::kDexTypeFieldIdItem:
1813 expected_offset = header_->field_ids_off_;
1814 expected_size = header_->field_ids_size_;
1815 break;
1816 case DexFile::kDexTypeMethodIdItem:
1817 expected_offset = header_->method_ids_off_;
1818 expected_size = header_->method_ids_size_;
1819 break;
1820 case DexFile::kDexTypeClassDefItem:
1821 expected_offset = header_->class_defs_off_;
1822 expected_size = header_->class_defs_size_;
1823 break;
1824 default:
1825 ErrorStringPrintf("Bad type for id section: %x", type);
1826 return false;
1827 }
1828
1829 // Check that the offset and size are what were expected from the header.
1830 if (UNLIKELY(offset != expected_offset)) {
1831 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
1832 return false;
1833 }
1834 if (UNLIKELY(count != expected_size)) {
1835 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
1836 return false;
1837 }
1838
1839 return CheckIntraSectionIterate(offset, count, type);
1840 }
1841
CheckIntraDataSection(size_t offset,uint32_t count,DexFile::MapItemType type)1842 bool DexFileVerifier::CheckIntraDataSection(size_t offset,
1843 uint32_t count,
1844 DexFile::MapItemType type) {
1845 size_t data_start = header_->data_off_;
1846 size_t data_end = data_start + header_->data_size_;
1847
1848 // Sanity check the offset of the section.
1849 if (UNLIKELY((offset < data_start) || (offset > data_end))) {
1850 ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
1851 return false;
1852 }
1853
1854 if (!CheckIntraSectionIterate(offset, count, type)) {
1855 return false;
1856 }
1857
1858 size_t next_offset = ptr_ - begin_;
1859 if (next_offset > data_end) {
1860 ErrorStringPrintf("Out-of-bounds end of data subsection: %zu data_off=%u data_size=%u",
1861 next_offset,
1862 header_->data_off_,
1863 header_->data_size_);
1864 return false;
1865 }
1866
1867 return true;
1868 }
1869
CheckIntraSection()1870 bool DexFileVerifier::CheckIntraSection() {
1871 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
1872 const DexFile::MapItem* item = map->list_;
1873 size_t offset = 0;
1874 uint32_t count = map->size_;
1875 ptr_ = begin_;
1876
1877 // Check the items listed in the map.
1878 while (count--) {
1879 const size_t current_offset = offset;
1880 uint32_t section_offset = item->offset_;
1881 uint32_t section_count = item->size_;
1882 DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
1883
1884 // Check for padding and overlap between items.
1885 if (!CheckPadding(offset, section_offset, type)) {
1886 return false;
1887 } else if (UNLIKELY(offset > section_offset)) {
1888 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
1889 return false;
1890 }
1891
1892 // Check each item based on its type.
1893 switch (type) {
1894 case DexFile::kDexTypeHeaderItem:
1895 if (UNLIKELY(section_count != 1)) {
1896 ErrorStringPrintf("Multiple header items");
1897 return false;
1898 }
1899 if (UNLIKELY(section_offset != 0)) {
1900 ErrorStringPrintf("Header at %x, not at start of file", section_offset);
1901 return false;
1902 }
1903 ptr_ = begin_ + header_->header_size_;
1904 offset = header_->header_size_;
1905 break;
1906 case DexFile::kDexTypeStringIdItem:
1907 case DexFile::kDexTypeTypeIdItem:
1908 case DexFile::kDexTypeProtoIdItem:
1909 case DexFile::kDexTypeFieldIdItem:
1910 case DexFile::kDexTypeMethodIdItem:
1911 case DexFile::kDexTypeClassDefItem:
1912 if (!CheckIntraIdSection(section_offset, section_count, type)) {
1913 return false;
1914 }
1915 offset = ptr_ - begin_;
1916 break;
1917 case DexFile::kDexTypeMapList:
1918 if (UNLIKELY(section_count != 1)) {
1919 ErrorStringPrintf("Multiple map list items");
1920 return false;
1921 }
1922 if (UNLIKELY(section_offset != header_->map_off_)) {
1923 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1924 section_offset, header_->map_off_);
1925 return false;
1926 }
1927 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1928 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1929 break;
1930 case DexFile::kDexTypeMethodHandleItem:
1931 case DexFile::kDexTypeCallSiteIdItem:
1932 CheckIntraSectionIterate(section_offset, section_count, type);
1933 offset = ptr_ - begin_;
1934 break;
1935 case DexFile::kDexTypeTypeList:
1936 case DexFile::kDexTypeAnnotationSetRefList:
1937 case DexFile::kDexTypeAnnotationSetItem:
1938 case DexFile::kDexTypeClassDataItem:
1939 case DexFile::kDexTypeCodeItem:
1940 case DexFile::kDexTypeStringDataItem:
1941 case DexFile::kDexTypeDebugInfoItem:
1942 case DexFile::kDexTypeAnnotationItem:
1943 case DexFile::kDexTypeEncodedArrayItem:
1944 case DexFile::kDexTypeAnnotationsDirectoryItem:
1945 if (!CheckIntraDataSection(section_offset, section_count, type)) {
1946 return false;
1947 }
1948 offset = ptr_ - begin_;
1949 break;
1950 }
1951
1952 if (offset == current_offset) {
1953 ErrorStringPrintf("Unknown map item type %x", type);
1954 return false;
1955 }
1956
1957 item++;
1958 }
1959
1960 return true;
1961 }
1962
CheckOffsetToTypeMap(size_t offset,uint16_t type)1963 bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
1964 DCHECK_NE(offset, 0u);
1965 auto it = offset_to_type_map_.Find(offset);
1966 if (UNLIKELY(it == offset_to_type_map_.end())) {
1967 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
1968 return false;
1969 }
1970 if (UNLIKELY(it->second != type)) {
1971 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
1972 offset, type, it->second);
1973 return false;
1974 }
1975 return true;
1976 }
1977
FindFirstClassDataDefiner(const uint8_t * ptr,bool * success)1978 dex::TypeIndex DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) {
1979 ClassDataItemIterator it(*dex_file_, ptr);
1980 *success = true;
1981
1982 if (it.HasNextStaticField() || it.HasNextInstanceField()) {
1983 LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
1984 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
1985 return field->class_idx_;
1986 }
1987
1988 if (it.HasNextMethod()) {
1989 LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
1990 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
1991 return method->class_idx_;
1992 }
1993
1994 return dex::TypeIndex(DexFile::kDexNoIndex16);
1995 }
1996
FindFirstAnnotationsDirectoryDefiner(const uint8_t * ptr,bool * success)1997 dex::TypeIndex DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr,
1998 bool* success) {
1999 const DexFile::AnnotationsDirectoryItem* item =
2000 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
2001 *success = true;
2002
2003 if (item->fields_size_ != 0) {
2004 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
2005 LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
2006 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
2007 return field->class_idx_;
2008 }
2009
2010 if (item->methods_size_ != 0) {
2011 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
2012 LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
2013 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
2014 return method->class_idx_;
2015 }
2016
2017 if (item->parameters_size_ != 0) {
2018 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
2019 LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
2020 *success = false; return dex::TypeIndex(DexFile::kDexNoIndex16))
2021 return method->class_idx_;
2022 }
2023
2024 return dex::TypeIndex(DexFile::kDexNoIndex16);
2025 }
2026
CheckInterStringIdItem()2027 bool DexFileVerifier::CheckInterStringIdItem() {
2028 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
2029
2030 // Check the map to make sure it has the right offset->type.
2031 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
2032 return false;
2033 }
2034
2035 // Check ordering between items.
2036 if (previous_item_ != nullptr) {
2037 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
2038 const char* prev_str = dex_file_->GetStringData(*prev_item);
2039 const char* str = dex_file_->GetStringData(*item);
2040 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
2041 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
2042 return false;
2043 }
2044 }
2045
2046 ptr_ += sizeof(DexFile::StringId);
2047 return true;
2048 }
2049
CheckInterTypeIdItem()2050 bool DexFileVerifier::CheckInterTypeIdItem() {
2051 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
2052
2053 LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
2054
2055 // Check that the descriptor is a valid type.
2056 if (UNLIKELY(!IsValidDescriptor(descriptor))) {
2057 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
2058 return false;
2059 }
2060
2061 // Check ordering between items.
2062 if (previous_item_ != nullptr) {
2063 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
2064 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
2065 ErrorStringPrintf("Out-of-order type_ids: %x then %x",
2066 prev_item->descriptor_idx_.index_,
2067 item->descriptor_idx_.index_);
2068 return false;
2069 }
2070 }
2071
2072 ptr_ += sizeof(DexFile::TypeId);
2073 return true;
2074 }
2075
CheckInterProtoIdItem()2076 bool DexFileVerifier::CheckInterProtoIdItem() {
2077 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
2078
2079 LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
2080
2081 if (item->parameters_off_ != 0 &&
2082 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
2083 return false;
2084 }
2085
2086 // Check that return type is representable as a uint16_t;
2087 if (UNLIKELY(!IsValidOrNoTypeId(item->return_type_idx_.index_, item->pad_))) {
2088 ErrorStringPrintf("proto with return type idx outside uint16_t range '%x:%x'",
2089 item->pad_, item->return_type_idx_.index_);
2090 return false;
2091 }
2092 // Check the return type and advance the shorty.
2093 LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
2094 if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
2095 return false;
2096 }
2097 shorty++;
2098
2099 DexFileParameterIterator it(*dex_file_, *item);
2100 while (it.HasNext() && *shorty != '\0') {
2101 if (!CheckIndex(it.GetTypeIdx().index_,
2102 dex_file_->NumTypeIds(),
2103 "inter_proto_id_item shorty type_idx")) {
2104 return false;
2105 }
2106 const char* descriptor = it.GetDescriptor();
2107 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
2108 return false;
2109 }
2110 it.Next();
2111 shorty++;
2112 }
2113 if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
2114 ErrorStringPrintf("Mismatched length for parameters and shorty");
2115 return false;
2116 }
2117
2118 // Check ordering between items. This relies on type_ids being in order.
2119 if (previous_item_ != nullptr) {
2120 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
2121 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
2122 ErrorStringPrintf("Out-of-order proto_id return types");
2123 return false;
2124 } else if (prev->return_type_idx_ == item->return_type_idx_) {
2125 DexFileParameterIterator curr_it(*dex_file_, *item);
2126 DexFileParameterIterator prev_it(*dex_file_, *prev);
2127
2128 while (curr_it.HasNext() && prev_it.HasNext()) {
2129 dex::TypeIndex prev_idx = prev_it.GetTypeIdx();
2130 dex::TypeIndex curr_idx = curr_it.GetTypeIdx();
2131 DCHECK_NE(prev_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
2132 DCHECK_NE(curr_idx, dex::TypeIndex(DexFile::kDexNoIndex16));
2133
2134 if (prev_idx < curr_idx) {
2135 break;
2136 } else if (UNLIKELY(prev_idx > curr_idx)) {
2137 ErrorStringPrintf("Out-of-order proto_id arguments");
2138 return false;
2139 }
2140
2141 prev_it.Next();
2142 curr_it.Next();
2143 }
2144 if (!curr_it.HasNext()) {
2145 // Either a duplicate ProtoId or a ProtoId with a shorter argument list follows
2146 // a ProtoId with a longer one. Both cases are forbidden by the specification.
2147 ErrorStringPrintf("Out-of-order proto_id arguments");
2148 return false;
2149 }
2150 }
2151 }
2152
2153 ptr_ += sizeof(DexFile::ProtoId);
2154 return true;
2155 }
2156
CheckInterFieldIdItem()2157 bool DexFileVerifier::CheckInterFieldIdItem() {
2158 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
2159
2160 // Check that the class descriptor is valid.
2161 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
2162 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
2163 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
2164 return false;
2165 }
2166
2167 // Check that the type descriptor is a valid field name.
2168 LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
2169 if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
2170 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
2171 return false;
2172 }
2173
2174 // Check that the name is valid.
2175 LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
2176 if (UNLIKELY(!IsValidMemberName(descriptor))) {
2177 ErrorStringPrintf("Invalid field name: '%s'", descriptor);
2178 return false;
2179 }
2180
2181 // Check ordering between items. This relies on the other sections being in order.
2182 if (previous_item_ != nullptr) {
2183 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
2184 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
2185 ErrorStringPrintf("Out-of-order field_ids");
2186 return false;
2187 } else if (prev_item->class_idx_ == item->class_idx_) {
2188 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
2189 ErrorStringPrintf("Out-of-order field_ids");
2190 return false;
2191 } else if (prev_item->name_idx_ == item->name_idx_) {
2192 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
2193 ErrorStringPrintf("Out-of-order field_ids");
2194 return false;
2195 }
2196 }
2197 }
2198 }
2199
2200 ptr_ += sizeof(DexFile::FieldId);
2201 return true;
2202 }
2203
CheckInterMethodIdItem()2204 bool DexFileVerifier::CheckInterMethodIdItem() {
2205 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
2206
2207 // Check that the class descriptor is a valid reference name.
2208 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
2209 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
2210 class_descriptor[0] != '['))) {
2211 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
2212 return false;
2213 }
2214
2215 // Check that the name is valid.
2216 LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
2217 if (UNLIKELY(!IsValidMemberName(descriptor))) {
2218 ErrorStringPrintf("Invalid method name: '%s'", descriptor);
2219 return false;
2220 }
2221
2222 // Check that the proto id is valid.
2223 if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
2224 "inter_method_id_item proto_idx"))) {
2225 return false;
2226 }
2227
2228 // Check ordering between items. This relies on the other sections being in order.
2229 if (previous_item_ != nullptr) {
2230 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
2231 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
2232 ErrorStringPrintf("Out-of-order method_ids");
2233 return false;
2234 } else if (prev_item->class_idx_ == item->class_idx_) {
2235 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
2236 ErrorStringPrintf("Out-of-order method_ids");
2237 return false;
2238 } else if (prev_item->name_idx_ == item->name_idx_) {
2239 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
2240 ErrorStringPrintf("Out-of-order method_ids");
2241 return false;
2242 }
2243 }
2244 }
2245 }
2246
2247 ptr_ += sizeof(DexFile::MethodId);
2248 return true;
2249 }
2250
CheckInterClassDefItem()2251 bool DexFileVerifier::CheckInterClassDefItem() {
2252 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
2253
2254 // Check that class_idx_ is representable as a uint16_t;
2255 if (UNLIKELY(!IsValidTypeId(item->class_idx_.index_, item->pad1_))) {
2256 ErrorStringPrintf("class with type idx outside uint16_t range '%x:%x'", item->pad1_,
2257 item->class_idx_.index_);
2258 return false;
2259 }
2260 // Check that superclass_idx_ is representable as a uint16_t;
2261 if (UNLIKELY(!IsValidOrNoTypeId(item->superclass_idx_.index_, item->pad2_))) {
2262 ErrorStringPrintf("class with superclass type idx outside uint16_t range '%x:%x'", item->pad2_,
2263 item->superclass_idx_.index_);
2264 return false;
2265 }
2266 // Check for duplicate class def.
2267 if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
2268 ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_.index_);
2269 return false;
2270 }
2271 defined_classes_.insert(item->class_idx_);
2272
2273 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
2274 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
2275 ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
2276 return false;
2277 }
2278
2279 // Only allow non-runtime modifiers.
2280 if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
2281 ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
2282 return false;
2283 }
2284
2285 if (item->interfaces_off_ != 0 &&
2286 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
2287 return false;
2288 }
2289 if (item->annotations_off_ != 0 &&
2290 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
2291 return false;
2292 }
2293 if (item->class_data_off_ != 0 &&
2294 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
2295 return false;
2296 }
2297 if (item->static_values_off_ != 0 &&
2298 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
2299 return false;
2300 }
2301
2302 if (item->superclass_idx_.IsValid()) {
2303 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2304 // Check that a class does not inherit from itself directly (by having
2305 // the same type idx as its super class).
2306 if (UNLIKELY(item->superclass_idx_ == item->class_idx_)) {
2307 ErrorStringPrintf("Class with same type idx as its superclass: '%d'",
2308 item->class_idx_.index_);
2309 return false;
2310 }
2311
2312 // Check that a class is defined after its super class (if the
2313 // latter is defined in the same Dex file).
2314 const DexFile::ClassDef* superclass_def = dex_file_->FindClassDef(item->superclass_idx_);
2315 if (superclass_def != nullptr) {
2316 // The superclass is defined in this Dex file.
2317 if (superclass_def > item) {
2318 // ClassDef item for super class appearing after the class' ClassDef item.
2319 ErrorStringPrintf("Invalid class definition ordering:"
2320 " class with type idx: '%d' defined before"
2321 " superclass with type idx: '%d'",
2322 item->class_idx_.index_,
2323 item->superclass_idx_.index_);
2324 return false;
2325 }
2326 }
2327 }
2328
2329 LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
2330 "inter_class_def_item superclass_idx")
2331 if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
2332 ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
2333 return false;
2334 }
2335 }
2336
2337 // Check interfaces.
2338 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
2339 if (interfaces != nullptr) {
2340 uint32_t size = interfaces->Size();
2341 for (uint32_t i = 0; i < size; i++) {
2342 if (header_->GetVersion() >= DexFile::kClassDefinitionOrderEnforcedVersion) {
2343 // Check that a class does not implement itself directly (by having the
2344 // same type idx as one of its immediate implemented interfaces).
2345 if (UNLIKELY(interfaces->GetTypeItem(i).type_idx_ == item->class_idx_)) {
2346 ErrorStringPrintf("Class with same type idx as implemented interface: '%d'",
2347 item->class_idx_.index_);
2348 return false;
2349 }
2350
2351 // Check that a class is defined after the interfaces it implements
2352 // (if they are defined in the same Dex file).
2353 const DexFile::ClassDef* interface_def =
2354 dex_file_->FindClassDef(interfaces->GetTypeItem(i).type_idx_);
2355 if (interface_def != nullptr) {
2356 // The interface is defined in this Dex file.
2357 if (interface_def > item) {
2358 // ClassDef item for interface appearing after the class' ClassDef item.
2359 ErrorStringPrintf("Invalid class definition ordering:"
2360 " class with type idx: '%d' defined before"
2361 " implemented interface with type idx: '%d'",
2362 item->class_idx_.index_,
2363 interfaces->GetTypeItem(i).type_idx_.index_);
2364 return false;
2365 }
2366 }
2367 }
2368
2369 // Ensure that the interface refers to a class (not an array nor a primitive type).
2370 LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
2371 "inter_class_def_item interface type_idx")
2372 if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
2373 ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
2374 return false;
2375 }
2376 }
2377
2378 /*
2379 * Ensure that there are no duplicates. This is an O(N^2) test, but in
2380 * practice the number of interfaces implemented by any given class is low.
2381 */
2382 for (uint32_t i = 1; i < size; i++) {
2383 dex::TypeIndex idx1 = interfaces->GetTypeItem(i).type_idx_;
2384 for (uint32_t j =0; j < i; j++) {
2385 dex::TypeIndex idx2 = interfaces->GetTypeItem(j).type_idx_;
2386 if (UNLIKELY(idx1 == idx2)) {
2387 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
2388 return false;
2389 }
2390 }
2391 }
2392 }
2393
2394 // Check that references in class_data_item are to the right class.
2395 if (item->class_data_off_ != 0) {
2396 const uint8_t* data = begin_ + item->class_data_off_;
2397 bool success;
2398 dex::TypeIndex data_definer = FindFirstClassDataDefiner(data, &success);
2399 if (!success) {
2400 return false;
2401 }
2402 if (UNLIKELY((data_definer != item->class_idx_) &&
2403 (data_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
2404 ErrorStringPrintf("Invalid class_data_item");
2405 return false;
2406 }
2407 }
2408
2409 // Check that references in annotations_directory_item are to right class.
2410 if (item->annotations_off_ != 0) {
2411 // annotations_off_ is supposed to be aligned by 4.
2412 if (!IsAlignedParam(item->annotations_off_, 4)) {
2413 ErrorStringPrintf("Invalid annotations_off_, not aligned by 4");
2414 return false;
2415 }
2416 const uint8_t* data = begin_ + item->annotations_off_;
2417 bool success;
2418 dex::TypeIndex annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
2419 if (!success) {
2420 return false;
2421 }
2422 if (UNLIKELY((annotations_definer != item->class_idx_) &&
2423 (annotations_definer != dex::TypeIndex(DexFile::kDexNoIndex16)))) {
2424 ErrorStringPrintf("Invalid annotations_directory_item");
2425 return false;
2426 }
2427 }
2428
2429 ptr_ += sizeof(DexFile::ClassDef);
2430 return true;
2431 }
2432
CheckInterCallSiteIdItem()2433 bool DexFileVerifier::CheckInterCallSiteIdItem() {
2434 const DexFile::CallSiteIdItem* item = reinterpret_cast<const DexFile::CallSiteIdItem*>(ptr_);
2435
2436 // Check call site referenced by item is in encoded array section.
2437 if (!CheckOffsetToTypeMap(item->data_off_, DexFile::kDexTypeEncodedArrayItem)) {
2438 ErrorStringPrintf("Invalid offset in CallSideIdItem");
2439 return false;
2440 }
2441
2442 CallSiteArrayValueIterator it(*dex_file_, *item);
2443
2444 // Check Method Handle
2445 if (!it.HasNext() || it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodHandle) {
2446 ErrorStringPrintf("CallSiteArray missing method handle");
2447 return false;
2448 }
2449
2450 uint32_t handle_index = static_cast<uint32_t>(it.GetJavaValue().i);
2451 if (handle_index >= dex_file_->NumMethodHandles()) {
2452 ErrorStringPrintf("CallSite has bad method handle id: %x", handle_index);
2453 return false;
2454 }
2455
2456 // Check target method name.
2457 it.Next();
2458 if (!it.HasNext() ||
2459 it.GetValueType() != EncodedArrayValueIterator::ValueType::kString) {
2460 ErrorStringPrintf("CallSiteArray missing target method name");
2461 return false;
2462 }
2463
2464 uint32_t name_index = static_cast<uint32_t>(it.GetJavaValue().i);
2465 if (name_index >= dex_file_->NumStringIds()) {
2466 ErrorStringPrintf("CallSite has bad method name id: %x", name_index);
2467 return false;
2468 }
2469
2470 // Check method type.
2471 it.Next();
2472 if (!it.HasNext() ||
2473 it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodType) {
2474 ErrorStringPrintf("CallSiteArray missing method type");
2475 return false;
2476 }
2477
2478 uint32_t proto_index = static_cast<uint32_t>(it.GetJavaValue().i);
2479 if (proto_index >= dex_file_->NumProtoIds()) {
2480 ErrorStringPrintf("CallSite has bad method type: %x", proto_index);
2481 return false;
2482 }
2483
2484 ptr_ += sizeof(DexFile::CallSiteIdItem);
2485 return true;
2486 }
2487
CheckInterMethodHandleItem()2488 bool DexFileVerifier::CheckInterMethodHandleItem() {
2489 const DexFile::MethodHandleItem* item = reinterpret_cast<const DexFile::MethodHandleItem*>(ptr_);
2490
2491 DexFile::MethodHandleType method_handle_type =
2492 static_cast<DexFile::MethodHandleType>(item->method_handle_type_);
2493 if (method_handle_type > DexFile::MethodHandleType::kLast) {
2494 ErrorStringPrintf("Bad method handle type %x", item->method_handle_type_);
2495 return false;
2496 }
2497
2498 uint32_t index = item->field_or_method_idx_;
2499 switch (method_handle_type) {
2500 case DexFile::MethodHandleType::kStaticPut:
2501 case DexFile::MethodHandleType::kStaticGet:
2502 case DexFile::MethodHandleType::kInstancePut:
2503 case DexFile::MethodHandleType::kInstanceGet: {
2504 LOAD_FIELD(field, index, "method_handle_item field_idx", return false);
2505 break;
2506 }
2507 case DexFile::MethodHandleType::kInvokeStatic:
2508 case DexFile::MethodHandleType::kInvokeInstance:
2509 case DexFile::MethodHandleType::kInvokeConstructor:
2510 case DexFile::MethodHandleType::kInvokeDirect:
2511 case DexFile::MethodHandleType::kInvokeInterface: {
2512 LOAD_METHOD(method, index, "method_handle_item method_idx", return false);
2513 break;
2514 }
2515 }
2516
2517 ptr_ += sizeof(DexFile::MethodHandleItem);
2518 return true;
2519 }
2520
CheckInterAnnotationSetRefList()2521 bool DexFileVerifier::CheckInterAnnotationSetRefList() {
2522 const DexFile::AnnotationSetRefList* list =
2523 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
2524 const DexFile::AnnotationSetRefItem* item = list->list_;
2525 uint32_t count = list->size_;
2526
2527 while (count--) {
2528 if (item->annotations_off_ != 0 &&
2529 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2530 return false;
2531 }
2532 item++;
2533 }
2534
2535 ptr_ = reinterpret_cast<const uint8_t*>(item);
2536 return true;
2537 }
2538
CheckInterAnnotationSetItem()2539 bool DexFileVerifier::CheckInterAnnotationSetItem() {
2540 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
2541 const uint32_t* offsets = set->entries_;
2542 uint32_t count = set->size_;
2543 uint32_t last_idx = 0;
2544
2545 for (uint32_t i = 0; i < count; i++) {
2546 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
2547 return false;
2548 }
2549
2550 // Get the annotation from the offset and the type index for the annotation.
2551 const DexFile::AnnotationItem* annotation =
2552 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
2553 const uint8_t* data = annotation->annotation_;
2554 DECODE_UNSIGNED_CHECKED_FROM(data, idx);
2555
2556 if (UNLIKELY(last_idx >= idx && i != 0)) {
2557 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
2558 return false;
2559 }
2560
2561 last_idx = idx;
2562 offsets++;
2563 }
2564
2565 ptr_ = reinterpret_cast<const uint8_t*>(offsets);
2566 return true;
2567 }
2568
CheckInterClassDataItem()2569 bool DexFileVerifier::CheckInterClassDataItem() {
2570 ClassDataItemIterator it(*dex_file_, ptr_);
2571 bool success;
2572 dex::TypeIndex defining_class = FindFirstClassDataDefiner(ptr_, &success);
2573 if (!success) {
2574 return false;
2575 }
2576
2577 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
2578 LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
2579 if (UNLIKELY(field->class_idx_ != defining_class)) {
2580 ErrorStringPrintf("Mismatched defining class for class_data_item field");
2581 return false;
2582 }
2583 }
2584 for (; it.HasNextMethod(); it.Next()) {
2585 uint32_t code_off = it.GetMethodCodeItemOffset();
2586 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
2587 return false;
2588 }
2589 LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
2590 if (UNLIKELY(method->class_idx_ != defining_class)) {
2591 ErrorStringPrintf("Mismatched defining class for class_data_item method");
2592 return false;
2593 }
2594 }
2595
2596 ptr_ = it.EndDataPointer();
2597 return true;
2598 }
2599
CheckInterAnnotationsDirectoryItem()2600 bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
2601 const DexFile::AnnotationsDirectoryItem* item =
2602 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
2603 bool success;
2604 dex::TypeIndex defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
2605 if (!success) {
2606 return false;
2607 }
2608
2609 if (item->class_annotations_off_ != 0 &&
2610 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2611 return false;
2612 }
2613
2614 // Field annotations follow immediately after the annotations directory.
2615 const DexFile::FieldAnnotationsItem* field_item =
2616 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
2617 uint32_t field_count = item->fields_size_;
2618 for (uint32_t i = 0; i < field_count; i++) {
2619 LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
2620 return false)
2621 if (UNLIKELY(field->class_idx_ != defining_class)) {
2622 ErrorStringPrintf("Mismatched defining class for field_annotation");
2623 return false;
2624 }
2625 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2626 return false;
2627 }
2628 field_item++;
2629 }
2630
2631 // Method annotations follow immediately after field annotations.
2632 const DexFile::MethodAnnotationsItem* method_item =
2633 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
2634 uint32_t method_count = item->methods_size_;
2635 for (uint32_t i = 0; i < method_count; i++) {
2636 LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
2637 return false)
2638 if (UNLIKELY(method->class_idx_ != defining_class)) {
2639 ErrorStringPrintf("Mismatched defining class for method_annotation");
2640 return false;
2641 }
2642 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2643 return false;
2644 }
2645 method_item++;
2646 }
2647
2648 // Parameter annotations follow immediately after method annotations.
2649 const DexFile::ParameterAnnotationsItem* parameter_item =
2650 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
2651 uint32_t parameter_count = item->parameters_size_;
2652 for (uint32_t i = 0; i < parameter_count; i++) {
2653 LOAD_METHOD(parameter_method, parameter_item->method_idx_,
2654 "inter_annotations_directory_item parameter method_id", return false)
2655 if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
2656 ErrorStringPrintf("Mismatched defining class for parameter_annotation");
2657 return false;
2658 }
2659 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
2660 DexFile::kDexTypeAnnotationSetRefList)) {
2661 return false;
2662 }
2663 parameter_item++;
2664 }
2665
2666 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
2667 return true;
2668 }
2669
CheckInterSectionIterate(size_t offset,uint32_t count,DexFile::MapItemType type)2670 bool DexFileVerifier::CheckInterSectionIterate(size_t offset,
2671 uint32_t count,
2672 DexFile::MapItemType type) {
2673 // Get the right alignment mask for the type of section.
2674 size_t alignment_mask;
2675 switch (type) {
2676 case DexFile::kDexTypeClassDataItem:
2677 alignment_mask = sizeof(uint8_t) - 1;
2678 break;
2679 default:
2680 alignment_mask = sizeof(uint32_t) - 1;
2681 break;
2682 }
2683
2684 // Iterate through the items in the section.
2685 previous_item_ = nullptr;
2686 for (uint32_t i = 0; i < count; i++) {
2687 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
2688 ptr_ = begin_ + new_offset;
2689 const uint8_t* prev_ptr = ptr_;
2690
2691 if (MapTypeToBitMask(type) == 0) {
2692 ErrorStringPrintf("Unknown map item type %x", type);
2693 return false;
2694 }
2695
2696 // Check depending on the section type.
2697 switch (type) {
2698 case DexFile::kDexTypeHeaderItem:
2699 case DexFile::kDexTypeMapList:
2700 case DexFile::kDexTypeTypeList:
2701 case DexFile::kDexTypeCodeItem:
2702 case DexFile::kDexTypeStringDataItem:
2703 case DexFile::kDexTypeDebugInfoItem:
2704 case DexFile::kDexTypeAnnotationItem:
2705 case DexFile::kDexTypeEncodedArrayItem:
2706 break;
2707 case DexFile::kDexTypeStringIdItem: {
2708 if (!CheckInterStringIdItem()) {
2709 return false;
2710 }
2711 break;
2712 }
2713 case DexFile::kDexTypeTypeIdItem: {
2714 if (!CheckInterTypeIdItem()) {
2715 return false;
2716 }
2717 break;
2718 }
2719 case DexFile::kDexTypeProtoIdItem: {
2720 if (!CheckInterProtoIdItem()) {
2721 return false;
2722 }
2723 break;
2724 }
2725 case DexFile::kDexTypeFieldIdItem: {
2726 if (!CheckInterFieldIdItem()) {
2727 return false;
2728 }
2729 break;
2730 }
2731 case DexFile::kDexTypeMethodIdItem: {
2732 if (!CheckInterMethodIdItem()) {
2733 return false;
2734 }
2735 break;
2736 }
2737 case DexFile::kDexTypeClassDefItem: {
2738 // There shouldn't be more class definitions than type ids allow.
2739 // This check should be redundant, since there are checks that the
2740 // class_idx_ is within range and that there is only one definition
2741 // for a given type id.
2742 if (i > kTypeIdLimit) {
2743 ErrorStringPrintf("Too many class definition items");
2744 return false;
2745 }
2746 if (!CheckInterClassDefItem()) {
2747 return false;
2748 }
2749 break;
2750 }
2751 case DexFile::kDexTypeCallSiteIdItem: {
2752 if (!CheckInterCallSiteIdItem()) {
2753 return false;
2754 }
2755 break;
2756 }
2757 case DexFile::kDexTypeMethodHandleItem: {
2758 if (!CheckInterMethodHandleItem()) {
2759 return false;
2760 }
2761 break;
2762 }
2763 case DexFile::kDexTypeAnnotationSetRefList: {
2764 if (!CheckInterAnnotationSetRefList()) {
2765 return false;
2766 }
2767 break;
2768 }
2769 case DexFile::kDexTypeAnnotationSetItem: {
2770 if (!CheckInterAnnotationSetItem()) {
2771 return false;
2772 }
2773 break;
2774 }
2775 case DexFile::kDexTypeClassDataItem: {
2776 // There shouldn't be more class data than type ids allow.
2777 // This check should be redundant, since there are checks that the
2778 // class_idx_ is within range and that there is only one definition
2779 // for a given type id.
2780 if (i > kTypeIdLimit) {
2781 ErrorStringPrintf("Too many class data items");
2782 return false;
2783 }
2784 if (!CheckInterClassDataItem()) {
2785 return false;
2786 }
2787 break;
2788 }
2789 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2790 if (!CheckInterAnnotationsDirectoryItem()) {
2791 return false;
2792 }
2793 break;
2794 }
2795 }
2796
2797 previous_item_ = prev_ptr;
2798 offset = ptr_ - begin_;
2799 }
2800
2801 return true;
2802 }
2803
CheckInterSection()2804 bool DexFileVerifier::CheckInterSection() {
2805 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
2806 const DexFile::MapItem* item = map->list_;
2807 uint32_t count = map->size_;
2808
2809 // Cross check the items listed in the map.
2810 while (count--) {
2811 uint32_t section_offset = item->offset_;
2812 uint32_t section_count = item->size_;
2813 DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
2814 bool found = false;
2815
2816 switch (type) {
2817 case DexFile::kDexTypeHeaderItem:
2818 case DexFile::kDexTypeMapList:
2819 case DexFile::kDexTypeTypeList:
2820 case DexFile::kDexTypeCodeItem:
2821 case DexFile::kDexTypeStringDataItem:
2822 case DexFile::kDexTypeDebugInfoItem:
2823 case DexFile::kDexTypeAnnotationItem:
2824 case DexFile::kDexTypeEncodedArrayItem:
2825 found = true;
2826 break;
2827 case DexFile::kDexTypeStringIdItem:
2828 case DexFile::kDexTypeTypeIdItem:
2829 case DexFile::kDexTypeProtoIdItem:
2830 case DexFile::kDexTypeFieldIdItem:
2831 case DexFile::kDexTypeMethodIdItem:
2832 case DexFile::kDexTypeClassDefItem:
2833 case DexFile::kDexTypeCallSiteIdItem:
2834 case DexFile::kDexTypeMethodHandleItem:
2835 case DexFile::kDexTypeAnnotationSetRefList:
2836 case DexFile::kDexTypeAnnotationSetItem:
2837 case DexFile::kDexTypeClassDataItem:
2838 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2839 if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2840 return false;
2841 }
2842 found = true;
2843 break;
2844 }
2845 }
2846
2847 if (!found) {
2848 ErrorStringPrintf("Unknown map item type %x", item->type_);
2849 return false;
2850 }
2851
2852 item++;
2853 }
2854
2855 return true;
2856 }
2857
Verify()2858 bool DexFileVerifier::Verify() {
2859 // Check the header.
2860 if (!CheckHeader()) {
2861 return false;
2862 }
2863
2864 // Check the map section.
2865 if (!CheckMap()) {
2866 return false;
2867 }
2868
2869 // Check structure within remaining sections.
2870 if (!CheckIntraSection()) {
2871 return false;
2872 }
2873
2874 // Check references from one section to another.
2875 if (!CheckInterSection()) {
2876 return false;
2877 }
2878
2879 return true;
2880 }
2881
ErrorStringPrintf(const char * fmt,...)2882 void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2883 va_list ap;
2884 va_start(ap, fmt);
2885 DCHECK(failure_reason_.empty()) << failure_reason_;
2886 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2887 StringAppendV(&failure_reason_, fmt, ap);
2888 va_end(ap);
2889 }
2890
2891 // Fields and methods may have only one of public/protected/private.
CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags)2892 static bool CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags) {
2893 size_t count = (((flags & kAccPublic) == 0) ? 0 : 1) +
2894 (((flags & kAccProtected) == 0) ? 0 : 1) +
2895 (((flags & kAccPrivate) == 0) ? 0 : 1);
2896 return count <= 1;
2897 }
2898
2899 // Helper functions to retrieve names from the dex file. We do not want to rely on DexFile
2900 // functionality, as we're still verifying the dex file. begin and header correspond to the
2901 // underscored variants in the DexFileVerifier.
2902
GetStringOrError(const uint8_t * const begin,const DexFile::Header * const header,dex::StringIndex string_idx)2903 static std::string GetStringOrError(const uint8_t* const begin,
2904 const DexFile::Header* const header,
2905 dex::StringIndex string_idx) {
2906 // The `string_idx` is not guaranteed to be valid yet.
2907 if (header->string_ids_size_ <= string_idx.index_) {
2908 return "(error)";
2909 }
2910
2911 const DexFile::StringId* string_id =
2912 reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_)
2913 + string_idx.index_;
2914
2915 // Assume that the data is OK at this point. String data has been checked at this point.
2916
2917 const uint8_t* ptr = begin + string_id->string_data_off_;
2918 uint32_t dummy;
2919 if (!DecodeUnsignedLeb128Checked(&ptr, begin + header->file_size_, &dummy)) {
2920 return "(error)";
2921 }
2922 return reinterpret_cast<const char*>(ptr);
2923 }
2924
GetClassOrError(const uint8_t * const begin,const DexFile::Header * const header,dex::TypeIndex class_idx)2925 static std::string GetClassOrError(const uint8_t* const begin,
2926 const DexFile::Header* const header,
2927 dex::TypeIndex class_idx) {
2928 // The `class_idx` is either `FieldId::class_idx_` or `MethodId::class_idx_` and
2929 // it has already been checked in `DexFileVerifier::CheckClassDataItemField()`
2930 // or `DexFileVerifier::CheckClassDataItemMethod()`, respectively, to match
2931 // a valid defining class.
2932 CHECK_LT(class_idx.index_, header->type_ids_size_);
2933
2934 const DexFile::TypeId* type_id =
2935 reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx.index_;
2936
2937 // Assume that the data is OK at this point. Type id offsets have been checked at this point.
2938
2939 return GetStringOrError(begin, header, type_id->descriptor_idx_);
2940 }
2941
GetFieldDescriptionOrError(const uint8_t * const begin,const DexFile::Header * const header,uint32_t idx)2942 static std::string GetFieldDescriptionOrError(const uint8_t* const begin,
2943 const DexFile::Header* const header,
2944 uint32_t idx) {
2945 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemField()`.
2946 CHECK_LT(idx, header->field_ids_size_);
2947
2948 const DexFile::FieldId* field_id =
2949 reinterpret_cast<const DexFile::FieldId*>(begin + header->field_ids_off_) + idx;
2950
2951 // Assume that the data is OK at this point. Field id offsets have been checked at this point.
2952
2953 std::string class_name = GetClassOrError(begin, header, field_id->class_idx_);
2954 std::string field_name = GetStringOrError(begin, header, field_id->name_idx_);
2955
2956 return class_name + "." + field_name;
2957 }
2958
GetMethodDescriptionOrError(const uint8_t * const begin,const DexFile::Header * const header,uint32_t idx)2959 static std::string GetMethodDescriptionOrError(const uint8_t* const begin,
2960 const DexFile::Header* const header,
2961 uint32_t idx) {
2962 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemMethod()`.
2963 CHECK_LT(idx, header->method_ids_size_);
2964
2965 const DexFile::MethodId* method_id =
2966 reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) + idx;
2967
2968 // Assume that the data is OK at this point. Method id offsets have been checked at this point.
2969
2970 std::string class_name = GetClassOrError(begin, header, method_id->class_idx_);
2971 std::string method_name = GetStringOrError(begin, header, method_id->name_idx_);
2972
2973 return class_name + "." + method_name;
2974 }
2975
CheckFieldAccessFlags(uint32_t idx,uint32_t field_access_flags,uint32_t class_access_flags,std::string * error_msg)2976 bool DexFileVerifier::CheckFieldAccessFlags(uint32_t idx,
2977 uint32_t field_access_flags,
2978 uint32_t class_access_flags,
2979 std::string* error_msg) {
2980 // Generally sort out >16-bit flags.
2981 if ((field_access_flags & ~kAccJavaFlagsMask) != 0) {
2982 *error_msg = StringPrintf("Bad field access_flags for %s: %x(%s)",
2983 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2984 field_access_flags,
2985 PrettyJavaAccessFlags(field_access_flags).c_str());
2986 return false;
2987 }
2988
2989 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
2990 constexpr uint32_t kFieldAccessFlags = kAccPublic |
2991 kAccPrivate |
2992 kAccProtected |
2993 kAccStatic |
2994 kAccFinal |
2995 kAccVolatile |
2996 kAccTransient |
2997 kAccSynthetic |
2998 kAccEnum;
2999
3000 // Fields may have only one of public/protected/final.
3001 if (!CheckAtMostOneOfPublicProtectedPrivate(field_access_flags)) {
3002 *error_msg = StringPrintf("Field may have only one of public/protected/private, %s: %x(%s)",
3003 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
3004 field_access_flags,
3005 PrettyJavaAccessFlags(field_access_flags).c_str());
3006 return false;
3007 }
3008
3009 // Interfaces have a pretty restricted list.
3010 if ((class_access_flags & kAccInterface) != 0) {
3011 // Interface fields must be public final static.
3012 constexpr uint32_t kPublicFinalStatic = kAccPublic | kAccFinal | kAccStatic;
3013 if ((field_access_flags & kPublicFinalStatic) != kPublicFinalStatic) {
3014 *error_msg = StringPrintf("Interface field is not public final static, %s: %x(%s)",
3015 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
3016 field_access_flags,
3017 PrettyJavaAccessFlags(field_access_flags).c_str());
3018 if (dex_file_->SupportsDefaultMethods()) {
3019 return false;
3020 } else {
3021 // Allow in older versions, but warn.
3022 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3023 << *error_msg;
3024 }
3025 }
3026 // Interface fields may be synthetic, but may not have other flags.
3027 constexpr uint32_t kDisallowed = ~(kPublicFinalStatic | kAccSynthetic);
3028 if ((field_access_flags & kFieldAccessFlags & kDisallowed) != 0) {
3029 *error_msg = StringPrintf("Interface field has disallowed flag, %s: %x(%s)",
3030 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
3031 field_access_flags,
3032 PrettyJavaAccessFlags(field_access_flags).c_str());
3033 if (dex_file_->SupportsDefaultMethods()) {
3034 return false;
3035 } else {
3036 // Allow in older versions, but warn.
3037 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3038 << *error_msg;
3039 }
3040 }
3041 return true;
3042 }
3043
3044 // Volatile fields may not be final.
3045 constexpr uint32_t kVolatileFinal = kAccVolatile | kAccFinal;
3046 if ((field_access_flags & kVolatileFinal) == kVolatileFinal) {
3047 *error_msg = StringPrintf("Fields may not be volatile and final: %s",
3048 GetFieldDescriptionOrError(begin_, header_, idx).c_str());
3049 return false;
3050 }
3051
3052 return true;
3053 }
3054
CheckMethodAccessFlags(uint32_t method_index,uint32_t method_access_flags,uint32_t class_access_flags,uint32_t constructor_flags_by_name,bool has_code,bool expect_direct,std::string * error_msg)3055 bool DexFileVerifier::CheckMethodAccessFlags(uint32_t method_index,
3056 uint32_t method_access_flags,
3057 uint32_t class_access_flags,
3058 uint32_t constructor_flags_by_name,
3059 bool has_code,
3060 bool expect_direct,
3061 std::string* error_msg) {
3062 // Generally sort out >16-bit flags, except dex knows Constructor and DeclaredSynchronized.
3063 constexpr uint32_t kAllMethodFlags =
3064 kAccJavaFlagsMask | kAccConstructor | kAccDeclaredSynchronized;
3065 if ((method_access_flags & ~kAllMethodFlags) != 0) {
3066 *error_msg = StringPrintf("Bad method access_flags for %s: %x",
3067 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
3068 method_access_flags);
3069 return false;
3070 }
3071
3072 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
3073 constexpr uint32_t kMethodAccessFlags = kAccPublic |
3074 kAccPrivate |
3075 kAccProtected |
3076 kAccStatic |
3077 kAccFinal |
3078 kAccSynthetic |
3079 kAccSynchronized |
3080 kAccBridge |
3081 kAccVarargs |
3082 kAccNative |
3083 kAccAbstract |
3084 kAccStrict;
3085
3086 // Methods may have only one of public/protected/final.
3087 if (!CheckAtMostOneOfPublicProtectedPrivate(method_access_flags)) {
3088 *error_msg = StringPrintf("Method may have only one of public/protected/private, %s: %x",
3089 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
3090 method_access_flags);
3091 return false;
3092 }
3093
3094 constexpr uint32_t kConstructorFlags = kAccStatic | kAccConstructor;
3095 const bool is_constructor_by_name = (constructor_flags_by_name & kConstructorFlags) != 0;
3096 const bool is_clinit_by_name = constructor_flags_by_name == kConstructorFlags;
3097
3098 // Only methods named "<clinit>" or "<init>" may be marked constructor. Note: we cannot enforce
3099 // the reverse for backwards compatibility reasons.
3100 if (((method_access_flags & kAccConstructor) != 0) && !is_constructor_by_name) {
3101 *error_msg =
3102 StringPrintf("Method %" PRIu32 "(%s) is marked constructor, but doesn't match name",
3103 method_index,
3104 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3105 return false;
3106 }
3107
3108 if (is_constructor_by_name) {
3109 // Check that the static constructor (= static initializer) is named "<clinit>" and that the
3110 // instance constructor is called "<init>".
3111 bool is_static = (method_access_flags & kAccStatic) != 0;
3112 if (is_static ^ is_clinit_by_name) {
3113 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) is not flagged correctly wrt/ static.",
3114 method_index,
3115 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3116 if (dex_file_->SupportsDefaultMethods()) {
3117 return false;
3118 } else {
3119 // Allow in older versions, but warn.
3120 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3121 << *error_msg;
3122 }
3123 }
3124 }
3125
3126 // Check that static and private methods, as well as constructors, are in the direct methods list,
3127 // and other methods in the virtual methods list.
3128 bool is_direct = ((method_access_flags & (kAccStatic | kAccPrivate)) != 0) ||
3129 is_constructor_by_name;
3130 if (is_direct != expect_direct) {
3131 *error_msg = StringPrintf("Direct/virtual method %" PRIu32 "(%s) not in expected list %d",
3132 method_index,
3133 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
3134 expect_direct);
3135 return false;
3136 }
3137
3138 // From here on out it is easier to mask out the bits we're supposed to ignore.
3139 method_access_flags &= kMethodAccessFlags;
3140
3141 // Interfaces are special.
3142 if ((class_access_flags & kAccInterface) != 0) {
3143 // Non-static interface methods must be public or private.
3144 uint32_t desired_flags = (kAccPublic | kAccStatic);
3145 if (dex_file_->SupportsDefaultMethods()) {
3146 desired_flags |= kAccPrivate;
3147 }
3148 if ((method_access_flags & desired_flags) == 0) {
3149 *error_msg = StringPrintf("Interface virtual method %" PRIu32 "(%s) is not public",
3150 method_index,
3151 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3152 if (dex_file_->SupportsDefaultMethods()) {
3153 return false;
3154 } else {
3155 // Allow in older versions, but warn.
3156 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3157 << *error_msg;
3158 }
3159 }
3160 }
3161
3162 // If there aren't any instructions, make sure that's expected.
3163 if (!has_code) {
3164 // Only native or abstract methods may not have code.
3165 if ((method_access_flags & (kAccNative | kAccAbstract)) == 0) {
3166 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has no code, but is not marked native or "
3167 "abstract",
3168 method_index,
3169 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3170 return false;
3171 }
3172 // Constructors must always have code.
3173 if (is_constructor_by_name) {
3174 *error_msg = StringPrintf("Constructor %u(%s) must not be abstract or native",
3175 method_index,
3176 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3177 if (dex_file_->SupportsDefaultMethods()) {
3178 return false;
3179 } else {
3180 // Allow in older versions, but warn.
3181 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3182 << *error_msg;
3183 }
3184 }
3185 if ((method_access_flags & kAccAbstract) != 0) {
3186 // Abstract methods are not allowed to have the following flags.
3187 constexpr uint32_t kForbidden =
3188 kAccPrivate | kAccStatic | kAccFinal | kAccNative | kAccStrict | kAccSynchronized;
3189 if ((method_access_flags & kForbidden) != 0) {
3190 *error_msg = StringPrintf("Abstract method %" PRIu32 "(%s) has disallowed access flags %x",
3191 method_index,
3192 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
3193 method_access_flags);
3194 return false;
3195 }
3196 // Abstract methods should be in an abstract class or interface.
3197 if ((class_access_flags & (kAccInterface | kAccAbstract)) == 0) {
3198 LOG(WARNING) << "Method " << GetMethodDescriptionOrError(begin_, header_, method_index)
3199 << " is abstract, but the declaring class is neither abstract nor an "
3200 << "interface in dex file "
3201 << dex_file_->GetLocation();
3202 }
3203 }
3204 // Interfaces are special.
3205 if ((class_access_flags & kAccInterface) != 0) {
3206 // Interface methods without code must be abstract.
3207 if ((method_access_flags & (kAccPublic | kAccAbstract)) != (kAccPublic | kAccAbstract)) {
3208 *error_msg = StringPrintf("Interface method %" PRIu32 "(%s) is not public and abstract",
3209 method_index,
3210 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3211 if (dex_file_->SupportsDefaultMethods()) {
3212 return false;
3213 } else {
3214 // Allow in older versions, but warn.
3215 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
3216 << *error_msg;
3217 }
3218 }
3219 // At this point, we know the method is public and abstract. This means that all the checks
3220 // for invalid combinations above applies. In addition, interface methods must not be
3221 // protected. This is caught by the check for only-one-of-public-protected-private.
3222 }
3223 return true;
3224 }
3225
3226 // When there's code, the method must not be native or abstract.
3227 if ((method_access_flags & (kAccNative | kAccAbstract)) != 0) {
3228 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has code, but is marked native or abstract",
3229 method_index,
3230 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3231 return false;
3232 }
3233
3234 // Instance constructors must not be synchronized and a few other flags.
3235 if (constructor_flags_by_name == kAccConstructor) {
3236 static constexpr uint32_t kInitAllowed =
3237 kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic;
3238 if ((method_access_flags & ~kInitAllowed) != 0) {
3239 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) flagged inappropriately %x",
3240 method_index,
3241 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
3242 method_access_flags);
3243 return false;
3244 }
3245 }
3246
3247 return true;
3248 }
3249
CheckConstructorProperties(uint32_t method_index,uint32_t constructor_flags)3250 bool DexFileVerifier::CheckConstructorProperties(
3251 uint32_t method_index,
3252 uint32_t constructor_flags) {
3253 DCHECK(constructor_flags == kAccConstructor ||
3254 constructor_flags == (kAccConstructor | kAccStatic));
3255
3256 // Check signature matches expectations.
3257 const DexFile::MethodId* const method_id = CheckLoadMethodId(method_index,
3258 "Bad <init>/<clinit> method id");
3259 if (method_id == nullptr) {
3260 return false;
3261 }
3262
3263 // Check the ProtoId for the corresponding method.
3264 //
3265 // TODO(oth): the error message here is to satisfy the MethodId test
3266 // in the DexFileVerifierTest. The test is checking that the error
3267 // contains this string if the index is out of range.
3268 const DexFile::ProtoId* const proto_id = CheckLoadProtoId(method_id->proto_idx_,
3269 "inter_method_id_item proto_idx");
3270 if (proto_id == nullptr) {
3271 return false;
3272 }
3273
3274 Signature signature = dex_file_->GetMethodSignature(*method_id);
3275 if (constructor_flags == (kAccStatic | kAccConstructor)) {
3276 if (!signature.IsVoid() || signature.GetNumberOfParameters() != 0) {
3277 ErrorStringPrintf("<clinit> must have descriptor ()V");
3278 return false;
3279 }
3280 } else if (!signature.IsVoid()) {
3281 ErrorStringPrintf("Constructor %u(%s) must be void",
3282 method_index,
3283 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
3284 return false;
3285 }
3286
3287 return true;
3288 }
3289
3290 } // namespace art
3291