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