blob: bbffbbb7b728841bd2476b1f248976896b205ee5 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
jeffhao10037c82012-01-23 15:06:23 -080016
17#include "dex_file_verifier.h"
18
Andreas Gampee6215c02015-08-31 18:54:38 -070019#include <inttypes.h>
Narayan Kamath92572be2013-11-28 14:06:24 +000020#include <zlib.h>
Andreas Gampee6215c02015-08-31 18:54:38 -070021
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Narayan Kamath92572be2013-11-28 14:06:24 +000023
Elliott Hughese222ee02012-12-13 14:41:43 -080024#include "base/stringprintf.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070025#include "dex_file-inl.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070026#include "experimental_flags.h"
jeffhao10037c82012-01-23 15:06:23 -080027#include "leb128.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070028#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070029#include "safe_map.h"
Ian Rogersa6724902013-09-23 09:23:37 -070030#include "utf-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031#include "utils.h"
jeffhao10037c82012-01-23 15:06:23 -080032
33namespace art {
34
35static uint32_t MapTypeToBitMask(uint32_t map_type) {
36 switch (map_type) {
37 case DexFile::kDexTypeHeaderItem: return 1 << 0;
38 case DexFile::kDexTypeStringIdItem: return 1 << 1;
39 case DexFile::kDexTypeTypeIdItem: return 1 << 2;
40 case DexFile::kDexTypeProtoIdItem: return 1 << 3;
41 case DexFile::kDexTypeFieldIdItem: return 1 << 4;
42 case DexFile::kDexTypeMethodIdItem: return 1 << 5;
43 case DexFile::kDexTypeClassDefItem: return 1 << 6;
44 case DexFile::kDexTypeMapList: return 1 << 7;
45 case DexFile::kDexTypeTypeList: return 1 << 8;
46 case DexFile::kDexTypeAnnotationSetRefList: return 1 << 9;
47 case DexFile::kDexTypeAnnotationSetItem: return 1 << 10;
48 case DexFile::kDexTypeClassDataItem: return 1 << 11;
49 case DexFile::kDexTypeCodeItem: return 1 << 12;
50 case DexFile::kDexTypeStringDataItem: return 1 << 13;
51 case DexFile::kDexTypeDebugInfoItem: return 1 << 14;
52 case DexFile::kDexTypeAnnotationItem: return 1 << 15;
53 case DexFile::kDexTypeEncodedArrayItem: return 1 << 16;
54 case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 17;
55 }
56 return 0;
57}
58
59static bool IsDataSectionType(uint32_t map_type) {
60 switch (map_type) {
61 case DexFile::kDexTypeHeaderItem:
62 case DexFile::kDexTypeStringIdItem:
63 case DexFile::kDexTypeTypeIdItem:
64 case DexFile::kDexTypeProtoIdItem:
65 case DexFile::kDexTypeFieldIdItem:
66 case DexFile::kDexTypeMethodIdItem:
67 case DexFile::kDexTypeClassDefItem:
68 return false;
69 }
70 return true;
71}
72
Andreas Gampee09269c2014-06-06 18:45:35 -070073const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070074 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumStringIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070075 return nullptr;
76 }
77 return dex_file_->StringDataByIdx(idx);
78}
79
80const char* DexFileVerifier::CheckLoadStringByTypeIdx(uint32_t type_idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070081 if (UNLIKELY(!CheckIndex(type_idx, dex_file_->NumTypeIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070082 return nullptr;
83 }
84 const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx);
85 uint32_t idx = type_id.descriptor_idx_;
86 return CheckLoadStringByIdx(idx, error_string);
87}
88
89const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070090 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumFieldIds(), error_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070091 return nullptr;
92 }
93 return &dex_file_->GetFieldId(idx);
94}
95
96const DexFile::MethodId* DexFileVerifier::CheckLoadMethodId(uint32_t idx, const char* err_string) {
Andreas Gampedf10b322014-06-11 21:46:05 -070097 if (UNLIKELY(!CheckIndex(idx, dex_file_->NumMethodIds(), err_string))) {
Andreas Gampee09269c2014-06-06 18:45:35 -070098 return nullptr;
99 }
100 return &dex_file_->GetMethodId(idx);
101}
102
103// Helper macro to load string and return false on error.
104#define LOAD_STRING(var, idx, error) \
105 const char* var = CheckLoadStringByIdx(idx, error); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700106 if (UNLIKELY(var == nullptr)) { \
Andreas Gampee09269c2014-06-06 18:45:35 -0700107 return false; \
108 }
109
110// Helper macro to load string by type idx and return false on error.
111#define LOAD_STRING_BY_TYPE(var, type_idx, error) \
112 const char* var = CheckLoadStringByTypeIdx(type_idx, error); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700113 if (UNLIKELY(var == nullptr)) { \
Andreas Gampee09269c2014-06-06 18:45:35 -0700114 return false; \
115 }
116
117// Helper macro to load method id. Return last parameter on error.
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700118#define LOAD_METHOD(var, idx, error_string, error_stmt) \
Andreas Gampee09269c2014-06-06 18:45:35 -0700119 const DexFile::MethodId* var = CheckLoadMethodId(idx, error_string); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700120 if (UNLIKELY(var == nullptr)) { \
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700121 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700122 }
123
124// Helper macro to load method id. Return last parameter on error.
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700125#define LOAD_FIELD(var, idx, fmt, error_stmt) \
Andreas Gampee09269c2014-06-06 18:45:35 -0700126 const DexFile::FieldId* var = CheckLoadFieldId(idx, fmt); \
Andreas Gampedf10b322014-06-11 21:46:05 -0700127 if (UNLIKELY(var == nullptr)) { \
Andreas Gampe5e31dda2014-06-13 11:35:12 -0700128 error_stmt; \
Andreas Gampee09269c2014-06-06 18:45:35 -0700129 }
130
Ian Rogers13735952014-10-08 12:43:28 -0700131bool DexFileVerifier::Verify(const DexFile* dex_file, const uint8_t* begin, size_t size,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700132 const char* location, std::string* error_msg) {
Ian Rogers700a4022014-05-19 16:49:03 -0700133 std::unique_ptr<DexFileVerifier> verifier(new DexFileVerifier(dex_file, begin, size, location));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700134 if (!verifier->Verify()) {
135 *error_msg = verifier->FailureReason();
136 return false;
137 }
138 return true;
139}
140
141bool DexFileVerifier::CheckShortyDescriptorMatch(char shorty_char, const char* descriptor,
142 bool is_return_type) {
jeffhao10037c82012-01-23 15:06:23 -0800143 switch (shorty_char) {
144 case 'V':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700145 if (UNLIKELY(!is_return_type)) {
146 ErrorStringPrintf("Invalid use of void");
jeffhao10037c82012-01-23 15:06:23 -0800147 return false;
148 }
Ian Rogersfc787ec2014-10-09 21:56:44 -0700149 FALLTHROUGH_INTENDED;
jeffhao10037c82012-01-23 15:06:23 -0800150 case 'B':
151 case 'C':
152 case 'D':
153 case 'F':
154 case 'I':
155 case 'J':
156 case 'S':
157 case 'Z':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700158 if (UNLIKELY((descriptor[0] != shorty_char) || (descriptor[1] != '\0'))) {
159 ErrorStringPrintf("Shorty vs. primitive type mismatch: '%c', '%s'",
160 shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800161 return false;
162 }
163 break;
164 case 'L':
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700165 if (UNLIKELY((descriptor[0] != 'L') && (descriptor[0] != '['))) {
166 ErrorStringPrintf("Shorty vs. type mismatch: '%c', '%s'", shorty_char, descriptor);
jeffhao10037c82012-01-23 15:06:23 -0800167 return false;
168 }
169 break;
170 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700171 ErrorStringPrintf("Bad shorty character: '%c'", shorty_char);
jeffhao10037c82012-01-23 15:06:23 -0800172 return false;
173 }
174 return true;
175}
176
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700177bool DexFileVerifier::CheckListSize(const void* start, size_t count, size_t elem_size,
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700178 const char* label) {
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700179 // Check that size is not 0.
180 CHECK_NE(elem_size, 0U);
181
Ian Rogers13735952014-10-08 12:43:28 -0700182 const uint8_t* range_start = reinterpret_cast<const uint8_t*>(start);
183 const uint8_t* file_start = reinterpret_cast<const uint8_t*>(begin_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700184
185 // Check for overflow.
186 uintptr_t max = 0 - 1;
187 size_t available_bytes_till_end_of_mem = max - reinterpret_cast<uintptr_t>(start);
188 size_t max_count = available_bytes_till_end_of_mem / elem_size;
189 if (max_count < count) {
190 ErrorStringPrintf("Overflow in range for %s: %zx for %zu@%zu", label,
191 static_cast<size_t>(range_start - file_start),
192 count, elem_size);
193 return false;
194 }
195
Ian Rogers13735952014-10-08 12:43:28 -0700196 const uint8_t* range_end = range_start + count * elem_size;
197 const uint8_t* file_end = file_start + size_;
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700198 if (UNLIKELY((range_start < file_start) || (range_end > file_end))) {
199 // Note: these two tests are enough as we make sure above that there's no overflow.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800200 ErrorStringPrintf("Bad range for %s: %zx to %zx", label,
Ian Rogerse3d55812014-06-11 13:00:44 -0700201 static_cast<size_t>(range_start - file_start),
202 static_cast<size_t>(range_end - file_start));
jeffhao10037c82012-01-23 15:06:23 -0800203 return false;
204 }
205 return true;
206}
207
Ian Rogers13735952014-10-08 12:43:28 -0700208bool DexFileVerifier::CheckList(size_t element_size, const char* label, const uint8_t* *ptr) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700209 // Check that the list is available. The first 4B are the count.
210 if (!CheckListSize(*ptr, 1, 4U, label)) {
211 return false;
212 }
213
214 uint32_t count = *reinterpret_cast<const uint32_t*>(*ptr);
215 if (count > 0) {
216 if (!CheckListSize(*ptr + 4, count, element_size, label)) {
217 return false;
218 }
219 }
220
221 *ptr += 4 + count * element_size;
222 return true;
223}
224
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700225bool DexFileVerifier::CheckIndex(uint32_t field, uint32_t limit, const char* label) {
226 if (UNLIKELY(field >= limit)) {
227 ErrorStringPrintf("Bad index for %s: %x >= %x", label, field, limit);
jeffhao10037c82012-01-23 15:06:23 -0800228 return false;
229 }
230 return true;
231}
232
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800233bool DexFileVerifier::CheckValidOffsetAndSize(uint32_t offset,
234 uint32_t size,
235 size_t alignment,
236 const char* label) {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700237 if (size == 0) {
238 if (offset != 0) {
239 ErrorStringPrintf("Offset(%d) should be zero when size is zero for %s.", offset, label);
240 return false;
241 }
242 }
243 if (size_ <= offset) {
244 ErrorStringPrintf("Offset(%d) should be within file size(%zu) for %s.", offset, size_, label);
245 return false;
246 }
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800247 if (alignment != 0 && !IsAlignedParam(offset, alignment)) {
248 ErrorStringPrintf("Offset(%d) should be aligned by %zu for %s.", offset, alignment, label);
249 return false;
250 }
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700251 return true;
252}
253
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100254bool DexFileVerifier::CheckSizeLimit(uint32_t size, uint32_t limit, const char* label) {
255 if (size > limit) {
256 ErrorStringPrintf("Size(%u) should not exceed limit(%u) for %s.", size, limit, label);
257 return false;
258 }
259 return true;
260}
261
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700262bool DexFileVerifier::CheckHeader() {
jeffhaof6174e82012-01-31 16:14:17 -0800263 // Check file size from the header.
264 uint32_t expected_size = header_->file_size_;
265 if (size_ != expected_size) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700266 ErrorStringPrintf("Bad file size (%zd, expected %ud)", size_, expected_size);
jeffhao10037c82012-01-23 15:06:23 -0800267 return false;
268 }
269
270 // Compute and verify the checksum in the header.
271 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
272 const uint32_t non_sum = sizeof(header_->magic_) + sizeof(header_->checksum_);
Ian Rogers13735952014-10-08 12:43:28 -0700273 const uint8_t* non_sum_ptr = reinterpret_cast<const uint8_t*>(header_) + non_sum;
jeffhaof6174e82012-01-31 16:14:17 -0800274 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
jeffhao10037c82012-01-23 15:06:23 -0800275 if (adler_checksum != header_->checksum_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700276 ErrorStringPrintf("Bad checksum (%08x, expected %08x)", adler_checksum, header_->checksum_);
jeffhao10037c82012-01-23 15:06:23 -0800277 return false;
278 }
279
280 // Check the contents of the header.
281 if (header_->endian_tag_ != DexFile::kDexEndianConstant) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700282 ErrorStringPrintf("Unexpected endian_tag: %x", header_->endian_tag_);
jeffhao10037c82012-01-23 15:06:23 -0800283 return false;
284 }
285
286 if (header_->header_size_ != sizeof(DexFile::Header)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700287 ErrorStringPrintf("Bad header size: %ud", header_->header_size_);
jeffhao10037c82012-01-23 15:06:23 -0800288 return false;
289 }
290
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700291 // Check that all offsets are inside the file.
292 bool result =
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800293 CheckValidOffsetAndSize(header_->link_off_,
294 header_->link_size_,
295 0 /* unaligned */,
296 "link") &&
297 CheckValidOffsetAndSize(header_->map_off_,
298 header_->map_off_,
299 4,
300 "map") &&
301 CheckValidOffsetAndSize(header_->string_ids_off_,
302 header_->string_ids_size_,
303 4,
304 "string-ids") &&
305 CheckValidOffsetAndSize(header_->type_ids_off_,
306 header_->type_ids_size_,
307 4,
308 "type-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100309 CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800310 CheckValidOffsetAndSize(header_->proto_ids_off_,
311 header_->proto_ids_size_,
312 4,
313 "proto-ids") &&
Vladimir Marko0ca8add2016-05-03 17:17:50 +0100314 CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") &&
Andreas Gampeb512c0e2016-02-19 19:45:34 -0800315 CheckValidOffsetAndSize(header_->field_ids_off_,
316 header_->field_ids_size_,
317 4,
318 "field-ids") &&
319 CheckValidOffsetAndSize(header_->method_ids_off_,
320 header_->method_ids_size_,
321 4,
322 "method-ids") &&
323 CheckValidOffsetAndSize(header_->class_defs_off_,
324 header_->class_defs_size_,
325 4,
326 "class-defs") &&
327 CheckValidOffsetAndSize(header_->data_off_,
328 header_->data_size_,
329 0, // Unaligned, spec doesn't talk about it, even though size
330 // is supposed to be a multiple of 4.
331 "data");
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700332 return result;
jeffhao10037c82012-01-23 15:06:23 -0800333}
334
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700335bool DexFileVerifier::CheckMap() {
Andreas Gamped4ae41f2014-09-02 11:17:34 -0700336 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ +
337 header_->map_off_);
338 // Check that map list content is available.
339 if (!CheckListSize(map, 1, sizeof(DexFile::MapList), "maplist content")) {
340 return false;
341 }
342
jeffhao10037c82012-01-23 15:06:23 -0800343 const DexFile::MapItem* item = map->list_;
344
345 uint32_t count = map->size_;
346 uint32_t last_offset = 0;
347 uint32_t data_item_count = 0;
348 uint32_t data_items_left = header_->data_size_;
349 uint32_t used_bits = 0;
350
351 // Sanity check the size of the map list.
352 if (!CheckListSize(item, count, sizeof(DexFile::MapItem), "map size")) {
353 return false;
354 }
355
356 // Check the items listed in the map.
357 for (uint32_t i = 0; i < count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700358 if (UNLIKELY(last_offset >= item->offset_ && i != 0)) {
359 ErrorStringPrintf("Out of order map item: %x then %x", last_offset, item->offset_);
jeffhao10037c82012-01-23 15:06:23 -0800360 return false;
361 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700362 if (UNLIKELY(item->offset_ >= header_->file_size_)) {
363 ErrorStringPrintf("Map item after end of file: %x, size %x",
364 item->offset_, header_->file_size_);
jeffhao10037c82012-01-23 15:06:23 -0800365 return false;
366 }
367
368 if (IsDataSectionType(item->type_)) {
369 uint32_t icount = item->size_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700370 if (UNLIKELY(icount > data_items_left)) {
371 ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
jeffhao10037c82012-01-23 15:06:23 -0800372 return false;
373 }
374 data_items_left -= icount;
375 data_item_count += icount;
376 }
377
378 uint32_t bit = MapTypeToBitMask(item->type_);
379
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700380 if (UNLIKELY(bit == 0)) {
381 ErrorStringPrintf("Unknown map section type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800382 return false;
383 }
384
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700385 if (UNLIKELY((used_bits & bit) != 0)) {
386 ErrorStringPrintf("Duplicate map section of type %x", item->type_);
jeffhao10037c82012-01-23 15:06:23 -0800387 return false;
388 }
389
390 used_bits |= bit;
391 last_offset = item->offset_;
392 item++;
393 }
394
395 // Check for missing sections in the map.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700396 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeHeaderItem)) == 0)) {
397 ErrorStringPrintf("Map is missing header entry");
jeffhao10037c82012-01-23 15:06:23 -0800398 return false;
399 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700400 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMapList)) == 0)) {
401 ErrorStringPrintf("Map is missing map_list entry");
jeffhao10037c82012-01-23 15:06:23 -0800402 return false;
403 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700404 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeStringIdItem)) == 0 &&
405 ((header_->string_ids_off_ != 0) || (header_->string_ids_size_ != 0)))) {
406 ErrorStringPrintf("Map is missing string_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800407 return false;
408 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700409 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeTypeIdItem)) == 0 &&
410 ((header_->type_ids_off_ != 0) || (header_->type_ids_size_ != 0)))) {
411 ErrorStringPrintf("Map is missing type_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800412 return false;
413 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700414 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeProtoIdItem)) == 0 &&
415 ((header_->proto_ids_off_ != 0) || (header_->proto_ids_size_ != 0)))) {
416 ErrorStringPrintf("Map is missing proto_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800417 return false;
418 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700419 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeFieldIdItem)) == 0 &&
420 ((header_->field_ids_off_ != 0) || (header_->field_ids_size_ != 0)))) {
421 ErrorStringPrintf("Map is missing field_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800422 return false;
423 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700424 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeMethodIdItem)) == 0 &&
425 ((header_->method_ids_off_ != 0) || (header_->method_ids_size_ != 0)))) {
426 ErrorStringPrintf("Map is missing method_ids entry");
jeffhao10037c82012-01-23 15:06:23 -0800427 return false;
428 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700429 if (UNLIKELY((used_bits & MapTypeToBitMask(DexFile::kDexTypeClassDefItem)) == 0 &&
430 ((header_->class_defs_off_ != 0) || (header_->class_defs_size_ != 0)))) {
431 ErrorStringPrintf("Map is missing class_defs entry");
jeffhao10037c82012-01-23 15:06:23 -0800432 return false;
433 }
jeffhao10037c82012-01-23 15:06:23 -0800434 return true;
435}
436
437uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) {
438 uint32_t result = 0;
Ian Rogers13735952014-10-08 12:43:28 -0700439 if (LIKELY(CheckListSize(ptr_, size, sizeof(uint8_t), "encoded_value"))) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700440 for (uint32_t i = 0; i < size; i++) {
441 result |= ((uint32_t) *(ptr_++)) << (i * 8);
442 }
jeffhao10037c82012-01-23 15:06:23 -0800443 }
jeffhao10037c82012-01-23 15:06:23 -0800444 return result;
445}
446
447bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700448 uint32_t* handler_offsets, uint32_t handlers_size) {
Ian Rogers13735952014-10-08 12:43:28 -0700449 const uint8_t* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -0800450
451 for (uint32_t i = 0; i < handlers_size; i++) {
452 bool catch_all;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800453 size_t offset = ptr_ - handlers_base;
jeffhao10037c82012-01-23 15:06:23 -0800454 int32_t size = DecodeSignedLeb128(&ptr_);
455
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700456 if (UNLIKELY((size < -65536) || (size > 65536))) {
457 ErrorStringPrintf("Invalid exception handler size: %d", size);
jeffhao10037c82012-01-23 15:06:23 -0800458 return false;
459 }
460
461 if (size <= 0) {
462 catch_all = true;
463 size = -size;
464 } else {
465 catch_all = false;
466 }
467
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800468 handler_offsets[i] = static_cast<uint32_t>(offset);
jeffhao10037c82012-01-23 15:06:23 -0800469
470 while (size-- > 0) {
471 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
472 if (!CheckIndex(type_idx, header_->type_ids_size_, "handler type_idx")) {
473 return false;
474 }
475
476 uint32_t addr = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700477 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
478 ErrorStringPrintf("Invalid handler addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800479 return false;
480 }
481 }
482
483 if (catch_all) {
484 uint32_t addr = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700485 if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
486 ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
jeffhao10037c82012-01-23 15:06:23 -0800487 return false;
488 }
489 }
490 }
491
492 return true;
493}
494
Andreas Gampee6215c02015-08-31 18:54:38 -0700495bool DexFileVerifier::CheckClassDataItemField(uint32_t idx,
496 uint32_t access_flags,
497 uint32_t class_access_flags,
Andreas Gampe1a973572015-09-10 20:09:11 -0700498 uint16_t class_type_index,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700499 bool expect_static) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700500 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800501 if (!CheckIndex(idx, header_->field_ids_size_, "class_data_item field_idx")) {
502 return false;
503 }
504
Andreas Gampee6215c02015-08-31 18:54:38 -0700505 // Check that it's the right class.
506 uint16_t my_class_index =
507 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + idx)->
508 class_idx_;
509 if (class_type_index != my_class_index) {
510 ErrorStringPrintf("Field's class index unexpected, %" PRIu16 "vs %" PRIu16,
511 my_class_index,
512 class_type_index);
513 return false;
514 }
515
516 // Check that it falls into the right class-data list.
jeffhao10037c82012-01-23 15:06:23 -0800517 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700518 if (UNLIKELY(is_static != expect_static)) {
519 ErrorStringPrintf("Static/instance field not in expected list");
jeffhao10037c82012-01-23 15:06:23 -0800520 return false;
521 }
522
Andreas Gampee6215c02015-08-31 18:54:38 -0700523 // Check field access flags.
524 std::string error_msg;
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800525 if (!CheckFieldAccessFlags(idx, access_flags, class_access_flags, &error_msg)) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700526 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800527 return false;
528 }
529
530 return true;
531}
532
Andreas Gampee6215c02015-08-31 18:54:38 -0700533bool DexFileVerifier::CheckClassDataItemMethod(uint32_t idx,
534 uint32_t access_flags,
535 uint32_t class_access_flags,
Andreas Gampe1a973572015-09-10 20:09:11 -0700536 uint16_t class_type_index,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700537 uint32_t code_offset,
Andreas Gampee6215c02015-08-31 18:54:38 -0700538 std::unordered_set<uint32_t>* direct_method_indexes,
Jeff Haoa574b0e2015-06-04 18:12:26 -0700539 bool expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700540 DCHECK(direct_method_indexes != nullptr);
541 // Check for overflow.
jeffhao10037c82012-01-23 15:06:23 -0800542 if (!CheckIndex(idx, header_->method_ids_size_, "class_data_item method_idx")) {
543 return false;
544 }
545
Andreas Gampee6215c02015-08-31 18:54:38 -0700546 // Check that it's the right class.
547 uint16_t my_class_index =
548 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + idx)->
549 class_idx_;
550 if (class_type_index != my_class_index) {
551 ErrorStringPrintf("Method's class index unexpected, %" PRIu16 "vs %" PRIu16,
552 my_class_index,
553 class_type_index);
jeffhao10037c82012-01-23 15:06:23 -0800554 return false;
555 }
556
Andreas Gampee6215c02015-08-31 18:54:38 -0700557 // Check that it's not defined as both direct and virtual.
Jeff Haoa574b0e2015-06-04 18:12:26 -0700558 if (expect_direct) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700559 direct_method_indexes->insert(idx);
560 } else if (direct_method_indexes->find(idx) != direct_method_indexes->end()) {
Jeff Haoa574b0e2015-06-04 18:12:26 -0700561 ErrorStringPrintf("Found virtual method with same index as direct method: %d", idx);
562 return false;
563 }
564
Andreas Gampee6215c02015-08-31 18:54:38 -0700565 // Check method access flags.
566 bool has_code = (code_offset != 0);
567 std::string error_msg;
568 if (!CheckMethodAccessFlags(idx,
569 access_flags,
570 class_access_flags,
571 has_code,
572 expect_direct,
573 &error_msg)) {
574 ErrorStringPrintf("%s", error_msg.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800575 return false;
576 }
577
578 return true;
579}
580
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800581bool DexFileVerifier::CheckPadding(size_t offset, uint32_t aligned_offset) {
jeffhao10037c82012-01-23 15:06:23 -0800582 if (offset < aligned_offset) {
Ian Rogers13735952014-10-08 12:43:28 -0700583 if (!CheckListSize(begin_ + offset, aligned_offset - offset, sizeof(uint8_t), "section")) {
jeffhao10037c82012-01-23 15:06:23 -0800584 return false;
585 }
586 while (offset < aligned_offset) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700587 if (UNLIKELY(*ptr_ != '\0')) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800588 ErrorStringPrintf("Non-zero padding %x before section start at %zx", *ptr_, offset);
jeffhao10037c82012-01-23 15:06:23 -0800589 return false;
590 }
591 ptr_++;
592 offset++;
593 }
594 }
595 return true;
596}
597
598bool DexFileVerifier::CheckEncodedValue() {
Ian Rogers13735952014-10-08 12:43:28 -0700599 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "encoded_value header")) {
jeffhao10037c82012-01-23 15:06:23 -0800600 return false;
601 }
602
603 uint8_t header_byte = *(ptr_++);
604 uint32_t value_type = header_byte & DexFile::kDexAnnotationValueTypeMask;
605 uint32_t value_arg = header_byte >> DexFile::kDexAnnotationValueArgShift;
606
607 switch (value_type) {
608 case DexFile::kDexAnnotationByte:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700609 if (UNLIKELY(value_arg != 0)) {
610 ErrorStringPrintf("Bad encoded_value byte size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800611 return false;
612 }
613 ptr_++;
614 break;
615 case DexFile::kDexAnnotationShort:
616 case DexFile::kDexAnnotationChar:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700617 if (UNLIKELY(value_arg > 1)) {
618 ErrorStringPrintf("Bad encoded_value char/short size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800619 return false;
620 }
621 ptr_ += value_arg + 1;
622 break;
623 case DexFile::kDexAnnotationInt:
624 case DexFile::kDexAnnotationFloat:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700625 if (UNLIKELY(value_arg > 3)) {
626 ErrorStringPrintf("Bad encoded_value int/float size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800627 return false;
628 }
629 ptr_ += value_arg + 1;
630 break;
631 case DexFile::kDexAnnotationLong:
632 case DexFile::kDexAnnotationDouble:
633 ptr_ += value_arg + 1;
634 break;
635 case DexFile::kDexAnnotationString: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700636 if (UNLIKELY(value_arg > 3)) {
637 ErrorStringPrintf("Bad encoded_value string size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800638 return false;
639 }
640 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
641 if (!CheckIndex(idx, header_->string_ids_size_, "encoded_value string")) {
642 return false;
643 }
644 break;
645 }
646 case DexFile::kDexAnnotationType: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700647 if (UNLIKELY(value_arg > 3)) {
648 ErrorStringPrintf("Bad encoded_value type size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800649 return false;
650 }
651 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
652 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_value type")) {
653 return false;
654 }
655 break;
656 }
657 case DexFile::kDexAnnotationField:
658 case DexFile::kDexAnnotationEnum: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700659 if (UNLIKELY(value_arg > 3)) {
660 ErrorStringPrintf("Bad encoded_value field/enum size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800661 return false;
662 }
663 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
664 if (!CheckIndex(idx, header_->field_ids_size_, "encoded_value field")) {
665 return false;
666 }
667 break;
668 }
669 case DexFile::kDexAnnotationMethod: {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700670 if (UNLIKELY(value_arg > 3)) {
671 ErrorStringPrintf("Bad encoded_value method size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800672 return false;
673 }
674 uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
675 if (!CheckIndex(idx, header_->method_ids_size_, "encoded_value method")) {
676 return false;
677 }
678 break;
679 }
680 case DexFile::kDexAnnotationArray:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700681 if (UNLIKELY(value_arg != 0)) {
682 ErrorStringPrintf("Bad encoded_value array value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800683 return false;
684 }
685 if (!CheckEncodedArray()) {
686 return false;
687 }
688 break;
689 case DexFile::kDexAnnotationAnnotation:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700690 if (UNLIKELY(value_arg != 0)) {
691 ErrorStringPrintf("Bad encoded_value annotation value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800692 return false;
693 }
694 if (!CheckEncodedAnnotation()) {
695 return false;
696 }
697 break;
698 case DexFile::kDexAnnotationNull:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700699 if (UNLIKELY(value_arg != 0)) {
700 ErrorStringPrintf("Bad encoded_value null value_arg %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800701 return false;
702 }
703 break;
704 case DexFile::kDexAnnotationBoolean:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700705 if (UNLIKELY(value_arg > 1)) {
706 ErrorStringPrintf("Bad encoded_value boolean size %x", value_arg);
jeffhao10037c82012-01-23 15:06:23 -0800707 return false;
708 }
709 break;
710 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700711 ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
jeffhao10037c82012-01-23 15:06:23 -0800712 return false;
713 }
714
715 return true;
716}
717
718bool DexFileVerifier::CheckEncodedArray() {
719 uint32_t size = DecodeUnsignedLeb128(&ptr_);
720
721 while (size--) {
722 if (!CheckEncodedValue()) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700723 failure_reason_ = StringPrintf("Bad encoded_array value: %s", failure_reason_.c_str());
jeffhao10037c82012-01-23 15:06:23 -0800724 return false;
725 }
726 }
727 return true;
728}
729
730bool DexFileVerifier::CheckEncodedAnnotation() {
731 uint32_t idx = DecodeUnsignedLeb128(&ptr_);
732 if (!CheckIndex(idx, header_->type_ids_size_, "encoded_annotation type_idx")) {
733 return false;
734 }
735
736 uint32_t size = DecodeUnsignedLeb128(&ptr_);
737 uint32_t last_idx = 0;
738
739 for (uint32_t i = 0; i < size; i++) {
740 idx = DecodeUnsignedLeb128(&ptr_);
741 if (!CheckIndex(idx, header_->string_ids_size_, "annotation_element name_idx")) {
742 return false;
743 }
744
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700745 if (UNLIKELY(last_idx >= idx && i != 0)) {
746 ErrorStringPrintf("Out-of-order annotation_element name_idx: %x then %x",
747 last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -0800748 return false;
749 }
750
751 if (!CheckEncodedValue()) {
752 return false;
753 }
754
755 last_idx = idx;
756 }
757 return true;
758}
759
Andreas Gampee6215c02015-08-31 18:54:38 -0700760bool DexFileVerifier::FindClassFlags(uint32_t index,
761 bool is_field,
762 uint16_t* class_type_index,
763 uint32_t* class_access_flags) {
764 DCHECK(class_type_index != nullptr);
765 DCHECK(class_access_flags != nullptr);
766
767 // First check if the index is valid.
768 if (index >= (is_field ? header_->field_ids_size_ : header_->method_ids_size_)) {
769 return false;
770 }
771
772 // Next get the type index.
773 if (is_field) {
774 *class_type_index =
775 (reinterpret_cast<const DexFile::FieldId*>(begin_ + header_->field_ids_off_) + index)->
776 class_idx_;
777 } else {
778 *class_type_index =
779 (reinterpret_cast<const DexFile::MethodId*>(begin_ + header_->method_ids_off_) + index)->
780 class_idx_;
781 }
782
783 // Check if that is valid.
784 if (*class_type_index >= header_->type_ids_size_) {
785 return false;
786 }
787
788 // Now search for the class def. This is basically a specialized version of the DexFile code, as
789 // we should not trust that this is a valid DexFile just yet.
790 const DexFile::ClassDef* class_def_begin =
791 reinterpret_cast<const DexFile::ClassDef*>(begin_ + header_->class_defs_off_);
792 for (size_t i = 0; i < header_->class_defs_size_; ++i) {
793 const DexFile::ClassDef* class_def = class_def_begin + i;
794 if (class_def->class_idx_ == *class_type_index) {
795 *class_access_flags = class_def->access_flags_;
796 return true;
797 }
798 }
799
800 // Didn't find the class-def, not defined here...
801 return false;
802}
803
804bool DexFileVerifier::CheckOrderAndGetClassFlags(bool is_field,
805 const char* type_descr,
806 uint32_t curr_index,
807 uint32_t prev_index,
808 bool* have_class,
809 uint16_t* class_type_index,
810 uint32_t* class_access_flags) {
811 if (curr_index < prev_index) {
812 ErrorStringPrintf("out-of-order %s indexes %" PRIu32 " and %" PRIu32,
813 type_descr,
814 prev_index,
815 curr_index);
816 return false;
817 }
818
819 if (!*have_class) {
820 *have_class = FindClassFlags(curr_index, is_field, class_type_index, class_access_flags);
821 if (!*have_class) {
822 // Should have really found one.
823 ErrorStringPrintf("could not find declaring class for %s index %" PRIu32,
824 type_descr,
825 curr_index);
826 return false;
827 }
828 }
829 return true;
830}
831
832template <bool kStatic>
833bool DexFileVerifier::CheckIntraClassDataItemFields(ClassDataItemIterator* it,
834 bool* have_class,
835 uint16_t* class_type_index,
836 uint32_t* class_access_flags) {
837 DCHECK(it != nullptr);
838 // These calls use the raw access flags to check whether the whole dex field is valid.
839 uint32_t prev_index = 0;
840 for (; kStatic ? it->HasNextStaticField() : it->HasNextInstanceField(); it->Next()) {
841 uint32_t curr_index = it->GetMemberIndex();
842 if (!CheckOrderAndGetClassFlags(true,
843 kStatic ? "static field" : "instance field",
844 curr_index,
845 prev_index,
846 have_class,
847 class_type_index,
848 class_access_flags)) {
849 return false;
850 }
851 prev_index = curr_index;
852
853 if (!CheckClassDataItemField(curr_index,
854 it->GetRawMemberAccessFlags(),
855 *class_access_flags,
856 *class_type_index,
857 kStatic)) {
858 return false;
859 }
860 }
861
862 return true;
863}
864
865template <bool kDirect>
866bool DexFileVerifier::CheckIntraClassDataItemMethods(
867 ClassDataItemIterator* it,
868 std::unordered_set<uint32_t>* direct_method_indexes,
869 bool* have_class,
870 uint16_t* class_type_index,
871 uint32_t* class_access_flags) {
872 uint32_t prev_index = 0;
873 for (; kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); it->Next()) {
874 uint32_t curr_index = it->GetMemberIndex();
875 if (!CheckOrderAndGetClassFlags(false,
876 kDirect ? "direct method" : "virtual method",
877 curr_index,
878 prev_index,
879 have_class,
880 class_type_index,
881 class_access_flags)) {
882 return false;
883 }
884 prev_index = curr_index;
885
886 if (!CheckClassDataItemMethod(curr_index,
887 it->GetRawMemberAccessFlags(),
888 *class_access_flags,
889 *class_type_index,
890 it->GetMethodCodeItemOffset(),
891 direct_method_indexes,
892 kDirect)) {
893 return false;
894 }
895 }
896
897 return true;
898}
899
jeffhao10037c82012-01-23 15:06:23 -0800900bool DexFileVerifier::CheckIntraClassDataItem() {
901 ClassDataItemIterator it(*dex_file_, ptr_);
Jeff Haoa574b0e2015-06-04 18:12:26 -0700902 std::unordered_set<uint32_t> direct_method_indexes;
jeffhao10037c82012-01-23 15:06:23 -0800903
Andreas Gampee6215c02015-08-31 18:54:38 -0700904 // This code is complicated by the fact that we don't directly know which class this belongs to.
905 // So we need to explicitly search with the first item we find (either field or method), and then,
906 // as the lookup is expensive, cache the result.
907 bool have_class = false;
908 uint16_t class_type_index;
909 uint32_t class_access_flags;
910
911 // Check fields.
912 if (!CheckIntraClassDataItemFields<true>(&it,
913 &have_class,
914 &class_type_index,
915 &class_access_flags)) {
916 return false;
jeffhao10037c82012-01-23 15:06:23 -0800917 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700918 if (!CheckIntraClassDataItemFields<false>(&it,
919 &have_class,
920 &class_type_index,
921 &class_access_flags)) {
922 return false;
jeffhao10037c82012-01-23 15:06:23 -0800923 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700924
925 // Check methods.
926 if (!CheckIntraClassDataItemMethods<true>(&it,
927 &direct_method_indexes,
928 &have_class,
929 &class_type_index,
930 &class_access_flags)) {
931 return false;
jeffhao10037c82012-01-23 15:06:23 -0800932 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700933 if (!CheckIntraClassDataItemMethods<false>(&it,
934 &direct_method_indexes,
935 &have_class,
936 &class_type_index,
937 &class_access_flags)) {
938 return false;
jeffhao10037c82012-01-23 15:06:23 -0800939 }
940
941 ptr_ = it.EndDataPointer();
942 return true;
943}
944
945bool DexFileVerifier::CheckIntraCodeItem() {
946 const DexFile::CodeItem* code_item = reinterpret_cast<const DexFile::CodeItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -0700947 if (!CheckListSize(code_item, 1, sizeof(DexFile::CodeItem), "code")) {
jeffhao10037c82012-01-23 15:06:23 -0800948 return false;
949 }
950
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700951 if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
952 ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
953 code_item->ins_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800954 return false;
955 }
956
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700957 if (UNLIKELY((code_item->outs_size_ > 5) &&
958 (code_item->outs_size_ > code_item->registers_size_))) {
jeffhao10037c82012-01-23 15:06:23 -0800959 /*
960 * outs_size can be up to 5, even if registers_size is smaller, since the
961 * short forms of method invocation allow repetitions of a register multiple
962 * times within a single parameter list. However, longer parameter lists
963 * need to be represented in-order in the register file.
964 */
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700965 ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
966 code_item->outs_size_, code_item->registers_size_);
jeffhao10037c82012-01-23 15:06:23 -0800967 return false;
968 }
969
970 const uint16_t* insns = code_item->insns_;
971 uint32_t insns_size = code_item->insns_size_in_code_units_;
972 if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
973 return false;
974 }
975
976 // Grab the end of the insns if there are no try_items.
977 uint32_t try_items_size = code_item->tries_size_;
978 if (try_items_size == 0) {
Ian Rogers13735952014-10-08 12:43:28 -0700979 ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -0800980 return true;
981 }
982
983 // try_items are 4-byte aligned. Verify the spacer is 0.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -0800984 if (((reinterpret_cast<uintptr_t>(&insns[insns_size]) & 3) != 0) && (insns[insns_size] != 0)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700985 ErrorStringPrintf("Non-zero padding: %x", insns[insns_size]);
jeffhao10037c82012-01-23 15:06:23 -0800986 return false;
987 }
988
989 const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
jeffhao10037c82012-01-23 15:06:23 -0800990 if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
991 return false;
992 }
993
Anestis Bechtsoudis6a8df532015-07-12 12:51:35 -0500994 ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
995 uint32_t handlers_size = DecodeUnsignedLeb128(&ptr_);
996
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700997 if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
998 ErrorStringPrintf("Invalid handlers_size: %ud", handlers_size);
jeffhao10037c82012-01-23 15:06:23 -0800999 return false;
1000 }
1001
Ian Rogers700a4022014-05-19 16:49:03 -07001002 std::unique_ptr<uint32_t[]> handler_offsets(new uint32_t[handlers_size]);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001003 if (!CheckAndGetHandlerOffsets(code_item, &handler_offsets[0], handlers_size)) {
jeffhao10037c82012-01-23 15:06:23 -08001004 return false;
1005 }
1006
1007 uint32_t last_addr = 0;
1008 while (try_items_size--) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001009 if (UNLIKELY(try_items->start_addr_ < last_addr)) {
1010 ErrorStringPrintf("Out-of_order try_item with start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001011 return false;
1012 }
1013
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001014 if (UNLIKELY(try_items->start_addr_ >= insns_size)) {
1015 ErrorStringPrintf("Invalid try_item start_addr: %x", try_items->start_addr_);
jeffhao10037c82012-01-23 15:06:23 -08001016 return false;
1017 }
1018
1019 uint32_t i;
1020 for (i = 0; i < handlers_size; i++) {
1021 if (try_items->handler_off_ == handler_offsets[i]) {
1022 break;
1023 }
1024 }
1025
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001026 if (UNLIKELY(i == handlers_size)) {
1027 ErrorStringPrintf("Bogus handler offset: %x", try_items->handler_off_);
jeffhao10037c82012-01-23 15:06:23 -08001028 return false;
1029 }
1030
1031 last_addr = try_items->start_addr_ + try_items->insn_count_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001032 if (UNLIKELY(last_addr > insns_size)) {
1033 ErrorStringPrintf("Invalid try_item insn_count: %x", try_items->insn_count_);
jeffhao10037c82012-01-23 15:06:23 -08001034 return false;
1035 }
1036
1037 try_items++;
1038 }
1039
1040 return true;
1041}
1042
1043bool DexFileVerifier::CheckIntraStringDataItem() {
1044 uint32_t size = DecodeUnsignedLeb128(&ptr_);
Ian Rogers13735952014-10-08 12:43:28 -07001045 const uint8_t* file_end = begin_ + size_;
jeffhao10037c82012-01-23 15:06:23 -08001046
1047 for (uint32_t i = 0; i < size; i++) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001048 CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001049 if (UNLIKELY(ptr_ >= file_end)) {
1050 ErrorStringPrintf("String data would go beyond end-of-file");
jeffhao10037c82012-01-23 15:06:23 -08001051 return false;
1052 }
1053
1054 uint8_t byte = *(ptr_++);
1055
1056 // Switch on the high 4 bits.
1057 switch (byte >> 4) {
1058 case 0x00:
1059 // Special case of bit pattern 0xxx.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001060 if (UNLIKELY(byte == 0)) {
Brian Carlstromc6475642014-05-27 11:14:12 -07001061 CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001062 ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001063 return false;
1064 }
1065 break;
1066 case 0x01:
1067 case 0x02:
1068 case 0x03:
1069 case 0x04:
1070 case 0x05:
1071 case 0x06:
1072 case 0x07:
1073 // No extra checks necessary for bit pattern 0xxx.
1074 break;
1075 case 0x08:
1076 case 0x09:
1077 case 0x0a:
1078 case 0x0b:
1079 case 0x0f:
1080 // Illegal bit patterns 10xx or 1111.
1081 // Note: 1111 is valid for normal UTF-8, but not here.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001082 ErrorStringPrintf("Illegal start byte %x in string data", byte);
jeffhao10037c82012-01-23 15:06:23 -08001083 return false;
1084 case 0x0c:
1085 case 0x0d: {
1086 // Bit pattern 110x has an additional byte.
1087 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001088 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1089 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001090 return false;
1091 }
1092 uint16_t value = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001093 if (UNLIKELY((value != 0) && (value < 0x80))) {
1094 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001095 return false;
1096 }
1097 break;
1098 }
1099 case 0x0e: {
1100 // Bit pattern 1110 has 2 additional bytes.
1101 uint8_t byte2 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001102 if (UNLIKELY((byte2 & 0xc0) != 0x80)) {
1103 ErrorStringPrintf("Illegal continuation byte %x in string data", byte2);
jeffhao10037c82012-01-23 15:06:23 -08001104 return false;
1105 }
1106 uint8_t byte3 = *(ptr_++);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001107 if (UNLIKELY((byte3 & 0xc0) != 0x80)) {
1108 ErrorStringPrintf("Illegal continuation byte %x in string data", byte3);
jeffhao10037c82012-01-23 15:06:23 -08001109 return false;
1110 }
1111 uint16_t value = ((byte & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001112 if (UNLIKELY(value < 0x800)) {
1113 ErrorStringPrintf("Illegal representation for value %x in string data", value);
jeffhao10037c82012-01-23 15:06:23 -08001114 return false;
1115 }
1116 break;
1117 }
1118 }
1119 }
1120
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001121 if (UNLIKELY(*(ptr_++) != '\0')) {
1122 ErrorStringPrintf("String longer than indicated size %x", size);
jeffhao10037c82012-01-23 15:06:23 -08001123 return false;
1124 }
1125
1126 return true;
1127}
1128
1129bool DexFileVerifier::CheckIntraDebugInfoItem() {
1130 DecodeUnsignedLeb128(&ptr_);
1131 uint32_t parameters_size = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001132 if (UNLIKELY(parameters_size > 65536)) {
1133 ErrorStringPrintf("Invalid parameters_size: %x", parameters_size);
jeffhao10037c82012-01-23 15:06:23 -08001134 return false;
1135 }
1136
1137 for (uint32_t j = 0; j < parameters_size; j++) {
1138 uint32_t parameter_name = DecodeUnsignedLeb128(&ptr_);
1139 if (parameter_name != 0) {
1140 parameter_name--;
1141 if (!CheckIndex(parameter_name, header_->string_ids_size_, "debug_info_item parameter_name")) {
1142 return false;
1143 }
1144 }
1145 }
1146
1147 while (true) {
1148 uint8_t opcode = *(ptr_++);
1149 switch (opcode) {
1150 case DexFile::DBG_END_SEQUENCE: {
1151 return true;
1152 }
1153 case DexFile::DBG_ADVANCE_PC: {
1154 DecodeUnsignedLeb128(&ptr_);
1155 break;
1156 }
1157 case DexFile::DBG_ADVANCE_LINE: {
1158 DecodeSignedLeb128(&ptr_);
1159 break;
1160 }
1161 case DexFile::DBG_START_LOCAL: {
1162 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001163 if (UNLIKELY(reg_num >= 65536)) {
1164 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001165 return false;
1166 }
1167 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
1168 if (name_idx != 0) {
1169 name_idx--;
1170 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL name_idx")) {
1171 return false;
1172 }
1173 }
1174 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
1175 if (type_idx != 0) {
1176 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001177 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001178 return false;
1179 }
1180 }
1181 break;
1182 }
1183 case DexFile::DBG_END_LOCAL:
1184 case DexFile::DBG_RESTART_LOCAL: {
1185 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001186 if (UNLIKELY(reg_num >= 65536)) {
1187 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001188 return false;
1189 }
1190 break;
1191 }
1192 case DexFile::DBG_START_LOCAL_EXTENDED: {
1193 uint32_t reg_num = DecodeUnsignedLeb128(&ptr_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001194 if (UNLIKELY(reg_num >= 65536)) {
1195 ErrorStringPrintf("Bad reg_num for opcode %x", opcode);
jeffhao10037c82012-01-23 15:06:23 -08001196 return false;
1197 }
1198 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
1199 if (name_idx != 0) {
1200 name_idx--;
1201 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED name_idx")) {
1202 return false;
1203 }
1204 }
1205 uint32_t type_idx = DecodeUnsignedLeb128(&ptr_);
1206 if (type_idx != 0) {
1207 type_idx--;
Logan Chiendd3208d2015-04-19 23:27:52 +08001208 if (!CheckIndex(type_idx, header_->type_ids_size_, "DBG_START_LOCAL_EXTENDED type_idx")) {
jeffhao10037c82012-01-23 15:06:23 -08001209 return false;
1210 }
1211 }
1212 uint32_t sig_idx = DecodeUnsignedLeb128(&ptr_);
1213 if (sig_idx != 0) {
1214 sig_idx--;
1215 if (!CheckIndex(sig_idx, header_->string_ids_size_, "DBG_START_LOCAL_EXTENDED sig_idx")) {
1216 return false;
1217 }
1218 }
1219 break;
1220 }
1221 case DexFile::DBG_SET_FILE: {
1222 uint32_t name_idx = DecodeUnsignedLeb128(&ptr_);
1223 if (name_idx != 0) {
1224 name_idx--;
1225 if (!CheckIndex(name_idx, header_->string_ids_size_, "DBG_SET_FILE name_idx")) {
1226 return false;
1227 }
1228 }
1229 break;
1230 }
1231 }
1232 }
1233}
1234
1235bool DexFileVerifier::CheckIntraAnnotationItem() {
Ian Rogers13735952014-10-08 12:43:28 -07001236 if (!CheckListSize(ptr_, 1, sizeof(uint8_t), "annotation visibility")) {
jeffhao10037c82012-01-23 15:06:23 -08001237 return false;
1238 }
1239
1240 // Check visibility
1241 switch (*(ptr_++)) {
1242 case DexFile::kDexVisibilityBuild:
1243 case DexFile::kDexVisibilityRuntime:
1244 case DexFile::kDexVisibilitySystem:
1245 break;
1246 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001247 ErrorStringPrintf("Bad annotation visibility: %x", *ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001248 return false;
1249 }
1250
1251 if (!CheckEncodedAnnotation()) {
1252 return false;
1253 }
1254
1255 return true;
1256}
1257
1258bool DexFileVerifier::CheckIntraAnnotationsDirectoryItem() {
1259 const DexFile::AnnotationsDirectoryItem* item =
1260 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001261 if (!CheckListSize(item, 1, sizeof(DexFile::AnnotationsDirectoryItem), "annotations_directory")) {
jeffhao10037c82012-01-23 15:06:23 -08001262 return false;
1263 }
1264
1265 // Field annotations follow immediately after the annotations directory.
1266 const DexFile::FieldAnnotationsItem* field_item =
1267 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
1268 uint32_t field_count = item->fields_size_;
1269 if (!CheckListSize(field_item, field_count, sizeof(DexFile::FieldAnnotationsItem), "field_annotations list")) {
1270 return false;
1271 }
1272
1273 uint32_t last_idx = 0;
1274 for (uint32_t i = 0; i < field_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001275 if (UNLIKELY(last_idx >= field_item->field_idx_ && i != 0)) {
1276 ErrorStringPrintf("Out-of-order field_idx for annotation: %x then %x", last_idx, field_item->field_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001277 return false;
1278 }
1279 last_idx = field_item->field_idx_;
1280 field_item++;
1281 }
1282
1283 // Method annotations follow immediately after field annotations.
1284 const DexFile::MethodAnnotationsItem* method_item =
1285 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
1286 uint32_t method_count = item->methods_size_;
1287 if (!CheckListSize(method_item, method_count, sizeof(DexFile::MethodAnnotationsItem), "method_annotations list")) {
1288 return false;
1289 }
1290
1291 last_idx = 0;
1292 for (uint32_t i = 0; i < method_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001293 if (UNLIKELY(last_idx >= method_item->method_idx_ && i != 0)) {
1294 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1295 last_idx, method_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001296 return false;
1297 }
1298 last_idx = method_item->method_idx_;
1299 method_item++;
1300 }
1301
1302 // Parameter annotations follow immediately after method annotations.
1303 const DexFile::ParameterAnnotationsItem* parameter_item =
1304 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
1305 uint32_t parameter_count = item->parameters_size_;
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07001306 if (!CheckListSize(parameter_item, parameter_count, sizeof(DexFile::ParameterAnnotationsItem),
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001307 "parameter_annotations list")) {
jeffhao10037c82012-01-23 15:06:23 -08001308 return false;
1309 }
1310
1311 last_idx = 0;
1312 for (uint32_t i = 0; i < parameter_count; i++) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001313 if (UNLIKELY(last_idx >= parameter_item->method_idx_ && i != 0)) {
1314 ErrorStringPrintf("Out-of-order method_idx for annotation: %x then %x",
1315 last_idx, parameter_item->method_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001316 return false;
1317 }
1318 last_idx = parameter_item->method_idx_;
1319 parameter_item++;
1320 }
1321
1322 // Return a pointer to the end of the annotations.
Ian Rogers13735952014-10-08 12:43:28 -07001323 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08001324 return true;
1325}
1326
Andreas Gampeb061cc12014-09-02 10:22:20 -07001327bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
1328 uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001329 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001330 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001331 switch (type) {
1332 case DexFile::kDexTypeClassDataItem:
1333 case DexFile::kDexTypeStringDataItem:
1334 case DexFile::kDexTypeDebugInfoItem:
1335 case DexFile::kDexTypeAnnotationItem:
1336 case DexFile::kDexTypeEncodedArrayItem:
1337 alignment_mask = sizeof(uint8_t) - 1;
1338 break;
1339 default:
1340 alignment_mask = sizeof(uint32_t) - 1;
1341 break;
1342 }
1343
1344 // Iterate through the items in the section.
Andreas Gampeb061cc12014-09-02 10:22:20 -07001345 for (uint32_t i = 0; i < section_count; i++) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001346 size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08001347
1348 // Check the padding between items.
1349 if (!CheckPadding(offset, aligned_offset)) {
1350 return false;
1351 }
1352
1353 // Check depending on the section type.
1354 switch (type) {
1355 case DexFile::kDexTypeStringIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001356 if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001357 return false;
1358 }
1359 ptr_ += sizeof(DexFile::StringId);
1360 break;
1361 }
1362 case DexFile::kDexTypeTypeIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001363 if (!CheckListSize(ptr_, 1, sizeof(DexFile::TypeId), "type_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001364 return false;
1365 }
1366 ptr_ += sizeof(DexFile::TypeId);
1367 break;
1368 }
1369 case DexFile::kDexTypeProtoIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001370 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ProtoId), "proto_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001371 return false;
1372 }
1373 ptr_ += sizeof(DexFile::ProtoId);
1374 break;
1375 }
1376 case DexFile::kDexTypeFieldIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001377 if (!CheckListSize(ptr_, 1, sizeof(DexFile::FieldId), "field_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001378 return false;
1379 }
1380 ptr_ += sizeof(DexFile::FieldId);
1381 break;
1382 }
1383 case DexFile::kDexTypeMethodIdItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001384 if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodId), "method_ids")) {
jeffhao10037c82012-01-23 15:06:23 -08001385 return false;
1386 }
1387 ptr_ += sizeof(DexFile::MethodId);
1388 break;
1389 }
1390 case DexFile::kDexTypeClassDefItem: {
Andreas Gampe50d1bc12014-07-17 21:49:24 -07001391 if (!CheckListSize(ptr_, 1, sizeof(DexFile::ClassDef), "class_defs")) {
jeffhao10037c82012-01-23 15:06:23 -08001392 return false;
1393 }
1394 ptr_ += sizeof(DexFile::ClassDef);
1395 break;
1396 }
1397 case DexFile::kDexTypeTypeList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001398 if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001399 return false;
1400 }
jeffhao10037c82012-01-23 15:06:23 -08001401 break;
1402 }
1403 case DexFile::kDexTypeAnnotationSetRefList: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001404 if (!CheckList(sizeof(DexFile::AnnotationSetRefItem), "annotation_set_ref_list", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001405 return false;
1406 }
jeffhao10037c82012-01-23 15:06:23 -08001407 break;
1408 }
1409 case DexFile::kDexTypeAnnotationSetItem: {
Andreas Gamped4ae41f2014-09-02 11:17:34 -07001410 if (!CheckList(sizeof(uint32_t), "annotation_set_item", &ptr_)) {
jeffhao10037c82012-01-23 15:06:23 -08001411 return false;
1412 }
jeffhao10037c82012-01-23 15:06:23 -08001413 break;
1414 }
1415 case DexFile::kDexTypeClassDataItem: {
1416 if (!CheckIntraClassDataItem()) {
1417 return false;
1418 }
1419 break;
1420 }
1421 case DexFile::kDexTypeCodeItem: {
1422 if (!CheckIntraCodeItem()) {
1423 return false;
1424 }
1425 break;
1426 }
1427 case DexFile::kDexTypeStringDataItem: {
1428 if (!CheckIntraStringDataItem()) {
1429 return false;
1430 }
1431 break;
1432 }
1433 case DexFile::kDexTypeDebugInfoItem: {
1434 if (!CheckIntraDebugInfoItem()) {
1435 return false;
1436 }
1437 break;
1438 }
1439 case DexFile::kDexTypeAnnotationItem: {
1440 if (!CheckIntraAnnotationItem()) {
1441 return false;
1442 }
1443 break;
1444 }
1445 case DexFile::kDexTypeEncodedArrayItem: {
1446 if (!CheckEncodedArray()) {
1447 return false;
1448 }
1449 break;
1450 }
1451 case DexFile::kDexTypeAnnotationsDirectoryItem: {
1452 if (!CheckIntraAnnotationsDirectoryItem()) {
1453 return false;
1454 }
1455 break;
1456 }
1457 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001458 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001459 return false;
1460 }
1461
1462 if (IsDataSectionType(type)) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001463 if (aligned_offset == 0u) {
1464 ErrorStringPrintf("Item %d offset is 0", i);
1465 return false;
1466 }
1467 DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
1468 offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
jeffhao10037c82012-01-23 15:06:23 -08001469 }
1470
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001471 aligned_offset = ptr_ - begin_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001472 if (UNLIKELY(aligned_offset > size_)) {
1473 ErrorStringPrintf("Item %d at ends out of bounds", i);
jeffhao10037c82012-01-23 15:06:23 -08001474 return false;
1475 }
1476
1477 offset = aligned_offset;
1478 }
1479
1480 return true;
1481}
1482
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001483bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08001484 uint32_t expected_offset;
1485 uint32_t expected_size;
1486
1487 // Get the expected offset and size from the header.
1488 switch (type) {
1489 case DexFile::kDexTypeStringIdItem:
1490 expected_offset = header_->string_ids_off_;
1491 expected_size = header_->string_ids_size_;
1492 break;
1493 case DexFile::kDexTypeTypeIdItem:
1494 expected_offset = header_->type_ids_off_;
1495 expected_size = header_->type_ids_size_;
1496 break;
1497 case DexFile::kDexTypeProtoIdItem:
1498 expected_offset = header_->proto_ids_off_;
1499 expected_size = header_->proto_ids_size_;
1500 break;
1501 case DexFile::kDexTypeFieldIdItem:
1502 expected_offset = header_->field_ids_off_;
1503 expected_size = header_->field_ids_size_;
1504 break;
1505 case DexFile::kDexTypeMethodIdItem:
1506 expected_offset = header_->method_ids_off_;
1507 expected_size = header_->method_ids_size_;
1508 break;
1509 case DexFile::kDexTypeClassDefItem:
1510 expected_offset = header_->class_defs_off_;
1511 expected_size = header_->class_defs_size_;
1512 break;
1513 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001514 ErrorStringPrintf("Bad type for id section: %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001515 return false;
1516 }
1517
1518 // Check that the offset and size are what were expected from the header.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001519 if (UNLIKELY(offset != expected_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001520 ErrorStringPrintf("Bad offset for section: got %zx, expected %x", offset, expected_offset);
jeffhao10037c82012-01-23 15:06:23 -08001521 return false;
1522 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001523 if (UNLIKELY(count != expected_size)) {
1524 ErrorStringPrintf("Bad size for section: got %x, expected %x", count, expected_size);
jeffhao10037c82012-01-23 15:06:23 -08001525 return false;
1526 }
1527
1528 return CheckIntraSectionIterate(offset, count, type);
1529}
1530
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001531bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
1532 size_t data_start = header_->data_off_;
1533 size_t data_end = data_start + header_->data_size_;
jeffhao10037c82012-01-23 15:06:23 -08001534
1535 // Sanity check the offset of the section.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001536 if (UNLIKELY((offset < data_start) || (offset > data_end))) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001537 ErrorStringPrintf("Bad offset for data subsection: %zx", offset);
jeffhao10037c82012-01-23 15:06:23 -08001538 return false;
1539 }
1540
1541 if (!CheckIntraSectionIterate(offset, count, type)) {
1542 return false;
1543 }
1544
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001545 size_t next_offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001546 if (next_offset > data_end) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001547 ErrorStringPrintf("Out-of-bounds end of data subsection: %zx", next_offset);
jeffhao10037c82012-01-23 15:06:23 -08001548 return false;
1549 }
1550
1551 return true;
1552}
1553
1554bool DexFileVerifier::CheckIntraSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08001555 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001556 const DexFile::MapItem* item = map->list_;
1557
1558 uint32_t count = map->size_;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001559 size_t offset = 0;
Ian Rogers30fab402012-01-23 15:43:46 -08001560 ptr_ = begin_;
jeffhao10037c82012-01-23 15:06:23 -08001561
1562 // Check the items listed in the map.
1563 while (count--) {
1564 uint32_t section_offset = item->offset_;
1565 uint32_t section_count = item->size_;
1566 uint16_t type = item->type_;
1567
1568 // Check for padding and overlap between items.
1569 if (!CheckPadding(offset, section_offset)) {
1570 return false;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001571 } else if (UNLIKELY(offset > section_offset)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001572 ErrorStringPrintf("Section overlap or out-of-order map: %zx, %x", offset, section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001573 return false;
1574 }
1575
1576 // Check each item based on its type.
1577 switch (type) {
1578 case DexFile::kDexTypeHeaderItem:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001579 if (UNLIKELY(section_count != 1)) {
1580 ErrorStringPrintf("Multiple header items");
jeffhao10037c82012-01-23 15:06:23 -08001581 return false;
1582 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001583 if (UNLIKELY(section_offset != 0)) {
1584 ErrorStringPrintf("Header at %x, not at start of file", section_offset);
jeffhao10037c82012-01-23 15:06:23 -08001585 return false;
1586 }
Ian Rogers30fab402012-01-23 15:43:46 -08001587 ptr_ = begin_ + header_->header_size_;
jeffhao10037c82012-01-23 15:06:23 -08001588 offset = header_->header_size_;
1589 break;
1590 case DexFile::kDexTypeStringIdItem:
1591 case DexFile::kDexTypeTypeIdItem:
1592 case DexFile::kDexTypeProtoIdItem:
1593 case DexFile::kDexTypeFieldIdItem:
1594 case DexFile::kDexTypeMethodIdItem:
1595 case DexFile::kDexTypeClassDefItem:
1596 if (!CheckIntraIdSection(section_offset, section_count, type)) {
1597 return false;
1598 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001599 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001600 break;
1601 case DexFile::kDexTypeMapList:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001602 if (UNLIKELY(section_count != 1)) {
1603 ErrorStringPrintf("Multiple map list items");
jeffhao10037c82012-01-23 15:06:23 -08001604 return false;
1605 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001606 if (UNLIKELY(section_offset != header_->map_off_)) {
1607 ErrorStringPrintf("Map not at header-defined offset: %x, expected %x",
1608 section_offset, header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08001609 return false;
1610 }
1611 ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1612 offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
1613 break;
1614 case DexFile::kDexTypeTypeList:
1615 case DexFile::kDexTypeAnnotationSetRefList:
1616 case DexFile::kDexTypeAnnotationSetItem:
1617 case DexFile::kDexTypeClassDataItem:
1618 case DexFile::kDexTypeCodeItem:
1619 case DexFile::kDexTypeStringDataItem:
1620 case DexFile::kDexTypeDebugInfoItem:
1621 case DexFile::kDexTypeAnnotationItem:
1622 case DexFile::kDexTypeEncodedArrayItem:
1623 case DexFile::kDexTypeAnnotationsDirectoryItem:
1624 if (!CheckIntraDataSection(section_offset, section_count, type)) {
1625 return false;
1626 }
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001627 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08001628 break;
1629 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001630 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08001631 return false;
1632 }
1633
1634 item++;
1635 }
1636
1637 return true;
1638}
1639
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001640bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) {
Mathieu Chartier0f8e0722015-10-26 14:52:42 -07001641 DCHECK_NE(offset, 0u);
1642 auto it = offset_to_type_map_.Find(offset);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001643 if (UNLIKELY(it == offset_to_type_map_.end())) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001644 ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type);
jeffhao10037c82012-01-23 15:06:23 -08001645 return false;
1646 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001647 if (UNLIKELY(it->second != type)) {
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08001648 ErrorStringPrintf("Unexpected data map entry @ %zx; expected %x, found %x",
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001649 offset, type, it->second);
jeffhao10037c82012-01-23 15:06:23 -08001650 return false;
1651 }
1652 return true;
1653}
1654
Ian Rogers13735952014-10-08 12:43:28 -07001655uint16_t DexFileVerifier::FindFirstClassDataDefiner(const uint8_t* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001656 ClassDataItemIterator it(*dex_file_, ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001657 *success = true;
jeffhao10037c82012-01-23 15:06:23 -08001658
1659 if (it.HasNextStaticField() || it.HasNextInstanceField()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001660 LOAD_FIELD(field, it.GetMemberIndex(), "first_class_data_definer field_id",
1661 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001662 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001663 }
1664
1665 if (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001666 LOAD_METHOD(method, it.GetMemberIndex(), "first_class_data_definer method_id",
1667 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001668 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001669 }
1670
1671 return DexFile::kDexNoIndex16;
1672}
1673
Ian Rogers13735952014-10-08 12:43:28 -07001674uint16_t DexFileVerifier::FindFirstAnnotationsDirectoryDefiner(const uint8_t* ptr, bool* success) {
jeffhao10037c82012-01-23 15:06:23 -08001675 const DexFile::AnnotationsDirectoryItem* item =
1676 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001677 *success = true;
1678
jeffhao10037c82012-01-23 15:06:23 -08001679 if (item->fields_size_ != 0) {
1680 DexFile::FieldAnnotationsItem* field_items = (DexFile::FieldAnnotationsItem*) (item + 1);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001681 LOAD_FIELD(field, field_items[0].field_idx_, "first_annotations_dir_definer field_id",
1682 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001683 return field->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001684 }
1685
1686 if (item->methods_size_ != 0) {
1687 DexFile::MethodAnnotationsItem* method_items = (DexFile::MethodAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001688 LOAD_METHOD(method, method_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001689 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001690 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001691 }
1692
1693 if (item->parameters_size_ != 0) {
1694 DexFile::ParameterAnnotationsItem* parameter_items = (DexFile::ParameterAnnotationsItem*) (item + 1);
Andreas Gampee09269c2014-06-06 18:45:35 -07001695 LOAD_METHOD(method, parameter_items[0].method_idx_, "first_annotations_dir_definer method id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07001696 *success = false; return DexFile::kDexNoIndex16)
Andreas Gampee09269c2014-06-06 18:45:35 -07001697 return method->class_idx_;
jeffhao10037c82012-01-23 15:06:23 -08001698 }
1699
1700 return DexFile::kDexNoIndex16;
1701}
1702
1703bool DexFileVerifier::CheckInterStringIdItem() {
1704 const DexFile::StringId* item = reinterpret_cast<const DexFile::StringId*>(ptr_);
1705
1706 // Check the map to make sure it has the right offset->type.
1707 if (!CheckOffsetToTypeMap(item->string_data_off_, DexFile::kDexTypeStringDataItem)) {
1708 return false;
1709 }
1710
1711 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001712 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001713 const DexFile::StringId* prev_item = reinterpret_cast<const DexFile::StringId*>(previous_item_);
1714 const char* prev_str = dex_file_->GetStringData(*prev_item);
1715 const char* str = dex_file_->GetStringData(*item);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001716 if (UNLIKELY(CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(prev_str, str) >= 0)) {
1717 ErrorStringPrintf("Out-of-order string_ids: '%s' then '%s'", prev_str, str);
jeffhao10037c82012-01-23 15:06:23 -08001718 return false;
1719 }
1720 }
1721
1722 ptr_ += sizeof(DexFile::StringId);
1723 return true;
1724}
1725
1726bool DexFileVerifier::CheckInterTypeIdItem() {
1727 const DexFile::TypeId* item = reinterpret_cast<const DexFile::TypeId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001728
1729 LOAD_STRING(descriptor, item->descriptor_idx_, "inter_type_id_item descriptor_idx")
jeffhao10037c82012-01-23 15:06:23 -08001730
1731 // Check that the descriptor is a valid type.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001732 if (UNLIKELY(!IsValidDescriptor(descriptor))) {
1733 ErrorStringPrintf("Invalid type descriptor: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001734 return false;
1735 }
1736
1737 // Check ordering between items.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001738 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001739 const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001740 if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
1741 ErrorStringPrintf("Out-of-order type_ids: %x then %x",
1742 prev_item->descriptor_idx_, item->descriptor_idx_);
jeffhao10037c82012-01-23 15:06:23 -08001743 return false;
1744 }
1745 }
1746
1747 ptr_ += sizeof(DexFile::TypeId);
1748 return true;
1749}
1750
1751bool DexFileVerifier::CheckInterProtoIdItem() {
1752 const DexFile::ProtoId* item = reinterpret_cast<const DexFile::ProtoId*>(ptr_);
Andreas Gampee09269c2014-06-06 18:45:35 -07001753
1754 LOAD_STRING(shorty, item->shorty_idx_, "inter_proto_id_item shorty_idx")
1755
jeffhao10037c82012-01-23 15:06:23 -08001756 if (item->parameters_off_ != 0 &&
1757 !CheckOffsetToTypeMap(item->parameters_off_, DexFile::kDexTypeTypeList)) {
1758 return false;
1759 }
1760
1761 // Check the return type and advance the shorty.
Andreas Gampee09269c2014-06-06 18:45:35 -07001762 LOAD_STRING_BY_TYPE(return_type, item->return_type_idx_, "inter_proto_id_item return_type_idx")
1763 if (!CheckShortyDescriptorMatch(*shorty, return_type, true)) {
jeffhao10037c82012-01-23 15:06:23 -08001764 return false;
1765 }
1766 shorty++;
1767
1768 DexFileParameterIterator it(*dex_file_, *item);
1769 while (it.HasNext() && *shorty != '\0') {
Andreas Gampebb836e12014-06-13 15:31:40 -07001770 if (!CheckIndex(it.GetTypeIdx(), dex_file_->NumTypeIds(),
1771 "inter_proto_id_item shorty type_idx")) {
1772 return false;
1773 }
jeffhao10037c82012-01-23 15:06:23 -08001774 const char* descriptor = it.GetDescriptor();
1775 if (!CheckShortyDescriptorMatch(*shorty, descriptor, false)) {
1776 return false;
1777 }
1778 it.Next();
1779 shorty++;
1780 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001781 if (UNLIKELY(it.HasNext() || *shorty != '\0')) {
1782 ErrorStringPrintf("Mismatched length for parameters and shorty");
jeffhao10037c82012-01-23 15:06:23 -08001783 return false;
1784 }
1785
1786 // Check ordering between items. This relies on type_ids being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001787 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001788 const DexFile::ProtoId* prev = reinterpret_cast<const DexFile::ProtoId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001789 if (UNLIKELY(prev->return_type_idx_ > item->return_type_idx_)) {
1790 ErrorStringPrintf("Out-of-order proto_id return types");
jeffhao10037c82012-01-23 15:06:23 -08001791 return false;
1792 } else if (prev->return_type_idx_ == item->return_type_idx_) {
1793 DexFileParameterIterator curr_it(*dex_file_, *item);
1794 DexFileParameterIterator prev_it(*dex_file_, *prev);
1795
1796 while (curr_it.HasNext() && prev_it.HasNext()) {
1797 uint16_t prev_idx = prev_it.GetTypeIdx();
1798 uint16_t curr_idx = curr_it.GetTypeIdx();
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001799 DCHECK_NE(prev_idx, DexFile::kDexNoIndex16);
1800 DCHECK_NE(curr_idx, DexFile::kDexNoIndex16);
jeffhao10037c82012-01-23 15:06:23 -08001801
1802 if (prev_idx < curr_idx) {
1803 break;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001804 } else if (UNLIKELY(prev_idx > curr_idx)) {
1805 ErrorStringPrintf("Out-of-order proto_id arguments");
jeffhao10037c82012-01-23 15:06:23 -08001806 return false;
1807 }
1808
1809 prev_it.Next();
1810 curr_it.Next();
1811 }
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001812 if (!curr_it.HasNext()) {
1813 // Either a duplicate ProtoId or a ProtoId with a shorter argument list follows
1814 // a ProtoId with a longer one. Both cases are forbidden by the specification.
1815 ErrorStringPrintf("Out-of-order proto_id arguments");
1816 return false;
1817 }
jeffhao10037c82012-01-23 15:06:23 -08001818 }
1819 }
1820
1821 ptr_ += sizeof(DexFile::ProtoId);
1822 return true;
1823}
1824
1825bool DexFileVerifier::CheckInterFieldIdItem() {
1826 const DexFile::FieldId* item = reinterpret_cast<const DexFile::FieldId*>(ptr_);
1827
1828 // Check that the class descriptor is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001829 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_field_id_item class_idx")
1830 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1831 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001832 return false;
1833 }
1834
1835 // Check that the type descriptor is a valid field name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001836 LOAD_STRING_BY_TYPE(type_descriptor, item->type_idx_, "inter_field_id_item type_idx")
1837 if (UNLIKELY(!IsValidDescriptor(type_descriptor) || type_descriptor[0] == 'V')) {
1838 ErrorStringPrintf("Invalid descriptor for type_idx: '%s'", type_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001839 return false;
1840 }
1841
1842 // Check that the name is valid.
Andreas Gampee09269c2014-06-06 18:45:35 -07001843 LOAD_STRING(descriptor, item->name_idx_, "inter_field_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001844 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1845 ErrorStringPrintf("Invalid field name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001846 return false;
1847 }
1848
1849 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001850 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001851 const DexFile::FieldId* prev_item = reinterpret_cast<const DexFile::FieldId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001852 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1853 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001854 return false;
1855 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001856 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1857 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001858 return false;
1859 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001860 if (UNLIKELY(prev_item->type_idx_ >= item->type_idx_)) {
1861 ErrorStringPrintf("Out-of-order field_ids");
jeffhao10037c82012-01-23 15:06:23 -08001862 return false;
1863 }
1864 }
1865 }
1866 }
1867
1868 ptr_ += sizeof(DexFile::FieldId);
1869 return true;
1870}
1871
1872bool DexFileVerifier::CheckInterMethodIdItem() {
1873 const DexFile::MethodId* item = reinterpret_cast<const DexFile::MethodId*>(ptr_);
1874
1875 // Check that the class descriptor is a valid reference name.
Andreas Gampee09269c2014-06-06 18:45:35 -07001876 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_method_id_item class_idx")
1877 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || (class_descriptor[0] != 'L' &&
1878 class_descriptor[0] != '['))) {
1879 ErrorStringPrintf("Invalid descriptor for class_idx: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001880 return false;
1881 }
1882
1883 // Check that the name is valid.
Andreas Gampedf10b322014-06-11 21:46:05 -07001884 LOAD_STRING(descriptor, item->name_idx_, "inter_method_id_item name_idx")
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001885 if (UNLIKELY(!IsValidMemberName(descriptor))) {
1886 ErrorStringPrintf("Invalid method name: '%s'", descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001887 return false;
1888 }
1889
Andreas Gampedf10b322014-06-11 21:46:05 -07001890 // Check that the proto id is valid.
1891 if (UNLIKELY(!CheckIndex(item->proto_idx_, dex_file_->NumProtoIds(),
1892 "inter_method_id_item proto_idx"))) {
1893 return false;
1894 }
1895
jeffhao10037c82012-01-23 15:06:23 -08001896 // Check ordering between items. This relies on the other sections being in order.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001897 if (previous_item_ != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001898 const DexFile::MethodId* prev_item = reinterpret_cast<const DexFile::MethodId*>(previous_item_);
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001899 if (UNLIKELY(prev_item->class_idx_ > item->class_idx_)) {
1900 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001901 return false;
1902 } else if (prev_item->class_idx_ == item->class_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001903 if (UNLIKELY(prev_item->name_idx_ > item->name_idx_)) {
1904 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001905 return false;
1906 } else if (prev_item->name_idx_ == item->name_idx_) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001907 if (UNLIKELY(prev_item->proto_idx_ >= item->proto_idx_)) {
1908 ErrorStringPrintf("Out-of-order method_ids");
jeffhao10037c82012-01-23 15:06:23 -08001909 return false;
1910 }
1911 }
1912 }
1913 }
1914
1915 ptr_ += sizeof(DexFile::MethodId);
1916 return true;
1917}
1918
1919bool DexFileVerifier::CheckInterClassDefItem() {
1920 const DexFile::ClassDef* item = reinterpret_cast<const DexFile::ClassDef*>(ptr_);
jeffhao10037c82012-01-23 15:06:23 -08001921
Andreas Gampe0ba238d2014-07-29 01:22:07 -07001922 // Check for duplicate class def.
1923 if (defined_classes_.find(item->class_idx_) != defined_classes_.end()) {
1924 ErrorStringPrintf("Redefinition of class with type idx: '%d'", item->class_idx_);
1925 return false;
1926 }
1927 defined_classes_.insert(item->class_idx_);
1928
Andreas Gampee09269c2014-06-06 18:45:35 -07001929 LOAD_STRING_BY_TYPE(class_descriptor, item->class_idx_, "inter_class_def_item class_idx")
1930 if (UNLIKELY(!IsValidDescriptor(class_descriptor) || class_descriptor[0] != 'L')) {
1931 ErrorStringPrintf("Invalid class descriptor: '%s'", class_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001932 return false;
1933 }
1934
Andreas Gampeacc2bb62014-07-17 19:26:50 -07001935 // Only allow non-runtime modifiers.
1936 if ((item->access_flags_ & ~kAccJavaFlagsMask) != 0) {
1937 ErrorStringPrintf("Invalid class flags: '%d'", item->access_flags_);
1938 return false;
1939 }
1940
jeffhao10037c82012-01-23 15:06:23 -08001941 if (item->interfaces_off_ != 0 &&
1942 !CheckOffsetToTypeMap(item->interfaces_off_, DexFile::kDexTypeTypeList)) {
1943 return false;
1944 }
1945 if (item->annotations_off_ != 0 &&
1946 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationsDirectoryItem)) {
1947 return false;
1948 }
1949 if (item->class_data_off_ != 0 &&
1950 !CheckOffsetToTypeMap(item->class_data_off_, DexFile::kDexTypeClassDataItem)) {
1951 return false;
1952 }
1953 if (item->static_values_off_ != 0 &&
1954 !CheckOffsetToTypeMap(item->static_values_off_, DexFile::kDexTypeEncodedArrayItem)) {
1955 return false;
1956 }
1957
1958 if (item->superclass_idx_ != DexFile::kDexNoIndex16) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001959 LOAD_STRING_BY_TYPE(superclass_descriptor, item->superclass_idx_,
1960 "inter_class_def_item superclass_idx")
1961 if (UNLIKELY(!IsValidDescriptor(superclass_descriptor) || superclass_descriptor[0] != 'L')) {
1962 ErrorStringPrintf("Invalid superclass: '%s'", superclass_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001963 return false;
1964 }
1965 }
1966
1967 const DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(*item);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001968 if (interfaces != nullptr) {
jeffhao10037c82012-01-23 15:06:23 -08001969 uint32_t size = interfaces->Size();
1970
1971 // Ensure that all interfaces refer to classes (not arrays or primitives).
1972 for (uint32_t i = 0; i < size; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07001973 LOAD_STRING_BY_TYPE(inf_descriptor, interfaces->GetTypeItem(i).type_idx_,
1974 "inter_class_def_item interface type_idx")
1975 if (UNLIKELY(!IsValidDescriptor(inf_descriptor) || inf_descriptor[0] != 'L')) {
1976 ErrorStringPrintf("Invalid interface: '%s'", inf_descriptor);
jeffhao10037c82012-01-23 15:06:23 -08001977 return false;
1978 }
1979 }
1980
1981 /*
1982 * Ensure that there are no duplicates. This is an O(N^2) test, but in
1983 * practice the number of interfaces implemented by any given class is low.
1984 */
1985 for (uint32_t i = 1; i < size; i++) {
1986 uint32_t idx1 = interfaces->GetTypeItem(i).type_idx_;
1987 for (uint32_t j =0; j < i; j++) {
1988 uint32_t idx2 = interfaces->GetTypeItem(j).type_idx_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001989 if (UNLIKELY(idx1 == idx2)) {
1990 ErrorStringPrintf("Duplicate interface: '%s'", dex_file_->StringByTypeIdx(idx1));
jeffhao10037c82012-01-23 15:06:23 -08001991 return false;
1992 }
1993 }
1994 }
1995 }
1996
1997 // Check that references in class_data_item are to the right class.
1998 if (item->class_data_off_ != 0) {
Ian Rogers13735952014-10-08 12:43:28 -07001999 const uint8_t* data = begin_ + item->class_data_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002000 bool success;
2001 uint16_t data_definer = FindFirstClassDataDefiner(data, &success);
2002 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002003 return false;
2004 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002005 if (UNLIKELY((data_definer != item->class_idx_) && (data_definer != DexFile::kDexNoIndex16))) {
2006 ErrorStringPrintf("Invalid class_data_item");
jeffhao10037c82012-01-23 15:06:23 -08002007 return false;
2008 }
2009 }
2010
2011 // Check that references in annotations_directory_item are to right class.
2012 if (item->annotations_off_ != 0) {
Andreas Gampeb512c0e2016-02-19 19:45:34 -08002013 // annotations_off_ is supposed to be aligned by 4.
2014 if (!IsAlignedParam(item->annotations_off_, 4)) {
2015 ErrorStringPrintf("Invalid annotations_off_, not aligned by 4");
2016 return false;
2017 }
Ian Rogers13735952014-10-08 12:43:28 -07002018 const uint8_t* data = begin_ + item->annotations_off_;
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002019 bool success;
2020 uint16_t annotations_definer = FindFirstAnnotationsDirectoryDefiner(data, &success);
2021 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002022 return false;
2023 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002024 if (UNLIKELY((annotations_definer != item->class_idx_) &&
2025 (annotations_definer != DexFile::kDexNoIndex16))) {
2026 ErrorStringPrintf("Invalid annotations_directory_item");
jeffhao10037c82012-01-23 15:06:23 -08002027 return false;
2028 }
2029 }
2030
2031 ptr_ += sizeof(DexFile::ClassDef);
2032 return true;
2033}
2034
2035bool DexFileVerifier::CheckInterAnnotationSetRefList() {
2036 const DexFile::AnnotationSetRefList* list =
2037 reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
2038 const DexFile::AnnotationSetRefItem* item = list->list_;
2039 uint32_t count = list->size_;
2040
2041 while (count--) {
2042 if (item->annotations_off_ != 0 &&
2043 !CheckOffsetToTypeMap(item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2044 return false;
2045 }
2046 item++;
2047 }
2048
Ian Rogers13735952014-10-08 12:43:28 -07002049 ptr_ = reinterpret_cast<const uint8_t*>(item);
jeffhao10037c82012-01-23 15:06:23 -08002050 return true;
2051}
2052
2053bool DexFileVerifier::CheckInterAnnotationSetItem() {
2054 const DexFile::AnnotationSetItem* set = reinterpret_cast<const DexFile::AnnotationSetItem*>(ptr_);
2055 const uint32_t* offsets = set->entries_;
2056 uint32_t count = set->size_;
2057 uint32_t last_idx = 0;
2058
2059 for (uint32_t i = 0; i < count; i++) {
2060 if (*offsets != 0 && !CheckOffsetToTypeMap(*offsets, DexFile::kDexTypeAnnotationItem)) {
2061 return false;
2062 }
2063
2064 // Get the annotation from the offset and the type index for the annotation.
2065 const DexFile::AnnotationItem* annotation =
Ian Rogers30fab402012-01-23 15:43:46 -08002066 reinterpret_cast<const DexFile::AnnotationItem*>(begin_ + *offsets);
jeffhao10037c82012-01-23 15:06:23 -08002067 const uint8_t* data = annotation->annotation_;
2068 uint32_t idx = DecodeUnsignedLeb128(&data);
2069
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002070 if (UNLIKELY(last_idx >= idx && i != 0)) {
2071 ErrorStringPrintf("Out-of-order entry types: %x then %x", last_idx, idx);
jeffhao10037c82012-01-23 15:06:23 -08002072 return false;
2073 }
2074
2075 last_idx = idx;
2076 offsets++;
2077 }
2078
Ian Rogers13735952014-10-08 12:43:28 -07002079 ptr_ = reinterpret_cast<const uint8_t*>(offsets);
jeffhao10037c82012-01-23 15:06:23 -08002080 return true;
2081}
2082
2083bool DexFileVerifier::CheckInterClassDataItem() {
2084 ClassDataItemIterator it(*dex_file_, ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002085 bool success;
2086 uint16_t defining_class = FindFirstClassDataDefiner(ptr_, &success);
2087 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002088 return false;
2089 }
jeffhao10037c82012-01-23 15:06:23 -08002090
2091 for (; it.HasNextStaticField() || it.HasNextInstanceField(); it.Next()) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002092 LOAD_FIELD(field, it.GetMemberIndex(), "inter_class_data_item field_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002093 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002094 ErrorStringPrintf("Mismatched defining class for class_data_item field");
jeffhao10037c82012-01-23 15:06:23 -08002095 return false;
2096 }
2097 }
2098 for (; it.HasNextDirectMethod() || it.HasNextVirtualMethod(); it.Next()) {
2099 uint32_t code_off = it.GetMethodCodeItemOffset();
2100 if (code_off != 0 && !CheckOffsetToTypeMap(code_off, DexFile::kDexTypeCodeItem)) {
2101 return false;
2102 }
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002103 LOAD_METHOD(method, it.GetMemberIndex(), "inter_class_data_item method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002104 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002105 ErrorStringPrintf("Mismatched defining class for class_data_item method");
jeffhao10037c82012-01-23 15:06:23 -08002106 return false;
2107 }
2108 }
2109
2110 ptr_ = it.EndDataPointer();
2111 return true;
2112}
2113
2114bool DexFileVerifier::CheckInterAnnotationsDirectoryItem() {
2115 const DexFile::AnnotationsDirectoryItem* item =
2116 reinterpret_cast<const DexFile::AnnotationsDirectoryItem*>(ptr_);
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002117 bool success;
2118 uint16_t defining_class = FindFirstAnnotationsDirectoryDefiner(ptr_, &success);
2119 if (!success) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002120 return false;
2121 }
jeffhao10037c82012-01-23 15:06:23 -08002122
2123 if (item->class_annotations_off_ != 0 &&
2124 !CheckOffsetToTypeMap(item->class_annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2125 return false;
2126 }
2127
2128 // Field annotations follow immediately after the annotations directory.
2129 const DexFile::FieldAnnotationsItem* field_item =
2130 reinterpret_cast<const DexFile::FieldAnnotationsItem*>(item + 1);
2131 uint32_t field_count = item->fields_size_;
2132 for (uint32_t i = 0; i < field_count; i++) {
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002133 LOAD_FIELD(field, field_item->field_idx_, "inter_annotations_directory_item field_id",
2134 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002135 if (UNLIKELY(field->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002136 ErrorStringPrintf("Mismatched defining class for field_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002137 return false;
2138 }
2139 if (!CheckOffsetToTypeMap(field_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2140 return false;
2141 }
2142 field_item++;
2143 }
2144
2145 // Method annotations follow immediately after field annotations.
2146 const DexFile::MethodAnnotationsItem* method_item =
2147 reinterpret_cast<const DexFile::MethodAnnotationsItem*>(field_item);
2148 uint32_t method_count = item->methods_size_;
2149 for (uint32_t i = 0; i < method_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002150 LOAD_METHOD(method, method_item->method_idx_, "inter_annotations_directory_item method_id",
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002151 return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002152 if (UNLIKELY(method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002153 ErrorStringPrintf("Mismatched defining class for method_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002154 return false;
2155 }
2156 if (!CheckOffsetToTypeMap(method_item->annotations_off_, DexFile::kDexTypeAnnotationSetItem)) {
2157 return false;
2158 }
2159 method_item++;
2160 }
2161
2162 // Parameter annotations follow immediately after method annotations.
2163 const DexFile::ParameterAnnotationsItem* parameter_item =
2164 reinterpret_cast<const DexFile::ParameterAnnotationsItem*>(method_item);
2165 uint32_t parameter_count = item->parameters_size_;
2166 for (uint32_t i = 0; i < parameter_count; i++) {
Andreas Gampee09269c2014-06-06 18:45:35 -07002167 LOAD_METHOD(parameter_method, parameter_item->method_idx_,
Andreas Gampe5e31dda2014-06-13 11:35:12 -07002168 "inter_annotations_directory_item parameter method_id", return false)
Andreas Gampee09269c2014-06-06 18:45:35 -07002169 if (UNLIKELY(parameter_method->class_idx_ != defining_class)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002170 ErrorStringPrintf("Mismatched defining class for parameter_annotation");
jeffhao10037c82012-01-23 15:06:23 -08002171 return false;
2172 }
Dragos Sbirlea2b87ddf2013-05-28 14:14:12 -07002173 if (!CheckOffsetToTypeMap(parameter_item->annotations_off_,
2174 DexFile::kDexTypeAnnotationSetRefList)) {
jeffhao10037c82012-01-23 15:06:23 -08002175 return false;
2176 }
2177 parameter_item++;
2178 }
2179
Ian Rogers13735952014-10-08 12:43:28 -07002180 ptr_ = reinterpret_cast<const uint8_t*>(parameter_item);
jeffhao10037c82012-01-23 15:06:23 -08002181 return true;
2182}
2183
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002184bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
jeffhao10037c82012-01-23 15:06:23 -08002185 // Get the right alignment mask for the type of section.
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002186 size_t alignment_mask;
jeffhao10037c82012-01-23 15:06:23 -08002187 switch (type) {
2188 case DexFile::kDexTypeClassDataItem:
2189 alignment_mask = sizeof(uint8_t) - 1;
2190 break;
2191 default:
2192 alignment_mask = sizeof(uint32_t) - 1;
2193 break;
2194 }
2195
2196 // Iterate through the items in the section.
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002197 previous_item_ = nullptr;
jeffhao10037c82012-01-23 15:06:23 -08002198 for (uint32_t i = 0; i < count; i++) {
2199 uint32_t new_offset = (offset + alignment_mask) & ~alignment_mask;
Ian Rogers30fab402012-01-23 15:43:46 -08002200 ptr_ = begin_ + new_offset;
Ian Rogers13735952014-10-08 12:43:28 -07002201 const uint8_t* prev_ptr = ptr_;
jeffhao10037c82012-01-23 15:06:23 -08002202
2203 // Check depending on the section type.
2204 switch (type) {
2205 case DexFile::kDexTypeStringIdItem: {
2206 if (!CheckInterStringIdItem()) {
2207 return false;
2208 }
2209 break;
2210 }
2211 case DexFile::kDexTypeTypeIdItem: {
2212 if (!CheckInterTypeIdItem()) {
2213 return false;
2214 }
2215 break;
2216 }
2217 case DexFile::kDexTypeProtoIdItem: {
2218 if (!CheckInterProtoIdItem()) {
2219 return false;
2220 }
2221 break;
2222 }
2223 case DexFile::kDexTypeFieldIdItem: {
2224 if (!CheckInterFieldIdItem()) {
2225 return false;
2226 }
2227 break;
2228 }
2229 case DexFile::kDexTypeMethodIdItem: {
2230 if (!CheckInterMethodIdItem()) {
2231 return false;
2232 }
2233 break;
2234 }
2235 case DexFile::kDexTypeClassDefItem: {
2236 if (!CheckInterClassDefItem()) {
2237 return false;
2238 }
2239 break;
2240 }
2241 case DexFile::kDexTypeAnnotationSetRefList: {
2242 if (!CheckInterAnnotationSetRefList()) {
2243 return false;
2244 }
2245 break;
2246 }
2247 case DexFile::kDexTypeAnnotationSetItem: {
2248 if (!CheckInterAnnotationSetItem()) {
2249 return false;
2250 }
2251 break;
2252 }
2253 case DexFile::kDexTypeClassDataItem: {
2254 if (!CheckInterClassDataItem()) {
2255 return false;
2256 }
2257 break;
2258 }
2259 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2260 if (!CheckInterAnnotationsDirectoryItem()) {
2261 return false;
2262 }
2263 break;
2264 }
2265 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002266 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002267 return false;
2268 }
2269
2270 previous_item_ = prev_ptr;
Ian Rogers8a6bbfc2014-01-23 13:29:07 -08002271 offset = ptr_ - begin_;
jeffhao10037c82012-01-23 15:06:23 -08002272 }
2273
2274 return true;
2275}
2276
2277bool DexFileVerifier::CheckInterSection() {
Ian Rogers30fab402012-01-23 15:43:46 -08002278 const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
jeffhao10037c82012-01-23 15:06:23 -08002279 const DexFile::MapItem* item = map->list_;
2280 uint32_t count = map->size_;
2281
2282 // Cross check the items listed in the map.
2283 while (count--) {
2284 uint32_t section_offset = item->offset_;
2285 uint32_t section_count = item->size_;
2286 uint16_t type = item->type_;
2287
2288 switch (type) {
2289 case DexFile::kDexTypeHeaderItem:
2290 case DexFile::kDexTypeMapList:
2291 case DexFile::kDexTypeTypeList:
2292 case DexFile::kDexTypeCodeItem:
2293 case DexFile::kDexTypeStringDataItem:
2294 case DexFile::kDexTypeDebugInfoItem:
2295 case DexFile::kDexTypeAnnotationItem:
2296 case DexFile::kDexTypeEncodedArrayItem:
2297 break;
2298 case DexFile::kDexTypeStringIdItem:
2299 case DexFile::kDexTypeTypeIdItem:
2300 case DexFile::kDexTypeProtoIdItem:
2301 case DexFile::kDexTypeFieldIdItem:
2302 case DexFile::kDexTypeMethodIdItem:
2303 case DexFile::kDexTypeClassDefItem:
2304 case DexFile::kDexTypeAnnotationSetRefList:
2305 case DexFile::kDexTypeAnnotationSetItem:
2306 case DexFile::kDexTypeClassDataItem:
2307 case DexFile::kDexTypeAnnotationsDirectoryItem: {
2308 if (!CheckInterSectionIterate(section_offset, section_count, type)) {
2309 return false;
2310 }
2311 break;
2312 }
2313 default:
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002314 ErrorStringPrintf("Unknown map item type %x", type);
jeffhao10037c82012-01-23 15:06:23 -08002315 return false;
2316 }
2317
2318 item++;
2319 }
2320
2321 return true;
2322}
2323
2324bool DexFileVerifier::Verify() {
2325 // Check the header.
2326 if (!CheckHeader()) {
2327 return false;
2328 }
2329
2330 // Check the map section.
2331 if (!CheckMap()) {
2332 return false;
2333 }
2334
2335 // Check structure within remaining sections.
2336 if (!CheckIntraSection()) {
2337 return false;
2338 }
2339
2340 // Check references from one section to another.
2341 if (!CheckInterSection()) {
2342 return false;
2343 }
2344
2345 return true;
2346}
2347
Ian Rogers8d31bbd2013-10-13 10:44:14 -07002348void DexFileVerifier::ErrorStringPrintf(const char* fmt, ...) {
2349 va_list ap;
2350 va_start(ap, fmt);
2351 DCHECK(failure_reason_.empty()) << failure_reason_;
2352 failure_reason_ = StringPrintf("Failure to verify dex file '%s': ", location_);
2353 StringAppendV(&failure_reason_, fmt, ap);
2354 va_end(ap);
2355}
2356
Andreas Gampee6215c02015-08-31 18:54:38 -07002357// Fields and methods may have only one of public/protected/private.
2358static bool CheckAtMostOneOfPublicProtectedPrivate(uint32_t flags) {
2359 size_t count = (((flags & kAccPublic) == 0) ? 0 : 1) +
2360 (((flags & kAccProtected) == 0) ? 0 : 1) +
2361 (((flags & kAccPrivate) == 0) ? 0 : 1);
2362 return count <= 1;
2363}
2364
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002365// Helper functions to retrieve names from the dex file. We do not want to rely on DexFile
2366// functionality, as we're still verifying the dex file. begin and header correspond to the
2367// underscored variants in the DexFileVerifier.
2368
2369static std::string GetStringOrError(const uint8_t* const begin,
2370 const DexFile::Header* const header,
2371 uint32_t string_idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002372 // The `string_idx` is not guaranteed to be valid yet.
2373 if (header->string_ids_size_ <= string_idx) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002374 return "(error)";
2375 }
2376
2377 const DexFile::StringId* string_id =
2378 reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx;
2379
2380 // Assume that the data is OK at this point. String data has been checked at this point.
2381
2382 const uint8_t* ptr = begin + string_id->string_data_off_;
2383 DecodeUnsignedLeb128(&ptr);
2384 return reinterpret_cast<const char*>(ptr);
2385}
2386
2387static std::string GetClassOrError(const uint8_t* const begin,
2388 const DexFile::Header* const header,
2389 uint32_t class_idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002390 // The `class_idx` is either `FieldId::class_idx_` or `MethodId::class_idx_` and
2391 // it has already been checked in `DexFileVerifier::CheckClassDataItemField()`
2392 // or `DexFileVerifier::CheckClassDataItemMethod()`, respectively, to match
2393 // a valid defining class.
2394 CHECK_LT(class_idx, header->type_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002395
2396 const DexFile::TypeId* type_id =
2397 reinterpret_cast<const DexFile::TypeId*>(begin + header->type_ids_off_) + class_idx;
2398
2399 // Assume that the data is OK at this point. Type id offsets have been checked at this point.
2400
2401 return GetStringOrError(begin, header, type_id->descriptor_idx_);
2402}
2403
2404static std::string GetFieldDescriptionOrError(const uint8_t* const begin,
2405 const DexFile::Header* const header,
2406 uint32_t idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002407 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemField()`.
2408 CHECK_LT(idx, header->field_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002409
2410 const DexFile::FieldId* field_id =
2411 reinterpret_cast<const DexFile::FieldId*>(begin + header->field_ids_off_) + idx;
2412
2413 // Assume that the data is OK at this point. Field id offsets have been checked at this point.
2414
2415 std::string class_name = GetClassOrError(begin, header, field_id->class_idx_);
2416 std::string field_name = GetStringOrError(begin, header, field_id->name_idx_);
2417
2418 return class_name + "." + field_name;
2419}
2420
2421static std::string GetMethodDescriptionOrError(const uint8_t* const begin,
2422 const DexFile::Header* const header,
2423 uint32_t idx) {
Vladimir Marko59399ab2016-05-03 16:31:52 +01002424 // The `idx` has already been checked in `DexFileVerifier::CheckClassDataItemMethod()`.
2425 CHECK_LT(idx, header->method_ids_size_);
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002426
2427 const DexFile::MethodId* method_id =
2428 reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) + idx;
2429
2430 // Assume that the data is OK at this point. Method id offsets have been checked at this point.
2431
2432 std::string class_name = GetClassOrError(begin, header, method_id->class_idx_);
2433 std::string method_name = GetStringOrError(begin, header, method_id->name_idx_);
2434
2435 return class_name + "." + method_name;
2436}
2437
2438bool DexFileVerifier::CheckFieldAccessFlags(uint32_t idx,
2439 uint32_t field_access_flags,
Andreas Gampee6215c02015-08-31 18:54:38 -07002440 uint32_t class_access_flags,
2441 std::string* error_msg) {
2442 // Generally sort out >16-bit flags.
2443 if ((field_access_flags & ~kAccJavaFlagsMask) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002444 *error_msg = StringPrintf("Bad field access_flags for %s: %x(%s)",
2445 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2446 field_access_flags,
2447 PrettyJavaAccessFlags(field_access_flags).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002448 return false;
2449 }
2450
2451 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
2452 constexpr uint32_t kFieldAccessFlags = kAccPublic |
2453 kAccPrivate |
2454 kAccProtected |
2455 kAccStatic |
2456 kAccFinal |
2457 kAccVolatile |
2458 kAccTransient |
2459 kAccSynthetic |
2460 kAccEnum;
2461
2462 // Fields may have only one of public/protected/final.
2463 if (!CheckAtMostOneOfPublicProtectedPrivate(field_access_flags)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002464 *error_msg = StringPrintf("Field may have only one of public/protected/private, %s: %x(%s)",
2465 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2466 field_access_flags,
2467 PrettyJavaAccessFlags(field_access_flags).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002468 return false;
2469 }
2470
2471 // Interfaces have a pretty restricted list.
2472 if ((class_access_flags & kAccInterface) != 0) {
2473 // Interface fields must be public final static.
2474 constexpr uint32_t kPublicFinalStatic = kAccPublic | kAccFinal | kAccStatic;
2475 if ((field_access_flags & kPublicFinalStatic) != kPublicFinalStatic) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002476 *error_msg = StringPrintf("Interface field is not public final static, %s: %x(%s)",
2477 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2478 field_access_flags,
2479 PrettyJavaAccessFlags(field_access_flags).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002480 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002481 return false;
2482 } else {
2483 // Allow in older versions, but warn.
2484 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2485 << *error_msg;
2486 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002487 }
2488 // Interface fields may be synthetic, but may not have other flags.
2489 constexpr uint32_t kDisallowed = ~(kPublicFinalStatic | kAccSynthetic);
2490 if ((field_access_flags & kFieldAccessFlags & kDisallowed) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002491 *error_msg = StringPrintf("Interface field has disallowed flag, %s: %x(%s)",
2492 GetFieldDescriptionOrError(begin_, header_, idx).c_str(),
2493 field_access_flags,
2494 PrettyJavaAccessFlags(field_access_flags).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002495 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002496 return false;
2497 } else {
2498 // Allow in older versions, but warn.
2499 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2500 << *error_msg;
2501 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002502 }
2503 return true;
2504 }
2505
2506 // Volatile fields may not be final.
2507 constexpr uint32_t kVolatileFinal = kAccVolatile | kAccFinal;
2508 if ((field_access_flags & kVolatileFinal) == kVolatileFinal) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002509 *error_msg = StringPrintf("Fields may not be volatile and final: %s",
2510 GetFieldDescriptionOrError(begin_, header_, idx).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002511 return false;
2512 }
2513
2514 return true;
2515}
2516
2517// Try to find the name of the method with the given index. We do not want to rely on DexFile
2518// infrastructure at this point, so do it all by hand. begin and header correspond to begin_ and
2519// header_ of the DexFileVerifier. str will contain the pointer to the method name on success
2520// (flagged by the return value), otherwise error_msg will contain an error string.
2521static bool FindMethodName(uint32_t method_index,
2522 const uint8_t* begin,
2523 const DexFile::Header* header,
2524 const char** str,
2525 std::string* error_msg) {
2526 if (method_index >= header->method_ids_size_) {
2527 *error_msg = "Method index not available for method flags verification";
2528 return false;
2529 }
2530 uint32_t string_idx =
2531 (reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) +
2532 method_index)->name_idx_;
2533 if (string_idx >= header->string_ids_size_) {
2534 *error_msg = "String index not available for method flags verification";
2535 return false;
2536 }
2537 uint32_t string_off =
2538 (reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx)->
2539 string_data_off_;
2540 if (string_off >= header->file_size_) {
2541 *error_msg = "String offset out of bounds for method flags verification";
2542 return false;
2543 }
2544 const uint8_t* str_data_ptr = begin + string_off;
2545 DecodeUnsignedLeb128(&str_data_ptr);
2546 *str = reinterpret_cast<const char*>(str_data_ptr);
2547 return true;
2548}
2549
2550bool DexFileVerifier::CheckMethodAccessFlags(uint32_t method_index,
2551 uint32_t method_access_flags,
2552 uint32_t class_access_flags,
2553 bool has_code,
2554 bool expect_direct,
2555 std::string* error_msg) {
2556 // Generally sort out >16-bit flags, except dex knows Constructor and DeclaredSynchronized.
2557 constexpr uint32_t kAllMethodFlags =
2558 kAccJavaFlagsMask | kAccConstructor | kAccDeclaredSynchronized;
2559 if ((method_access_flags & ~kAllMethodFlags) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002560 *error_msg = StringPrintf("Bad method access_flags for %s: %x",
2561 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
2562 method_access_flags);
Andreas Gampee6215c02015-08-31 18:54:38 -07002563 return false;
2564 }
2565
2566 // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored.
2567 constexpr uint32_t kMethodAccessFlags = kAccPublic |
2568 kAccPrivate |
2569 kAccProtected |
2570 kAccStatic |
2571 kAccFinal |
2572 kAccSynthetic |
2573 kAccSynchronized |
2574 kAccBridge |
2575 kAccVarargs |
2576 kAccNative |
2577 kAccAbstract |
2578 kAccStrict;
2579
2580 // Methods may have only one of public/protected/final.
2581 if (!CheckAtMostOneOfPublicProtectedPrivate(method_access_flags)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002582 *error_msg = StringPrintf("Method may have only one of public/protected/private, %s: %x",
2583 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002584 method_access_flags);
2585 return false;
2586 }
2587
2588 // Try to find the name, to check for constructor properties.
2589 const char* str;
2590 if (!FindMethodName(method_index, begin_, header_, &str, error_msg)) {
2591 return false;
2592 }
2593 bool is_init_by_name = false;
2594 constexpr const char* kInitName = "<init>";
2595 size_t str_offset = (reinterpret_cast<const uint8_t*>(str) - begin_);
2596 if (header_->file_size_ - str_offset >= sizeof(kInitName)) {
2597 is_init_by_name = strcmp(kInitName, str) == 0;
2598 }
2599 bool is_clinit_by_name = false;
2600 constexpr const char* kClinitName = "<clinit>";
2601 if (header_->file_size_ - str_offset >= sizeof(kClinitName)) {
2602 is_clinit_by_name = strcmp(kClinitName, str) == 0;
2603 }
2604 bool is_constructor = is_init_by_name || is_clinit_by_name;
2605
2606 // Only methods named "<clinit>" or "<init>" may be marked constructor. Note: we cannot enforce
2607 // the reverse for backwards compatibility reasons.
2608 if (((method_access_flags & kAccConstructor) != 0) && !is_constructor) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002609 *error_msg =
2610 StringPrintf("Method %" PRIu32 "(%s) is marked constructor, but doesn't match name",
2611 method_index,
2612 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002613 return false;
2614 }
2615 // Check that the static constructor (= static initializer) is named "<clinit>" and that the
2616 // instance constructor is called "<init>".
2617 if (is_constructor) {
2618 bool is_static = (method_access_flags & kAccStatic) != 0;
2619 if (is_static ^ is_clinit_by_name) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002620 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) is not flagged correctly wrt/ static.",
2621 method_index,
2622 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightf0ecae72016-05-06 10:39:06 -07002623 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2624 return false;
2625 } else {
2626 // Allow in older versions, but warn.
2627 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2628 << *error_msg;
2629 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002630 }
2631 }
2632 // Check that static and private methods, as well as constructors, are in the direct methods list,
2633 // and other methods in the virtual methods list.
2634 bool is_direct = (method_access_flags & (kAccStatic | kAccPrivate)) != 0 || is_constructor;
2635 if (is_direct != expect_direct) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002636 *error_msg = StringPrintf("Direct/virtual method %" PRIu32 "(%s) not in expected list %d",
Andreas Gampee6215c02015-08-31 18:54:38 -07002637 method_index,
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002638 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002639 expect_direct);
2640 return false;
2641 }
2642
2643
2644 // From here on out it is easier to mask out the bits we're supposed to ignore.
2645 method_access_flags &= kMethodAccessFlags;
2646
Alex Lightd7c10c22016-03-31 10:03:07 -07002647 // Interfaces are special.
2648 if ((class_access_flags & kAccInterface) != 0) {
Alex Lightb55f1ac2016-04-12 15:50:55 -07002649 // Non-static interface methods must be public or private.
2650 uint32_t desired_flags = (kAccPublic | kAccStatic);
2651 if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2652 desired_flags |= kAccPrivate;
2653 }
2654 if ((method_access_flags & desired_flags) == 0) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002655 *error_msg = StringPrintf("Interface virtual method %" PRIu32 "(%s) is not public",
2656 method_index,
2657 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002658 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002659 return false;
2660 } else {
2661 // Allow in older versions, but warn.
2662 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2663 << *error_msg;
2664 }
2665 }
2666 }
2667
Andreas Gampee6215c02015-08-31 18:54:38 -07002668 // If there aren't any instructions, make sure that's expected.
2669 if (!has_code) {
2670 // Only native or abstract methods may not have code.
2671 if ((method_access_flags & (kAccNative | kAccAbstract)) == 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002672 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has no code, but is not marked native or "
Andreas Gampee6215c02015-08-31 18:54:38 -07002673 "abstract",
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002674 method_index,
2675 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002676 return false;
2677 }
2678 // Constructors must always have code.
2679 if (is_constructor) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002680 *error_msg = StringPrintf("Constructor %u(%s) must not be abstract or native",
2681 method_index,
2682 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightf0ecae72016-05-06 10:39:06 -07002683 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
2684 return false;
2685 } else {
2686 // Allow in older versions, but warn.
2687 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2688 << *error_msg;
2689 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002690 }
2691 if ((method_access_flags & kAccAbstract) != 0) {
2692 // Abstract methods are not allowed to have the following flags.
2693 constexpr uint32_t kForbidden =
2694 kAccPrivate | kAccStatic | kAccFinal | kAccNative | kAccStrict | kAccSynchronized;
2695 if ((method_access_flags & kForbidden) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002696 *error_msg = StringPrintf("Abstract method %" PRIu32 "(%s) has disallowed access flags %x",
2697 method_index,
2698 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
2699 method_access_flags);
Andreas Gampee6215c02015-08-31 18:54:38 -07002700 return false;
2701 }
Andreas Gampe97b11352015-12-10 16:23:41 -08002702 // Abstract methods should be in an abstract class or interface.
Andreas Gampee6215c02015-08-31 18:54:38 -07002703 if ((class_access_flags & (kAccInterface | kAccAbstract)) == 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002704 LOG(WARNING) << "Method " << GetMethodDescriptionOrError(begin_, header_, method_index)
Andreas Gampe97b11352015-12-10 16:23:41 -08002705 << " is abstract, but the declaring class is neither abstract nor an "
2706 << "interface in dex file "
2707 << dex_file_->GetLocation();
Andreas Gampee6215c02015-08-31 18:54:38 -07002708 }
2709 }
2710 // Interfaces are special.
2711 if ((class_access_flags & kAccInterface) != 0) {
Alex Lightd7c10c22016-03-31 10:03:07 -07002712 // Interface methods without code must be abstract.
Andreas Gampee6215c02015-08-31 18:54:38 -07002713 if ((method_access_flags & (kAccPublic | kAccAbstract)) != (kAccPublic | kAccAbstract)) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002714 *error_msg = StringPrintf("Interface method %" PRIu32 "(%s) is not public and abstract",
2715 method_index,
2716 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Alex Lightb55f1ac2016-04-12 15:50:55 -07002717 if (header_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
Andreas Gampe76ed99d2016-03-28 18:31:29 -07002718 return false;
2719 } else {
2720 // Allow in older versions, but warn.
2721 LOG(WARNING) << "This dex file is invalid and will be rejected in the future. Error is: "
2722 << *error_msg;
2723 }
Andreas Gampee6215c02015-08-31 18:54:38 -07002724 }
2725 // At this point, we know the method is public and abstract. This means that all the checks
2726 // for invalid combinations above applies. In addition, interface methods must not be
2727 // protected. This is caught by the check for only-one-of-public-protected-private.
2728 }
2729 return true;
2730 }
2731
2732 // When there's code, the method must not be native or abstract.
2733 if ((method_access_flags & (kAccNative | kAccAbstract)) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002734 *error_msg = StringPrintf("Method %" PRIu32 "(%s) has code, but is marked native or abstract",
2735 method_index,
2736 GetMethodDescriptionOrError(begin_, header_, method_index).c_str());
Andreas Gampee6215c02015-08-31 18:54:38 -07002737 return false;
2738 }
2739
Andreas Gampee6215c02015-08-31 18:54:38 -07002740 // Instance constructors must not be synchronized and a few other flags.
2741 if (is_init_by_name) {
2742 static constexpr uint32_t kInitAllowed =
2743 kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic;
2744 if ((method_access_flags & ~kInitAllowed) != 0) {
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002745 *error_msg = StringPrintf("Constructor %" PRIu32 "(%s) flagged inappropriately %x",
Andreas Gampee6215c02015-08-31 18:54:38 -07002746 method_index,
Andreas Gampec9f0ba12016-02-09 09:21:04 -08002747 GetMethodDescriptionOrError(begin_, header_, method_index).c_str(),
Andreas Gampee6215c02015-08-31 18:54:38 -07002748 method_access_flags);
2749 return false;
2750 }
2751 }
2752
2753 return true;
2754}
2755
jeffhao10037c82012-01-23 15:06:23 -08002756} // namespace art