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