blob: 5b6a07d77853ac7775ff126329758b2d14c40444 [file] [log] [blame]
Andreas Gampea43ba3d2019-03-13 15:49:20 -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 "class_verifier.h"
18
19#include <android-base/logging.h>
20#include <android-base/stringprintf.h>
21
22#include "art_method-inl.h"
Alex Lightb1eebde2019-10-22 16:30:47 +000023#include "base/enums.h"
Alex Lightc2d0c962019-10-23 14:14:25 -070024#include "base/locks.h"
25#include "base/logging.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -070026#include "base/systrace.h"
27#include "base/utils.h"
28#include "class_linker.h"
29#include "compiler_callbacks.h"
30#include "dex/class_accessor-inl.h"
31#include "dex/class_reference.h"
32#include "dex/descriptors_names.h"
33#include "dex/dex_file-inl.h"
Alex Lightb1eebde2019-10-22 16:30:47 +000034#include "handle.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -070035#include "handle_scope-inl.h"
36#include "method_verifier-inl.h"
37#include "mirror/class-inl.h"
38#include "mirror/dex_cache.h"
39#include "runtime.h"
Alex Lightb1eebde2019-10-22 16:30:47 +000040#include "thread.h"
Alex Lightc2d0c962019-10-23 14:14:25 -070041#include "verifier/method_verifier.h"
42#include "verifier/reg_type_cache.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -070043
44namespace art {
45namespace verifier {
46
47using android::base::StringPrintf;
48
49// We print a warning blurb about "dx --no-optimize" when we find monitor-locking issues. Make
50// sure we only print this once.
51static bool gPrintedDxMonitorText = false;
52
Alex Lightc2d0c962019-10-23 14:14:25 -070053class StandardVerifyCallback : public VerifierCallback {
54 public:
55 void SetDontCompile(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
56 if (value) {
57 m->SetDontCompile();
58 }
59 }
60 void SetMustCountLocks(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
61 if (value) {
62 m->SetMustCountLocks();
63 }
64 }
65};
66
Alex Lightb1eebde2019-10-22 16:30:47 +000067FailureKind ClassVerifier::ReverifyClass(Thread* self,
68 ObjPtr<mirror::Class> klass,
69 HardFailLogMode log_level,
70 uint32_t api_level,
71 std::string* error) {
72 DCHECK(!Runtime::Current()->IsAotCompiler());
73 StackHandleScope<1> hs(self);
74 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Alex Lightc2d0c962019-10-23 14:14:25 -070075 // We don't want to mess with these while other mutators are possibly looking at them. Instead we
76 // will wait until we can update them while everything is suspended.
77 class DelayedVerifyCallback : public VerifierCallback {
78 public:
79 void SetDontCompile(ArtMethod* m, bool value) override REQUIRES_SHARED(Locks::mutator_lock_) {
80 dont_compiles_.push_back({ m, value });
81 }
82 void SetMustCountLocks(ArtMethod* m, bool value) override
83 REQUIRES_SHARED(Locks::mutator_lock_) {
84 count_locks_.push_back({ m, value });
85 }
86 void UpdateFlags(bool skip_access_checks) REQUIRES(Locks::mutator_lock_) {
87 for (auto it : count_locks_) {
88 VLOG(verifier_debug) << "Setting " << it.first->PrettyMethod() << " count locks to "
89 << it.second;
90 if (it.second) {
91 it.first->SetMustCountLocks();
92 } else {
93 it.first->ClearMustCountLocks();
94 }
95 if (skip_access_checks && it.first->IsInvokable() && !it.first->IsNative()) {
96 it.first->SetSkipAccessChecks();
97 }
98 }
99 for (auto it : dont_compiles_) {
100 VLOG(verifier_debug) << "Setting " << it.first->PrettyMethod() << " dont-compile to "
101 << it.second;
102 if (it.second) {
103 it.first->SetDontCompile();
104 } else {
105 it.first->ClearDontCompile();
106 }
107 }
108 }
109
110 private:
111 std::vector<std::pair<ArtMethod*, bool>> dont_compiles_;
112 std::vector<std::pair<ArtMethod*, bool>> count_locks_;
113 };
114 DelayedVerifyCallback dvc;
Alex Lightb1eebde2019-10-22 16:30:47 +0000115 FailureKind res = CommonVerifyClass(self,
116 h_klass.Get(),
117 /*callbacks=*/nullptr,
Alex Lightc2d0c962019-10-23 14:14:25 -0700118 &dvc,
Alex Lightb1eebde2019-10-22 16:30:47 +0000119 /*allow_soft_failures=*/false,
120 log_level,
121 api_level,
Alex Lightb1eebde2019-10-22 16:30:47 +0000122 error);
Alex Lightc2d0c962019-10-23 14:14:25 -0700123 DCHECK_NE(res, FailureKind::kHardFailure);
124 ScopedThreadSuspension sts(Thread::Current(), ThreadState::kSuspended);
125 ScopedSuspendAll ssa("Update method flags for reverify");
126 dvc.UpdateFlags(res == FailureKind::kNoFailure);
Alex Lightb1eebde2019-10-22 16:30:47 +0000127 return res;
128}
129
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700130FailureKind ClassVerifier::VerifyClass(Thread* self,
131 ObjPtr<mirror::Class> klass,
132 CompilerCallbacks* callbacks,
133 bool allow_soft_failures,
134 HardFailLogMode log_level,
135 uint32_t api_level,
136 std::string* error) {
137 if (klass->IsVerified()) {
138 return FailureKind::kNoFailure;
139 }
Alex Lightc2d0c962019-10-23 14:14:25 -0700140 StandardVerifyCallback svc;
Alex Lightb1eebde2019-10-22 16:30:47 +0000141 return CommonVerifyClass(self,
142 klass,
143 callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700144 &svc,
Alex Lightb1eebde2019-10-22 16:30:47 +0000145 allow_soft_failures,
146 log_level,
147 api_level,
Alex Lightb1eebde2019-10-22 16:30:47 +0000148 error);
149}
Alex Lightc2d0c962019-10-23 14:14:25 -0700150
Alex Lightb1eebde2019-10-22 16:30:47 +0000151FailureKind ClassVerifier::CommonVerifyClass(Thread* self,
152 ObjPtr<mirror::Class> klass,
153 CompilerCallbacks* callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700154 VerifierCallback* verifier_callback,
Alex Lightb1eebde2019-10-22 16:30:47 +0000155 bool allow_soft_failures,
156 HardFailLogMode log_level,
157 uint32_t api_level,
Alex Lightb1eebde2019-10-22 16:30:47 +0000158 std::string* error) {
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700159 bool early_failure = false;
160 std::string failure_message;
161 const DexFile& dex_file = klass->GetDexFile();
162 const dex::ClassDef* class_def = klass->GetClassDef();
163 ObjPtr<mirror::Class> super = klass->GetSuperClass();
164 std::string temp;
165 if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
166 early_failure = true;
167 failure_message = " that has no super class";
168 } else if (super != nullptr && super->IsFinal()) {
169 early_failure = true;
170 failure_message = " that attempts to sub-class final class " + super->PrettyDescriptor();
171 } else if (class_def == nullptr) {
172 early_failure = true;
173 failure_message = " that isn't present in dex file " + dex_file.GetLocation();
174 }
175 if (early_failure) {
176 *error = "Verifier rejected class " + klass->PrettyDescriptor() + failure_message;
177 if (callbacks != nullptr) {
178 ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
179 callbacks->ClassRejected(ref);
180 }
181 return FailureKind::kHardFailure;
182 }
183 StackHandleScope<2> hs(self);
184 Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
185 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
186 return VerifyClass(self,
187 &dex_file,
188 dex_cache,
189 class_loader,
190 *class_def,
191 callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700192 verifier_callback,
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700193 allow_soft_failures,
194 log_level,
195 api_level,
196 error);
197}
198
Alex Lightc2d0c962019-10-23 14:14:25 -0700199
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700200FailureKind ClassVerifier::VerifyClass(Thread* self,
201 const DexFile* dex_file,
202 Handle<mirror::DexCache> dex_cache,
203 Handle<mirror::ClassLoader> class_loader,
204 const dex::ClassDef& class_def,
205 CompilerCallbacks* callbacks,
206 bool allow_soft_failures,
207 HardFailLogMode log_level,
208 uint32_t api_level,
209 std::string* error) {
Alex Lightc2d0c962019-10-23 14:14:25 -0700210 StandardVerifyCallback svc;
Alex Lightb1eebde2019-10-22 16:30:47 +0000211 return VerifyClass(self,
212 dex_file,
213 dex_cache,
214 class_loader,
215 class_def,
216 callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700217 &svc,
Alex Lightb1eebde2019-10-22 16:30:47 +0000218 allow_soft_failures,
219 log_level,
220 api_level,
Alex Lightb1eebde2019-10-22 16:30:47 +0000221 error);
222}
223
224FailureKind ClassVerifier::VerifyClass(Thread* self,
225 const DexFile* dex_file,
226 Handle<mirror::DexCache> dex_cache,
227 Handle<mirror::ClassLoader> class_loader,
228 const dex::ClassDef& class_def,
229 CompilerCallbacks* callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700230 VerifierCallback* verifier_callback,
Alex Lightb1eebde2019-10-22 16:30:47 +0000231 bool allow_soft_failures,
232 HardFailLogMode log_level,
233 uint32_t api_level,
Alex Lightb1eebde2019-10-22 16:30:47 +0000234 std::string* error) {
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700235 // A class must not be abstract and final.
236 if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) {
237 *error = "Verifier rejected class ";
238 *error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
239 *error += ": class is abstract and final.";
240 return FailureKind::kHardFailure;
241 }
242
243 ClassAccessor accessor(*dex_file, class_def);
244 SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(accessor.GetDescriptor());
Eric Holka79872b2020-10-01 13:09:53 -0700245 metrics::AutoTimer timer{GetMetrics()->ClassVerificationTotalTime()};
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700246
247 int64_t previous_method_idx[2] = { -1, -1 };
248 MethodVerifier::FailureData failure_data;
249 ClassLinker* const linker = Runtime::Current()->GetClassLinker();
250
251 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
252 int64_t* previous_idx = &previous_method_idx[method.IsStaticOrDirect() ? 0u : 1u];
253 self->AllowThreadSuspension();
254 const uint32_t method_idx = method.GetIndex();
255 if (method_idx == *previous_idx) {
256 // smali can create dex files with two encoded_methods sharing the same method_idx
257 // http://code.google.com/p/smali/issues/detail?id=119
258 continue;
259 }
260 *previous_idx = method_idx;
261 const InvokeType type = method.GetInvokeType(class_def.access_flags_);
262 ArtMethod* resolved_method = linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
263 method_idx, dex_cache, class_loader, /* referrer= */ nullptr, type);
264 if (resolved_method == nullptr) {
265 DCHECK(self->IsExceptionPending());
266 // We couldn't resolve the method, but continue regardless.
267 self->ClearException();
268 } else {
269 DCHECK(resolved_method->GetDeclaringClassUnchecked() != nullptr) << type;
270 }
271 std::string hard_failure_msg;
272 MethodVerifier::FailureData result =
273 MethodVerifier::VerifyMethod(self,
Andreas Gampee0bbab92019-07-25 12:28:22 -0700274 linker,
Andreas Gampef1468b52019-07-26 09:22:39 -0700275 Runtime::Current()->GetArenaPool(),
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700276 method_idx,
277 dex_file,
278 dex_cache,
279 class_loader,
280 class_def,
281 method.GetCodeItem(),
282 resolved_method,
283 method.GetAccessFlags(),
284 callbacks,
Alex Lightc2d0c962019-10-23 14:14:25 -0700285 verifier_callback,
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700286 allow_soft_failures,
287 log_level,
288 /*need_precise_constants=*/ false,
289 api_level,
Andreas Gampefef91cc2019-07-25 14:13:23 -0700290 Runtime::Current()->IsAotCompiler(),
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700291 &hard_failure_msg);
292 if (result.kind == FailureKind::kHardFailure) {
293 if (failure_data.kind == FailureKind::kHardFailure) {
294 // If we logged an error before, we need a newline.
295 *error += "\n";
296 } else {
297 // If we didn't log a hard failure before, print the header of the message.
298 *error += "Verifier rejected class ";
299 *error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
300 *error += ":";
301 }
302 *error += " ";
303 *error += hard_failure_msg;
304 }
305 failure_data.Merge(result);
306 }
Eric Holka79872b2020-10-01 13:09:53 -0700307 uint64_t elapsed_time_microseconds = timer.Stop();
Eric Holk4bb09002020-09-30 11:42:34 -0700308 VLOG(verifier) << "VerifyClass took " << PrettyDuration(UsToNs(elapsed_time_microseconds))
Rock.Yehfa88d522020-06-23 21:29:19 +0800309 << ", class: " << PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700310
Eric Holke7ff7ef2021-03-17 16:42:24 -0700311 GetMetrics()->ClassVerificationCount()->AddOne();
312
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700313 if (failure_data.kind == FailureKind::kNoFailure) {
314 return FailureKind::kNoFailure;
315 } else {
316 if ((failure_data.types & VERIFY_ERROR_LOCKING) != 0) {
317 // Print a warning about expected slow-down. Use a string temporary to print one contiguous
318 // warning.
319 std::string tmp =
320 StringPrintf("Class %s failed lock verification and will run slower.",
321 PrettyDescriptor(accessor.GetDescriptor()).c_str());
322 if (!gPrintedDxMonitorText) {
323 tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n"
324 "and incorrect proguard optimizations.";
325 gPrintedDxMonitorText = true;
326 }
327 LOG(WARNING) << tmp;
328 }
329 return failure_data.kind;
330 }
331}
332
Andreas Gampee0bbab92019-07-25 12:28:22 -0700333void ClassVerifier::Init(ClassLinker* class_linker) {
334 MethodVerifier::Init(class_linker);
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700335}
336
337void ClassVerifier::Shutdown() {
338 MethodVerifier::Shutdown();
339}
340
341void ClassVerifier::VisitStaticRoots(RootVisitor* visitor) {
342 MethodVerifier::VisitStaticRoots(visitor);
343}
344
345} // namespace verifier
346} // namespace art