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