blob: f14b1d56cbc573d4c019a1562fe64bc1c65a7ffd [file] [log] [blame]
Andreas Gampedf10b322014-06-11 21:46:05 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "dex_file_verifier.h"
18
Ian Rogerse63db272014-07-15 15:36:11 -070019#include "sys/mman.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070020#include "zlib.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070021#include <functional>
Ian Rogerse63db272014-07-15 15:36:11 -070022#include <memory>
Andreas Gampedf10b322014-06-11 21:46:05 -070023
Ian Rogerse63db272014-07-15 15:36:11 -070024#include "base/unix_file/fd_file.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070025#include "base/bit_utils.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070026#include "base/macros.h"
Ian Rogerse63db272014-07-15 15:36:11 -070027#include "common_runtime_test.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070028#include "dex_file-inl.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080029#include "dex_file_types.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070030#include "leb128.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070032#include "thread-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070033#include "utils.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070034
35namespace art {
36
Alex Light0ed05212016-05-06 17:36:36 -070037// Make the Dex file version 37.
38static void MakeDexVersion37(DexFile* dex_file) {
39 size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
40 CHECK_EQ(*(dex_file->Begin() + offset), '5');
41 *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
42}
43
Andreas Gampee6215c02015-08-31 18:54:38 -070044static void FixUpChecksum(uint8_t* dex_file) {
45 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
46 uint32_t expected_size = header->file_size_;
47 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
48 const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
49 const uint8_t* non_sum_ptr = dex_file + non_sum;
50 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
51 header->checksum_ = adler_checksum;
52}
53
Andreas Gampee6215c02015-08-31 18:54:38 -070054class DexFileVerifierTest : public CommonRuntimeTest {
55 protected:
Aart Bik37d6a3b2016-06-21 18:30:10 -070056 DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
David Sehr733ddb22016-09-19 15:02:18 -070057 return new DexFile(dex_bytes, length, "tmp", 0, nullptr);
Aart Bik37d6a3b2016-06-21 18:30:10 -070058 }
59
Andreas Gampee6215c02015-08-31 18:54:38 -070060 void VerifyModification(const char* dex_file_base64_content,
61 const char* location,
Andreas Gampeca620d72016-11-08 08:09:33 -080062 const std::function<void(DexFile*)>& f,
Andreas Gampee6215c02015-08-31 18:54:38 -070063 const char* expected_error) {
Vladimir Marko59399ab2016-05-03 16:31:52 +010064 size_t length;
Alex Light9c20a142016-08-23 15:05:12 -070065 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(dex_file_base64_content, &length));
Vladimir Marko59399ab2016-05-03 16:31:52 +010066 CHECK(dex_bytes != nullptr);
67 // Note: `dex_file` will be destroyed before `dex_bytes`.
Aart Bik37d6a3b2016-06-21 18:30:10 -070068 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
Andreas Gampee6215c02015-08-31 18:54:38 -070069 f(dex_file.get());
70 FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));
71
Aart Bik37d6a3b2016-06-21 18:30:10 -070072 static constexpr bool kVerifyChecksum = true;
Andreas Gampee6215c02015-08-31 18:54:38 -070073 std::string error_msg;
74 bool success = DexFileVerifier::Verify(dex_file.get(),
75 dex_file->Begin(),
76 dex_file->Size(),
77 location,
Aart Bik37d6a3b2016-06-21 18:30:10 -070078 kVerifyChecksum,
Andreas Gampee6215c02015-08-31 18:54:38 -070079 &error_msg);
80 if (expected_error == nullptr) {
81 EXPECT_TRUE(success) << error_msg;
82 } else {
83 EXPECT_FALSE(success) << "Expected " << expected_error;
84 if (!success) {
85 EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
86 }
87 }
88 }
Andreas Gampee6215c02015-08-31 18:54:38 -070089};
90
Richard Uhlerfbef44d2014-12-23 09:48:51 -080091static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
92 const char* location,
93 std::string* error_msg) {
Andreas Gampedf10b322014-06-11 21:46:05 -070094 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -070095 CHECK(base64 != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -070096 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -070097 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070098 CHECK(dex_bytes.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -070099
100 // write to provided file
101 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700102 CHECK(file.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700103 if (!file->WriteFully(dex_bytes.get(), length)) {
104 PLOG(FATAL) << "Failed to write base64 as dex file";
105 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800106 if (file->FlushCloseOrErase() != 0) {
107 PLOG(FATAL) << "Could not flush and close test file.";
108 }
Andreas Gampedf10b322014-06-11 21:46:05 -0700109 file.reset();
110
111 // read dex file
112 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800113 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700114 bool success = DexFile::Open(location, location, true, error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700115 CHECK(success) << error_msg;
116 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800117 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Andreas Gampe833a4852014-05-21 18:46:59 -0700118 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
119 EXPECT_TRUE(dex_file->IsReadOnly());
120 return dex_file;
Andreas Gampedf10b322014-06-11 21:46:05 -0700121}
122
Roland Levillain621b5ea2016-05-18 11:41:33 +0100123// To generate a base64 encoded Dex file (such as kGoodTestDex, below)
124// from Smali files, use:
125//
126// smali -o classes.dex class1.smali [class2.smali ...]
127// base64 classes.dex >classes.dex.base64
128
Andreas Gampedf10b322014-06-11 21:46:05 -0700129// For reference.
130static const char kGoodTestDex[] =
131 "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
132 "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
133 "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
134 "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
135 "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
136 "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
137 "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
138 "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
139 "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
140 "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
141 "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
142 "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";
143
144TEST_F(DexFileVerifierTest, GoodDex) {
145 ScratchFile tmp;
146 std::string error_msg;
147 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
148 &error_msg));
149 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
150}
151
Andreas Gampedf10b322014-06-11 21:46:05 -0700152TEST_F(DexFileVerifierTest, MethodId) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700153 // Class idx error.
154 VerifyModification(
155 kGoodTestDex,
156 "method_id_class_idx",
157 [](DexFile* dex_file) {
158 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
Andreas Gampea5b09a62016-11-17 15:21:22 -0800159 method_id->class_idx_ = dex::TypeIndex(0xFF);
Andreas Gampee6215c02015-08-31 18:54:38 -0700160 },
161 "could not find declaring class for direct method index 0");
162
163 // Proto idx error.
164 VerifyModification(
165 kGoodTestDex,
166 "method_id_proto_idx",
167 [](DexFile* dex_file) {
168 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
169 method_id->proto_idx_ = 0xFF;
170 },
171 "inter_method_id_item proto_idx");
172
173 // Name idx error.
174 VerifyModification(
175 kGoodTestDex,
176 "method_id_name_idx",
177 [](DexFile* dex_file) {
178 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800179 method_id->name_idx_ = dex::StringIndex(0xFF);
Andreas Gampee6215c02015-08-31 18:54:38 -0700180 },
181 "String index not available for method flags verification");
182}
183
184// Method flags test class generated from the following smali code. The declared-synchronized
185// flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
186// the code, but we need to remove them before doing tests.
187//
188// .class public LMethodFlags;
189// .super Ljava/lang/Object;
190//
191// .method public static constructor <clinit>()V
192// .registers 1
193// return-void
194// .end method
195//
196// .method public constructor <init>()V
197// .registers 1
198// return-void
199// .end method
200//
201// .method private declared-synchronized foo()V
202// .registers 1
203// return-void
204// .end method
205//
206// .method public declared-synchronized bar()V
207// .registers 1
208// return-void
209// .end method
210
211static const char kMethodFlagsTestDex[] =
212 "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
213 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
214 "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
215 "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
216 "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
217 "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
218 "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
219 "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
220 "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
221 "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";
222
223// Find the method data for the first method with the given name (from class 0). Note: the pointer
224// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
225// delta.
Vladimir Marko59399ab2016-05-03 16:31:52 +0100226static const uint8_t* FindMethodData(const DexFile* dex_file,
227 const char* name,
228 /*out*/ uint32_t* method_idx = nullptr) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700229 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
230 const uint8_t* class_data = dex_file->GetClassData(class_def);
231
232 ClassDataItemIterator it(*dex_file, class_data);
233
234 const uint8_t* trailing = class_data;
235 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
236 // element has already been loaded into the iterator.
237 DecodeUnsignedLeb128(&trailing);
238 DecodeUnsignedLeb128(&trailing);
239 DecodeUnsignedLeb128(&trailing);
240 DecodeUnsignedLeb128(&trailing);
241
242 // Skip all fields.
243 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
244 trailing = it.DataPointer();
245 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700246 }
247
Andreas Gampee6215c02015-08-31 18:54:38 -0700248 while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
249 uint32_t method_index = it.GetMemberIndex();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800250 dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
Andreas Gampee6215c02015-08-31 18:54:38 -0700251 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
252 const char* str = dex_file->GetStringData(string_id);
253 if (strcmp(name, str) == 0) {
Vladimir Marko59399ab2016-05-03 16:31:52 +0100254 if (method_idx != nullptr) {
255 *method_idx = method_index;
256 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700257 DecodeUnsignedLeb128(&trailing);
258 return trailing;
259 }
260
261 trailing = it.DataPointer();
262 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700263 }
264
Andreas Gampee6215c02015-08-31 18:54:38 -0700265 return nullptr;
266}
267
268// Set the method flags to the given value.
269static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
270 uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
271 CHECK(method_flags_ptr != nullptr) << method;
272
273 // Unroll this, as we only have three bytes, anyways.
274 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
275 *(method_flags_ptr++) = (base1 | 0x80);
276 mask >>= 7;
277
278 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
279 *(method_flags_ptr++) = (base2 | 0x80);
280 mask >>= 7;
281
282 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
283 *method_flags_ptr = base3;
284}
285
286static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
287 const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
288 CHECK(method_flags_ptr != nullptr) << method;
289 return DecodeUnsignedLeb128(&method_flags_ptr);
290}
291
292// Apply the given mask to method flags.
293static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
294 uint32_t value = GetMethodFlags(dex_file, method);
295 value &= mask;
296 SetMethodFlags(dex_file, method, value);
297}
298
299// Apply the given mask to method flags.
300static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
301 uint32_t value = GetMethodFlags(dex_file, method);
302 value |= mask;
303 SetMethodFlags(dex_file, method, value);
304}
305
306// Set code_off to 0 for the method.
307static void RemoveCode(DexFile* dex_file, const char* method) {
308 const uint8_t* ptr = FindMethodData(dex_file, method);
309 // Next is flags, pass.
310 DecodeUnsignedLeb128(&ptr);
311
312 // Figure out how many bytes the code_off is.
313 const uint8_t* tmp = ptr;
314 DecodeUnsignedLeb128(&tmp);
315 size_t bytes = tmp - ptr;
316
317 uint8_t* mod = const_cast<uint8_t*>(ptr);
318 for (size_t i = 1; i < bytes; ++i) {
319 *(mod++) = 0x80;
Andreas Gampedf10b322014-06-11 21:46:05 -0700320 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700321 *mod = 0x00;
322}
323
324TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
325 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
326 VerifyModification(
327 kMethodFlagsTestDex,
328 "method_flags_ok",
329 [](DexFile* dex_file) {
330 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
331 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
332 },
333 nullptr);
334}
335
336TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
337 // Make sure we still accept constructors without their flags.
338 VerifyModification(
339 kMethodFlagsTestDex,
340 "method_flags_missing_constructor_tag_ok",
341 [](DexFile* dex_file) {
342 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
343 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
344
345 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
346 ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
347 },
348 nullptr);
349
350 constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
351 for (size_t i = 0; i < 2; ++i) {
352 // Constructor with code marked native.
353 VerifyModification(
354 kMethodFlagsTestDex,
355 "method_flags_constructor_native",
356 [&](DexFile* dex_file) {
357 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
358 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
359
360 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
361 },
362 "has code, but is marked native or abstract");
363 // Constructor with code marked abstract.
364 VerifyModification(
365 kMethodFlagsTestDex,
366 "method_flags_constructor_abstract",
367 [&](DexFile* dex_file) {
368 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
369 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
370
371 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
372 },
373 "has code, but is marked native or abstract");
374 // Constructor as-is without code.
375 VerifyModification(
376 kMethodFlagsTestDex,
377 "method_flags_constructor_nocode",
378 [&](DexFile* dex_file) {
379 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
380 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
381
382 RemoveCode(dex_file, kConstructors[i]);
383 },
384 "has no code, but is not marked native or abstract");
385 // Constructor without code marked native.
386 VerifyModification(
387 kMethodFlagsTestDex,
388 "method_flags_constructor_native_nocode",
389 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700390 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700391 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
392 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
393
394 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
395 RemoveCode(dex_file, kConstructors[i]);
396 },
397 "must not be abstract or native");
398 // Constructor without code marked abstract.
399 VerifyModification(
400 kMethodFlagsTestDex,
401 "method_flags_constructor_abstract_nocode",
402 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700403 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700404 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
405 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
406
407 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
408 RemoveCode(dex_file, kConstructors[i]);
409 },
410 "must not be abstract or native");
411 }
412 // <init> may only have (modulo ignored):
413 // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
414 static constexpr uint32_t kInitAllowed[] = {
415 0,
416 kAccPrivate,
417 kAccProtected,
418 kAccPublic,
419 kAccStrict,
420 kAccVarargs,
421 kAccSynthetic
422 };
423 for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
424 VerifyModification(
425 kMethodFlagsTestDex,
426 "init_allowed_flags",
427 [&](DexFile* dex_file) {
428 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
429 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
430
431 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
432 OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
433 },
434 nullptr);
435 }
436 // Only one of public-private-protected.
437 for (size_t i = 1; i < 8; ++i) {
438 if (POPCOUNT(i) < 2) {
439 continue;
440 }
441 // Technically the flags match, but just be defensive here.
442 uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
443 ((i & 2) != 0 ? kAccProtected : 0) |
444 ((i & 4) != 0 ? kAccPublic : 0);
445 VerifyModification(
446 kMethodFlagsTestDex,
447 "init_one_of_ppp",
448 [&](DexFile* dex_file) {
449 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
450 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
451
452 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
453 OrMaskToMethodFlags(dex_file, "<init>", mask);
454 },
455 "Method may have only one of public/protected/private");
456 }
457 // <init> doesn't allow
458 // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
459 // Need to handle static separately as it has its own error message.
460 VerifyModification(
461 kMethodFlagsTestDex,
462 "init_not_allowed_flags",
463 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700464 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700465 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
466 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
467
468 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
469 OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
470 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800471 "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
Andreas Gampee6215c02015-08-31 18:54:38 -0700472 static constexpr uint32_t kInitNotAllowed[] = {
473 kAccFinal,
474 kAccSynchronized,
475 kAccBridge
476 };
477 for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
478 VerifyModification(
479 kMethodFlagsTestDex,
480 "init_not_allowed_flags",
481 [&](DexFile* dex_file) {
482 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
483 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
484
485 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
486 OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
487 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800488 "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
Andreas Gampee6215c02015-08-31 18:54:38 -0700489 }
490}
491
492TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
493 constexpr const char* kMethods[] = { "foo", "bar"};
494 for (size_t i = 0; i < arraysize(kMethods); ++i) {
495 // Make sure we reject non-constructors marked as constructors.
496 VerifyModification(
497 kMethodFlagsTestDex,
498 "method_flags_non_constructor",
499 [&](DexFile* dex_file) {
500 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
501 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
502
503 OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
504 },
505 "is marked constructor, but doesn't match name");
506
507 VerifyModification(
508 kMethodFlagsTestDex,
509 "method_flags_native_with_code",
510 [&](DexFile* dex_file) {
511 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
512 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
513
514 OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
515 },
516 "has code, but is marked native or abstract");
517
518 VerifyModification(
519 kMethodFlagsTestDex,
520 "method_flags_abstract_with_code",
521 [&](DexFile* dex_file) {
522 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
523 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
524
525 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
526 },
527 "has code, but is marked native or abstract");
528
529 VerifyModification(
530 kMethodFlagsTestDex,
531 "method_flags_non_abstract_native_no_code",
532 [&](DexFile* dex_file) {
533 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
534 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
535
536 RemoveCode(dex_file, kMethods[i]);
537 },
538 "has no code, but is not marked native or abstract");
539
540 // Abstract methods may not have the following flags.
541 constexpr uint32_t kAbstractDisallowed[] = {
542 kAccPrivate,
543 kAccStatic,
544 kAccFinal,
545 kAccNative,
546 kAccStrict,
547 kAccSynchronized,
548 };
549 for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
550 VerifyModification(
551 kMethodFlagsTestDex,
552 "method_flags_abstract_and_disallowed_no_code",
553 [&](DexFile* dex_file) {
554 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
555 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
556
557 RemoveCode(dex_file, kMethods[i]);
558
559 // Can't check private and static with foo, as it's in the virtual list and gives a
560 // different error.
561 if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
562 ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
563 // Use another breaking flag.
564 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
565 } else {
566 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
567 }
568 },
569 "has disallowed access flags");
570 }
571
572 // Only one of public-private-protected.
573 for (size_t j = 1; j < 8; ++j) {
574 if (POPCOUNT(j) < 2) {
575 continue;
576 }
577 // Technically the flags match, but just be defensive here.
578 uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
579 ((j & 2) != 0 ? kAccProtected : 0) |
580 ((j & 4) != 0 ? kAccPublic : 0);
581 VerifyModification(
582 kMethodFlagsTestDex,
583 "method_flags_one_of_ppp",
584 [&](DexFile* dex_file) {
585 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
586 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
587
588 ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
589 OrMaskToMethodFlags(dex_file, kMethods[i], mask);
590 },
591 "Method may have only one of public/protected/private");
592 }
593 }
594}
595
596TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
597 constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
598 for (size_t i = 0; i < arraysize(kMethods); ++i) {
599 // All interesting method flags, other flags are to be ignored.
600 constexpr uint32_t kAllMethodFlags =
601 kAccPublic |
602 kAccPrivate |
603 kAccProtected |
604 kAccStatic |
605 kAccFinal |
606 kAccSynchronized |
607 kAccBridge |
608 kAccVarargs |
609 kAccNative |
610 kAccAbstract |
611 kAccStrict |
612 kAccSynthetic;
613 constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
614 VerifyModification(
615 kMethodFlagsTestDex,
616 "method_flags_ignored",
617 [&](DexFile* dex_file) {
618 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
619 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
620
621 OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
622 },
623 nullptr);
624 }
625}
626
Vladimir Marko59399ab2016-05-03 16:31:52 +0100627TEST_F(DexFileVerifierTest, B28552165) {
628 // Regression test for bad error string retrieval in different situations.
629 // Using invalid access flags to trigger the error.
630 VerifyModification(
631 kMethodFlagsTestDex,
632 "b28552165",
633 [](DexFile* dex_file) {
634 OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
635 uint32_t method_idx;
636 FindMethodData(dex_file, "foo", &method_idx);
637 auto* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(method_idx));
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800638 method_id->name_idx_ = dex::StringIndex(dex_file->NumStringIds());
Vladimir Marko59399ab2016-05-03 16:31:52 +0100639 },
640 "Method may have only one of public/protected/private, LMethodFlags;.(error)");
641}
642
Andreas Gampee6215c02015-08-31 18:54:38 -0700643// Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
644// just easier to break up bad cases.
645
Andreas Gampee6215c02015-08-31 18:54:38 -0700646// Standard interface. Use declared-synchronized again for 3B encoding.
647//
648// .class public interface LInterfaceMethodFlags;
649// .super Ljava/lang/Object;
650//
651// .method public static constructor <clinit>()V
652// .registers 1
653// return-void
654// .end method
655//
656// .method public abstract declared-synchronized foo()V
657// .end method
658static const char kMethodFlagsInterface[] =
659 "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
660 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
661 "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
662 "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
663 "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
664 "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
665 "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
666 "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";
667
668// To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
669// to a src_value, such that mask bit 0 applies to the lowest set bit in src_value, and so on.
670static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
671 uint32_t result = 0;
672 uint32_t mask_index = 0;
673 while (src_value != 0) {
674 uint32_t index = CTZ(src_value);
675 if (((src_value & (1 << index)) != 0) &&
676 ((mask & (1 << mask_index)) != 0)) {
677 result |= (1 << index);
678 }
679 src_value &= ~(1 << index);
680 mask_index++;
681 }
682 return result;
683}
684
685TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700686 VerifyModification(
687 kMethodFlagsInterface,
688 "method_flags_interface_ok",
689 [](DexFile* dex_file) {
690 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
691 },
692 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700693 VerifyModification(
694 kMethodFlagsInterface,
695 "method_flags_interface_ok37",
696 [](DexFile* dex_file) {
697 MakeDexVersion37(dex_file);
698 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
699 },
700 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -0700701
702 VerifyModification(
703 kMethodFlagsInterface,
704 "method_flags_interface_non_public",
705 [](DexFile* dex_file) {
706 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
707
708 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
709 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700710 nullptr); // Should be allowed in older dex versions for backwards compatibility.
711 VerifyModification(
712 kMethodFlagsInterface,
713 "method_flags_interface_non_public",
714 [](DexFile* dex_file) {
715 MakeDexVersion37(dex_file);
716 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
717
718 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
719 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700720 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700721
Andreas Gampee6215c02015-08-31 18:54:38 -0700722 VerifyModification(
723 kMethodFlagsInterface,
724 "method_flags_interface_non_abstract",
725 [](DexFile* dex_file) {
726 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
727
728 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
729 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800730 "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");
Andreas Gampee6215c02015-08-31 18:54:38 -0700731
732 VerifyModification(
733 kMethodFlagsInterface,
734 "method_flags_interface_static",
735 [](DexFile* dex_file) {
736 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
737
738 OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
739 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800740 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700741 VerifyModification(
742 kMethodFlagsInterface,
743 "method_flags_interface_private",
744 [](DexFile* dex_file) {
745 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
746
747 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
748 OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
749 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800750 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700751
752 VerifyModification(
753 kMethodFlagsInterface,
754 "method_flags_interface_non_public",
755 [](DexFile* dex_file) {
756 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
757
758 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
759 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700760 nullptr); // Should be allowed in older dex versions for backwards compatibility.
761 VerifyModification(
762 kMethodFlagsInterface,
763 "method_flags_interface_non_public",
764 [](DexFile* dex_file) {
765 MakeDexVersion37(dex_file);
766 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
767
768 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
769 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700770 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700771
Andreas Gampee6215c02015-08-31 18:54:38 -0700772 VerifyModification(
773 kMethodFlagsInterface,
774 "method_flags_interface_protected",
775 [](DexFile* dex_file) {
776 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
777
778 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
779 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
780 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700781 nullptr); // Should be allowed in older dex versions for backwards compatibility.
782 VerifyModification(
783 kMethodFlagsInterface,
784 "method_flags_interface_protected",
785 [](DexFile* dex_file) {
786 MakeDexVersion37(dex_file);
787 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
788
789 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
790 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
791 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700792 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampee6215c02015-08-31 18:54:38 -0700793
794 constexpr uint32_t kAllMethodFlags =
795 kAccPublic |
796 kAccPrivate |
797 kAccProtected |
798 kAccStatic |
799 kAccFinal |
800 kAccSynchronized |
801 kAccBridge |
802 kAccVarargs |
803 kAccNative |
804 kAccAbstract |
805 kAccStrict |
806 kAccSynthetic;
807 constexpr uint32_t kInterfaceMethodFlags =
808 kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
809 constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
810 ~kInterfaceMethodFlags &
811 // Already tested, needed to be separate.
812 ~kAccStatic &
813 ~kAccPrivate &
814 ~kAccProtected;
815 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
816
817 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
818 for (uint32_t i = 1; i < (1u << bits); ++i) {
819 VerifyModification(
820 kMethodFlagsInterface,
821 "method_flags_interface_non_abstract",
822 [&](DexFile* dex_file) {
823 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
824
825 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
826 if ((mask & kAccProtected) != 0) {
827 mask &= ~kAccProtected;
828 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
829 }
830 OrMaskToMethodFlags(dex_file, "foo", mask);
831 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800832 "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
Andreas Gampee6215c02015-08-31 18:54:38 -0700833 }
834}
835
836///////////////////////////////////////////////////////////////////
837
838// Field flags.
839
840// Find the method data for the first method with the given name (from class 0). Note: the pointer
841// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
842// delta.
843static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
844 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
845 const uint8_t* class_data = dex_file->GetClassData(class_def);
846
847 ClassDataItemIterator it(*dex_file, class_data);
848
849 const uint8_t* trailing = class_data;
850 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
851 // element has already been loaded into the iterator.
852 DecodeUnsignedLeb128(&trailing);
853 DecodeUnsignedLeb128(&trailing);
854 DecodeUnsignedLeb128(&trailing);
855 DecodeUnsignedLeb128(&trailing);
856
857 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
858 uint32_t field_index = it.GetMemberIndex();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800859 dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
Andreas Gampee6215c02015-08-31 18:54:38 -0700860 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
861 const char* str = dex_file->GetStringData(string_id);
862 if (strcmp(name, str) == 0) {
863 DecodeUnsignedLeb128(&trailing);
864 return trailing;
865 }
866
867 trailing = it.DataPointer();
868 it.Next();
869 }
870
871 return nullptr;
872}
873
874// Set the method flags to the given value.
875static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
876 uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
877 CHECK(field_flags_ptr != nullptr) << field;
878
879 // Unroll this, as we only have three bytes, anyways.
880 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
881 *(field_flags_ptr++) = (base1 | 0x80);
882 mask >>= 7;
883
884 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
885 *(field_flags_ptr++) = (base2 | 0x80);
886 mask >>= 7;
887
888 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
889 *field_flags_ptr = base3;
890}
891
892static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
893 const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
894 CHECK(field_flags_ptr != nullptr) << field;
895 return DecodeUnsignedLeb128(&field_flags_ptr);
896}
897
898// Apply the given mask to method flags.
899static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
900 uint32_t value = GetFieldFlags(dex_file, field);
901 value &= mask;
902 SetFieldFlags(dex_file, field, value);
903}
904
905// Apply the given mask to method flags.
906static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
907 uint32_t value = GetFieldFlags(dex_file, field);
908 value |= mask;
909 SetFieldFlags(dex_file, field, value);
910}
911
912// Standard class. Use declared-synchronized again for 3B encoding.
913//
914// .class public LFieldFlags;
915// .super Ljava/lang/Object;
916//
917// .field declared-synchronized public foo:I
918//
919// .field declared-synchronized public static bar:I
920
921static const char kFieldFlagsTestDex[] =
922 "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
923 "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
924 "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
925 "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
926 "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
927 "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
928 "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";
929
930TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
931 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
932 VerifyModification(
933 kFieldFlagsTestDex,
934 "field_flags_ok",
935 [](DexFile* dex_file) {
936 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
937 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
938 },
939 nullptr);
940}
941
942TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
943 // Mark the field so that it should appear in the opposite list (instance vs static).
944 VerifyModification(
945 kFieldFlagsTestDex,
946 "field_flags_wrong_list",
947 [](DexFile* dex_file) {
948 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
949 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
950
951 OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
952 },
953 "Static/instance field not in expected list");
954 VerifyModification(
955 kFieldFlagsTestDex,
956 "field_flags_wrong_list",
957 [](DexFile* dex_file) {
958 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
959 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
960
961 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
962 },
963 "Static/instance field not in expected list");
964}
965
966TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
967 static const char* kFields[] = { "foo", "bar" };
968 for (size_t i = 0; i < arraysize(kFields); ++i) {
969 // Should be OK to remove public.
970 VerifyModification(
971 kFieldFlagsTestDex,
972 "field_flags_non_public",
973 [&](DexFile* dex_file) {
974 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
975 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
976
977 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
978 },
979 nullptr);
980 constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
981 uint32_t bits = POPCOUNT(kAccFlags);
982 for (uint32_t j = 1; j < (1u << bits); ++j) {
983 if (POPCOUNT(j) < 2) {
984 continue;
985 }
986 VerifyModification(
987 kFieldFlagsTestDex,
988 "field_flags_ppp",
989 [&](DexFile* dex_file) {
990 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
991 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
992
993 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
994 uint32_t mask = ApplyMaskShifted(kAccFlags, j);
995 OrMaskToFieldFlags(dex_file, kFields[i], mask);
996 },
997 "Field may have only one of public/protected/private");
998 }
999 }
1000}
1001
1002TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
1003 constexpr const char* kFields[] = { "foo", "bar"};
1004 for (size_t i = 0; i < arraysize(kFields); ++i) {
1005 // All interesting method flags, other flags are to be ignored.
1006 constexpr uint32_t kAllFieldFlags =
1007 kAccPublic |
1008 kAccPrivate |
1009 kAccProtected |
1010 kAccStatic |
1011 kAccFinal |
1012 kAccVolatile |
1013 kAccTransient |
1014 kAccSynthetic |
1015 kAccEnum;
1016 constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
1017 VerifyModification(
1018 kFieldFlagsTestDex,
1019 "field_flags_ignored",
1020 [&](DexFile* dex_file) {
1021 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1022 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1023
1024 OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
1025 },
1026 nullptr);
1027 }
1028}
1029
1030TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
1031 constexpr const char* kFields[] = { "foo", "bar"};
1032 for (size_t i = 0; i < arraysize(kFields); ++i) {
1033 VerifyModification(
1034 kFieldFlagsTestDex,
1035 "field_flags_final_and_volatile",
1036 [&](DexFile* dex_file) {
1037 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1038 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1039
1040 OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
1041 },
1042 "Fields may not be volatile and final");
1043 }
1044}
1045
1046// Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
1047// Use declared-synchronized again for 3B encoding.
1048//
1049// .class public interface LInterfaceFieldFlags;
1050// .super Ljava/lang/Object;
1051//
1052// .field declared-synchronized public static final foo:I
1053
1054static const char kFieldFlagsInterfaceTestDex[] =
1055 "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1056 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1057 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1058 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1059 "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1060 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1061 "AAAAEAAAAQAAAPQAAAA=";
1062
1063TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
1064 VerifyModification(
1065 kFieldFlagsInterfaceTestDex,
1066 "field_flags_interface",
1067 [](DexFile* dex_file) {
1068 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1069 },
1070 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001071 VerifyModification(
1072 kFieldFlagsInterfaceTestDex,
1073 "field_flags_interface",
1074 [](DexFile* dex_file) {
1075 MakeDexVersion37(dex_file);
1076 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1077 },
1078 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -07001079
1080 VerifyModification(
1081 kFieldFlagsInterfaceTestDex,
1082 "field_flags_interface_non_public",
1083 [](DexFile* dex_file) {
1084 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1085
1086 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1087 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001088 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1089 VerifyModification(
1090 kFieldFlagsInterfaceTestDex,
1091 "field_flags_interface_non_public",
1092 [](DexFile* dex_file) {
1093 MakeDexVersion37(dex_file);
1094 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1095
1096 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1097 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001098 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001099
Andreas Gampee6215c02015-08-31 18:54:38 -07001100 VerifyModification(
1101 kFieldFlagsInterfaceTestDex,
1102 "field_flags_interface_non_final",
1103 [](DexFile* dex_file) {
1104 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1105
1106 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1107 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001108 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1109 VerifyModification(
1110 kFieldFlagsInterfaceTestDex,
1111 "field_flags_interface_non_final",
1112 [](DexFile* dex_file) {
1113 MakeDexVersion37(dex_file);
1114 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1115
1116 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1117 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001118 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001119
Andreas Gampee6215c02015-08-31 18:54:38 -07001120 VerifyModification(
1121 kFieldFlagsInterfaceTestDex,
1122 "field_flags_interface_protected",
1123 [](DexFile* dex_file) {
1124 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1125
1126 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1127 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1128 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001129 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1130 VerifyModification(
1131 kFieldFlagsInterfaceTestDex,
1132 "field_flags_interface_protected",
1133 [](DexFile* dex_file) {
1134 MakeDexVersion37(dex_file);
1135 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1136
1137 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1138 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1139 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001140 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001141
Andreas Gampee6215c02015-08-31 18:54:38 -07001142 VerifyModification(
1143 kFieldFlagsInterfaceTestDex,
1144 "field_flags_interface_private",
1145 [](DexFile* dex_file) {
1146 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1147
1148 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1149 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1150 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001151 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1152 VerifyModification(
1153 kFieldFlagsInterfaceTestDex,
1154 "field_flags_interface_private",
1155 [](DexFile* dex_file) {
1156 MakeDexVersion37(dex_file);
1157 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1158
1159 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1160 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1161 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001162 "Interface field is not public final static");
1163
1164 VerifyModification(
1165 kFieldFlagsInterfaceTestDex,
1166 "field_flags_interface_synthetic",
1167 [](DexFile* dex_file) {
1168 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1169
1170 OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
1171 },
1172 nullptr);
1173
1174 constexpr uint32_t kAllFieldFlags =
1175 kAccPublic |
1176 kAccPrivate |
1177 kAccProtected |
1178 kAccStatic |
1179 kAccFinal |
1180 kAccVolatile |
1181 kAccTransient |
1182 kAccSynthetic |
1183 kAccEnum;
1184 constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
1185 constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
1186 ~kInterfaceFieldFlags &
1187 ~kAccProtected &
1188 ~kAccPrivate;
1189 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
1190
1191 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
1192 for (uint32_t i = 1; i < (1u << bits); ++i) {
1193 VerifyModification(
1194 kFieldFlagsInterfaceTestDex,
1195 "field_flags_interface_disallowed",
1196 [&](DexFile* dex_file) {
1197 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1198
1199 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1200 if ((mask & kAccProtected) != 0) {
1201 mask &= ~kAccProtected;
1202 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1203 }
1204 OrMaskToFieldFlags(dex_file, "foo", mask);
1205 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001206 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1207 VerifyModification(
1208 kFieldFlagsInterfaceTestDex,
1209 "field_flags_interface_disallowed",
1210 [&](DexFile* dex_file) {
1211 MakeDexVersion37(dex_file);
1212 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1213
1214 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1215 if ((mask & kAccProtected) != 0) {
1216 mask &= ~kAccProtected;
1217 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1218 }
1219 OrMaskToFieldFlags(dex_file, "foo", mask);
1220 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001221 "Interface field has disallowed flag");
1222 }
1223}
1224
1225// Standard bad interface. Needs to be separate from class as interfaces do not allow instance
1226// fields. Use declared-synchronized again for 3B encoding.
1227//
1228// .class public interface LInterfaceFieldFlags;
1229// .super Ljava/lang/Object;
1230//
1231// .field declared-synchronized public final foo:I
1232
1233static const char kFieldFlagsInterfaceBadTestDex[] =
1234 "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1235 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1236 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1237 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1238 "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1239 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1240 "AAAAEAAAAQAAAPQAAAA=";
1241
1242TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
1243 VerifyModification(
1244 kFieldFlagsInterfaceBadTestDex,
1245 "field_flags_interface_non_static",
1246 [](DexFile* dex_file) {
1247 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1248 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001249 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1250 VerifyModification(
1251 kFieldFlagsInterfaceBadTestDex,
1252 "field_flags_interface_non_static",
1253 [](DexFile* dex_file) {
1254 MakeDexVersion37(dex_file);
1255 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1256 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001257 "Interface field is not public final static");
Andreas Gampedf10b322014-06-11 21:46:05 -07001258}
1259
Logan Chiendd3208d2015-04-19 23:27:52 +08001260// Generated from:
1261//
1262// .class public LTest;
1263// .super Ljava/lang/Object;
1264// .source "Test.java"
1265//
1266// .method public constructor <init>()V
1267// .registers 1
1268//
1269// .prologue
1270// .line 1
1271// invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1272//
1273// return-void
1274// .end method
1275//
1276// .method public static main()V
1277// .registers 2
1278//
1279// const-string v0, "a"
1280// const-string v0, "b"
1281// const-string v0, "c"
1282// const-string v0, "d"
1283// const-string v0, "e"
1284// const-string v0, "f"
1285// const-string v0, "g"
1286// const-string v0, "h"
1287// const-string v0, "i"
1288// const-string v0, "j"
1289// const-string v0, "k"
1290//
1291// .local v1, "local_var":Ljava/lang/String;
1292// const-string v1, "test"
1293// .end method
1294
1295static const char kDebugInfoTestDex[] =
1296 "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
1297 "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
1298 "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
1299 "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
1300 "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
1301 "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
1302 "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
1303 "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
1304 "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
1305 "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
1306 "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
1307 "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";
1308
1309TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
1310 {
1311 // The input dex file should be good before modification.
1312 ScratchFile tmp;
1313 std::string error_msg;
1314 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
1315 tmp.GetFilename().c_str(),
1316 &error_msg));
1317 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1318 }
1319
Andreas Gampee6215c02015-08-31 18:54:38 -07001320 // Modify the debug information entry.
1321 VerifyModification(
1322 kDebugInfoTestDex,
1323 "debug_start_type_idx",
1324 [](DexFile* dex_file) {
1325 *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
1326 },
1327 "DBG_START_LOCAL type_idx");
Logan Chiendd3208d2015-04-19 23:27:52 +08001328}
1329
Andreas Gampeb512c0e2016-02-19 19:45:34 -08001330TEST_F(DexFileVerifierTest, SectionAlignment) {
1331 {
1332 // The input dex file should be good before modification. Any file is fine, as long as it
1333 // uses all sections.
1334 ScratchFile tmp;
1335 std::string error_msg;
1336 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
1337 tmp.GetFilename().c_str(),
1338 &error_msg));
1339 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1340 }
1341
1342 // Modify all section offsets to be unaligned.
1343 constexpr size_t kSections = 7;
1344 for (size_t i = 0; i < kSections; ++i) {
1345 VerifyModification(
1346 kGoodTestDex,
1347 "section_align",
1348 [&](DexFile* dex_file) {
1349 DexFile::Header* header = const_cast<DexFile::Header*>(
1350 reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
1351 uint32_t* off_ptr;
1352 switch (i) {
1353 case 0:
1354 off_ptr = &header->map_off_;
1355 break;
1356 case 1:
1357 off_ptr = &header->string_ids_off_;
1358 break;
1359 case 2:
1360 off_ptr = &header->type_ids_off_;
1361 break;
1362 case 3:
1363 off_ptr = &header->proto_ids_off_;
1364 break;
1365 case 4:
1366 off_ptr = &header->field_ids_off_;
1367 break;
1368 case 5:
1369 off_ptr = &header->method_ids_off_;
1370 break;
1371 case 6:
1372 off_ptr = &header->class_defs_off_;
1373 break;
1374
1375 static_assert(kSections == 7, "kSections is wrong");
1376 default:
1377 LOG(FATAL) << "Unexpected section";
1378 UNREACHABLE();
1379 }
1380 ASSERT_TRUE(off_ptr != nullptr);
1381 ASSERT_NE(*off_ptr, 0U) << i; // Should already contain a value (in use).
1382 (*off_ptr)++; // Add one, which should misalign it (all the sections
1383 // above are aligned by 4).
1384 },
1385 "should be aligned by 4 for");
1386 }
1387}
1388
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001389// Generated from
1390//
1391// .class LOverloading;
1392//
1393// .super Ljava/lang/Object;
1394//
1395// .method public static foo()V
1396// .registers 1
1397// return-void
1398// .end method
1399//
1400// .method public static foo(I)V
1401// .registers 1
1402// return-void
1403// .end method
1404static const char kProtoOrderingTestDex[] =
1405 "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
1406 "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
1407 "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
1408 "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
1409 "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
1410 "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
1411 "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
1412 "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
1413 "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";
1414
1415TEST_F(DexFileVerifierTest, ProtoOrdering) {
1416 {
1417 // The input dex file should be good before modification.
1418 ScratchFile tmp;
1419 std::string error_msg;
1420 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
1421 tmp.GetFilename().c_str(),
1422 &error_msg));
1423 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1424 }
1425
1426 // Modify the order of the ProtoIds for two overloads of "foo" with the
1427 // same return type and one having longer parameter list than the other.
1428 for (size_t i = 0; i != 2; ++i) {
1429 VerifyModification(
1430 kProtoOrderingTestDex,
1431 "proto_ordering",
1432 [i](DexFile* dex_file) {
1433 uint32_t method_idx;
1434 const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
1435 CHECK(data != nullptr);
1436 // There should be 2 methods called "foo".
1437 CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
1438 CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
1439 dex_file->GetMethodId(method_idx + 1).name_idx_);
1440 CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
1441 dex_file->GetMethodId(method_idx + 1).proto_idx_);
1442 // Their return types should be the same.
1443 uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
1444 const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
1445 const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
1446 CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
1447 // And the first should not have any parameters while the second should have some.
1448 CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
1449 CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
1450 if (i == 0) {
1451 // Swap the proto parameters and shorties to break the ordering.
1452 std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
1453 const_cast<uint32_t&>(proto2.parameters_off_));
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001454 std::swap(const_cast<dex::StringIndex&>(proto1.shorty_idx_),
1455 const_cast<dex::StringIndex&>(proto2.shorty_idx_));
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001456 } else {
1457 // Copy the proto parameters and shorty to create duplicate proto id.
1458 const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001459 const_cast<dex::StringIndex&>(proto1.shorty_idx_) = proto2.shorty_idx_;
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001460 }
1461 },
1462 "Out-of-order proto_id arguments");
1463 }
1464}
1465
Roland Levillain621b5ea2016-05-18 11:41:33 +01001466// To generate a base64 encoded Dex file version 037 from Smali files, use:
1467//
1468// smali --api-level 24 -o classes.dex class1.smali [class2.smali ...]
1469// base64 classes.dex >classes.dex.base64
1470
1471// Dex file version 037 generated from:
1472//
1473// .class public LB28685551;
1474// .super LB28685551;
1475
1476static const char kClassExtendsItselfTestDex[] =
1477 "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
1478 "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
1479 "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
1480 "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
1481 "mAAAAAAQAAABAAAAqAAAAA==";
1482
1483TEST_F(DexFileVerifierTest, ClassExtendsItself) {
1484 VerifyModification(
1485 kClassExtendsItselfTestDex,
1486 "class_extends_itself",
1487 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1488 "Class with same type idx as its superclass: '0'");
1489}
1490
1491// Dex file version 037 generated from:
1492//
1493// .class public LFoo;
1494// .super LBar;
1495//
1496// and:
1497//
1498// .class public LBar;
1499// .super LFoo;
1500
1501static const char kClassesExtendOneAnotherTestDex[] =
1502 "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
1503 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
1504 "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
1505 "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
1506 "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";
1507
1508TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
1509 VerifyModification(
1510 kClassesExtendOneAnotherTestDex,
1511 "classes_extend_one_another",
1512 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1513 "Invalid class definition ordering: class with type idx: '1' defined before"
1514 " superclass with type idx: '0'");
1515}
1516
1517// Dex file version 037 generated from:
1518//
1519// .class public LAll;
1520// .super LYour;
1521//
1522// and:
1523//
1524// .class public LYour;
1525// .super LBase;
1526//
1527// and:
1528//
1529// .class public LBase;
1530// .super LAll;
1531
1532static const char kCircularClassInheritanceTestDex[] =
1533 "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
1534 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
1535 "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
1536 "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
1537 "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
1538 "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";
1539
1540TEST_F(DexFileVerifierTest, CircularClassInheritance) {
1541 VerifyModification(
1542 kCircularClassInheritanceTestDex,
1543 "circular_class_inheritance",
1544 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1545 "Invalid class definition ordering: class with type idx: '1' defined before"
1546 " superclass with type idx: '0'");
1547}
1548
1549// Dex file version 037 generated from:
1550//
1551// .class public abstract interface LInterfaceImplementsItself;
1552// .super Ljava/lang/Object;
1553// .implements LInterfaceImplementsItself;
1554
1555static const char kInterfaceImplementsItselfTestDex[] =
1556 "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
1557 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
1558 "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
1559 "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
1560 "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
1561 "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";
1562
1563TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
1564 VerifyModification(
1565 kInterfaceImplementsItselfTestDex,
1566 "interface_implements_itself",
1567 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1568 "Class with same type idx as implemented interface: '0'");
1569}
1570
1571// Dex file version 037 generated from:
1572//
1573// .class public abstract interface LPing;
1574// .super Ljava/lang/Object;
1575// .implements LPong;
1576//
1577// and:
1578//
1579// .class public abstract interface LPong;
1580// .super Ljava/lang/Object;
1581// .implements LPing;
1582
1583static const char kInterfacesImplementOneAnotherTestDex[] =
1584 "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
1585 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
1586 "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
1587 "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
1588 "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
1589 "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";
1590
1591TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
1592 VerifyModification(
1593 kInterfacesImplementOneAnotherTestDex,
1594 "interfaces_implement_one_another",
1595 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1596 "Invalid class definition ordering: class with type idx: '1' defined before"
1597 " implemented interface with type idx: '0'");
1598}
1599
1600// Dex file version 037 generated from:
1601//
1602// .class public abstract interface LA;
1603// .super Ljava/lang/Object;
1604// .implements LB;
1605//
1606// and:
1607//
1608// .class public abstract interface LB;
1609// .super Ljava/lang/Object;
1610// .implements LC;
1611//
1612// and:
1613//
1614// .class public abstract interface LC;
1615// .super Ljava/lang/Object;
1616// .implements LA;
1617
1618static const char kCircularInterfaceImplementationTestDex[] =
1619 "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
1620 "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
1621 "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
1622 "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
1623 "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
1624 "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
1625 "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";
1626
1627TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
1628 VerifyModification(
1629 kCircularInterfaceImplementationTestDex,
1630 "circular_interface_implementation",
1631 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1632 "Invalid class definition ordering: class with type idx: '2' defined before"
1633 " implemented interface with type idx: '0'");
1634}
1635
Aart Bik37d6a3b2016-06-21 18:30:10 -07001636TEST_F(DexFileVerifierTest, Checksum) {
1637 size_t length;
Alex Light9c20a142016-08-23 15:05:12 -07001638 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kGoodTestDex, &length));
Aart Bik37d6a3b2016-06-21 18:30:10 -07001639 CHECK(dex_bytes != nullptr);
1640 // Note: `dex_file` will be destroyed before `dex_bytes`.
1641 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1642 std::string error_msg;
1643
1644 // Good checksum: all pass.
1645 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1646 dex_file->Begin(),
1647 dex_file->Size(),
1648 "good checksum, no verify",
1649 /*verify_checksum*/ false,
1650 &error_msg));
1651 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1652 dex_file->Begin(),
1653 dex_file->Size(),
1654 "good checksum, verify",
1655 /*verify_checksum*/ true,
1656 &error_msg));
1657
1658 // Bad checksum: !verify_checksum passes verify_checksum fails.
1659 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(
1660 const_cast<uint8_t*>(dex_file->Begin()));
1661 header->checksum_ = 0;
1662 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1663 dex_file->Begin(),
1664 dex_file->Size(),
1665 "bad checksum, no verify",
1666 /*verify_checksum*/ false,
1667 &error_msg));
1668 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1669 dex_file->Begin(),
1670 dex_file->Size(),
1671 "bad checksum, verify",
1672 /*verify_checksum*/ true,
1673 &error_msg));
1674 EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg;
1675}
1676
Andreas Gampedf10b322014-06-11 21:46:05 -07001677} // namespace art