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