1 /*
2 * Copyright (C) 2008 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 "dalvik_system_ZygoteHooks.h"
18
19 #include <stdlib.h>
20
21 #include <android-base/logging.h>
22 #include <android-base/stringprintf.h>
23
24 #include "arch/instruction_set.h"
25 #include "art_method-inl.h"
26 #include "base/macros.h"
27 #include "base/mutex.h"
28 #include "base/runtime_debug.h"
29 #include "debugger.h"
30 #include "hidden_api.h"
31 #include "jit/jit.h"
32 #include "jit/jit_code_cache.h"
33 #include "jni/java_vm_ext.h"
34 #include "jni/jni_internal.h"
35 #include "native_util.h"
36 #include "nativehelper/jni_macros.h"
37 #include "nativehelper/scoped_utf_chars.h"
38 #include "non_debuggable_classes.h"
39 #include "oat_file.h"
40 #include "oat_file_manager.h"
41 #include "scoped_thread_state_change-inl.h"
42 #include "stack.h"
43 #include "thread-current-inl.h"
44 #include "thread_list.h"
45 #include "trace.h"
46
47 #include <sys/resource.h>
48
49 namespace art {
50
51 // Set to true to always determine the non-debuggable classes even if we would not allow a debugger
52 // to actually attach.
53 static bool kAlwaysCollectNonDebuggableClasses =
54 RegisterRuntimeDebugFlag(&kAlwaysCollectNonDebuggableClasses);
55
56 using android::base::StringPrintf;
57
58 class ClassSet {
59 public:
60 // The number of classes we reasonably expect to have to look at. Realistically the number is more
61 // ~10 but there is little harm in having some extra.
62 static constexpr int kClassSetCapacity = 100;
63
ClassSet(Thread * const self)64 explicit ClassSet(Thread* const self) : self_(self) {
65 self_->GetJniEnv()->PushFrame(kClassSetCapacity);
66 }
67
~ClassSet()68 ~ClassSet() {
69 self_->GetJniEnv()->PopFrame();
70 }
71
AddClass(ObjPtr<mirror::Class> klass)72 void AddClass(ObjPtr<mirror::Class> klass) REQUIRES(Locks::mutator_lock_) {
73 class_set_.insert(self_->GetJniEnv()->AddLocalReference<jclass>(klass));
74 }
75
GetClasses() const76 const std::unordered_set<jclass>& GetClasses() const {
77 return class_set_;
78 }
79
80 private:
81 Thread* const self_;
82 std::unordered_set<jclass> class_set_;
83 };
84
DoCollectNonDebuggableCallback(Thread * thread,void * data)85 static void DoCollectNonDebuggableCallback(Thread* thread, void* data)
86 REQUIRES(Locks::mutator_lock_) {
87 class NonDebuggableStacksVisitor : public StackVisitor {
88 public:
89 NonDebuggableStacksVisitor(Thread* t, ClassSet* class_set)
90 : StackVisitor(t, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
91 class_set_(class_set) {}
92
93 ~NonDebuggableStacksVisitor() override {}
94
95 bool VisitFrame() override REQUIRES(Locks::mutator_lock_) {
96 if (GetMethod()->IsRuntimeMethod()) {
97 return true;
98 }
99 class_set_->AddClass(GetMethod()->GetDeclaringClass());
100 if (kIsDebugBuild) {
101 LOG(INFO) << GetMethod()->GetDeclaringClass()->PrettyClass()
102 << " might not be fully debuggable/deoptimizable due to "
103 << GetMethod()->PrettyMethod() << " appearing on the stack during zygote fork.";
104 }
105 return true;
106 }
107
108 private:
109 ClassSet* class_set_;
110 };
111 NonDebuggableStacksVisitor visitor(thread, reinterpret_cast<ClassSet*>(data));
112 visitor.WalkStack();
113 }
114
CollectNonDebuggableClasses()115 static void CollectNonDebuggableClasses() REQUIRES(!Locks::mutator_lock_) {
116 Runtime* const runtime = Runtime::Current();
117 Thread* const self = Thread::Current();
118 // Get the mutator lock.
119 ScopedObjectAccess soa(self);
120 ClassSet classes(self);
121 {
122 // Drop the shared mutator lock.
123 ScopedThreadSuspension sts(self, art::ThreadState::kNative);
124 // Get exclusive mutator lock with suspend all.
125 ScopedSuspendAll suspend("Checking stacks for non-obsoletable methods!",
126 /*long_suspend=*/false);
127 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
128 runtime->GetThreadList()->ForEach(DoCollectNonDebuggableCallback, &classes);
129 }
130 for (jclass klass : classes.GetClasses()) {
131 NonDebuggableClasses::AddNonDebuggableClass(klass);
132 }
133 }
134
135 // Must match values in com.android.internal.os.Zygote.
136 enum {
137 DEBUG_ENABLE_JDWP = 1,
138 DEBUG_ENABLE_CHECKJNI = 1 << 1,
139 DEBUG_ENABLE_ASSERT = 1 << 2,
140 DEBUG_ENABLE_SAFEMODE = 1 << 3,
141 DEBUG_ENABLE_JNI_LOGGING = 1 << 4,
142 DEBUG_GENERATE_DEBUG_INFO = 1 << 5,
143 DEBUG_ALWAYS_JIT = 1 << 6,
144 DEBUG_NATIVE_DEBUGGABLE = 1 << 7,
145 DEBUG_JAVA_DEBUGGABLE = 1 << 8,
146 DISABLE_VERIFIER = 1 << 9,
147 ONLY_USE_SYSTEM_OAT_FILES = 1 << 10,
148 DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11,
149 HIDDEN_API_ENFORCEMENT_POLICY_MASK = (1 << 12)
150 | (1 << 13),
151 PROFILE_SYSTEM_SERVER = 1 << 14,
152 USE_APP_IMAGE_STARTUP_CACHE = 1 << 16,
153
154 // bits to shift (flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) by to get a value
155 // corresponding to hiddenapi::EnforcementPolicy
156 API_ENFORCEMENT_POLICY_SHIFT = CTZ(HIDDEN_API_ENFORCEMENT_POLICY_MASK),
157 };
158
EnableDebugFeatures(uint32_t runtime_flags)159 static uint32_t EnableDebugFeatures(uint32_t runtime_flags) {
160 Runtime* const runtime = Runtime::Current();
161 if ((runtime_flags & DEBUG_ENABLE_CHECKJNI) != 0) {
162 JavaVMExt* vm = runtime->GetJavaVM();
163 if (!vm->IsCheckJniEnabled()) {
164 LOG(INFO) << "Late-enabling -Xcheck:jni";
165 vm->SetCheckJniEnabled(true);
166 // There's only one thread running at this point, so only one JNIEnv to fix up.
167 Thread::Current()->GetJniEnv()->SetCheckJniEnabled(true);
168 } else {
169 LOG(INFO) << "Not late-enabling -Xcheck:jni (already on)";
170 }
171 runtime_flags &= ~DEBUG_ENABLE_CHECKJNI;
172 }
173
174 if ((runtime_flags & DEBUG_ENABLE_JNI_LOGGING) != 0) {
175 gLogVerbosity.third_party_jni = true;
176 runtime_flags &= ~DEBUG_ENABLE_JNI_LOGGING;
177 }
178
179 Dbg::SetJdwpAllowed((runtime_flags & DEBUG_ENABLE_JDWP) != 0);
180 runtime_flags &= ~DEBUG_ENABLE_JDWP;
181
182 const bool safe_mode = (runtime_flags & DEBUG_ENABLE_SAFEMODE) != 0;
183 if (safe_mode) {
184 // Only quicken oat files.
185 runtime->AddCompilerOption("--compiler-filter=quicken");
186 runtime->SetSafeMode(true);
187 runtime_flags &= ~DEBUG_ENABLE_SAFEMODE;
188 }
189
190 // This is for backwards compatibility with Dalvik.
191 runtime_flags &= ~DEBUG_ENABLE_ASSERT;
192
193 if ((runtime_flags & DEBUG_ALWAYS_JIT) != 0) {
194 jit::JitOptions* jit_options = runtime->GetJITOptions();
195 CHECK(jit_options != nullptr);
196 Runtime::Current()->DoAndMaybeSwitchInterpreter([=]() {
197 jit_options->SetJitAtFirstUse();
198 });
199 runtime_flags &= ~DEBUG_ALWAYS_JIT;
200 }
201
202 bool needs_non_debuggable_classes = false;
203 if ((runtime_flags & DEBUG_JAVA_DEBUGGABLE) != 0) {
204 runtime->AddCompilerOption("--debuggable");
205 runtime_flags |= DEBUG_GENERATE_MINI_DEBUG_INFO;
206 runtime->SetJavaDebuggable(true);
207 {
208 // Deoptimize the boot image as it may be non-debuggable.
209 ScopedSuspendAll ssa(__FUNCTION__);
210 runtime->DeoptimizeBootImage();
211 }
212 runtime_flags &= ~DEBUG_JAVA_DEBUGGABLE;
213 needs_non_debuggable_classes = true;
214 }
215 if (needs_non_debuggable_classes || kAlwaysCollectNonDebuggableClasses) {
216 CollectNonDebuggableClasses();
217 }
218
219 if ((runtime_flags & DEBUG_NATIVE_DEBUGGABLE) != 0) {
220 runtime->AddCompilerOption("--debuggable");
221 runtime_flags |= DEBUG_GENERATE_DEBUG_INFO;
222 runtime->SetNativeDebuggable(true);
223 runtime_flags &= ~DEBUG_NATIVE_DEBUGGABLE;
224 }
225
226 if ((runtime_flags & DEBUG_GENERATE_MINI_DEBUG_INFO) != 0) {
227 // Generate native minimal debug information to allow backtracing.
228 runtime->AddCompilerOption("--generate-mini-debug-info");
229 runtime_flags &= ~DEBUG_GENERATE_MINI_DEBUG_INFO;
230 }
231
232 if ((runtime_flags & DEBUG_GENERATE_DEBUG_INFO) != 0) {
233 // Generate all native debug information we can (e.g. line-numbers).
234 runtime->AddCompilerOption("--generate-debug-info");
235 runtime_flags &= ~DEBUG_GENERATE_DEBUG_INFO;
236 }
237
238 return runtime_flags;
239 }
240
ZygoteHooks_nativePreFork(JNIEnv * env,jclass)241 static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
242 Runtime* runtime = Runtime::Current();
243 CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote";
244
245 runtime->PreZygoteFork();
246
247 // Grab thread before fork potentially makes Thread::pthread_key_self_ unusable.
248 return reinterpret_cast<jlong>(ThreadForEnv(env));
249 }
250
ZygoteHooks_nativePostZygoteFork(JNIEnv *,jclass)251 static void ZygoteHooks_nativePostZygoteFork(JNIEnv*, jclass) {
252 Runtime* runtime = Runtime::Current();
253 if (runtime->IsZygote()) {
254 runtime->PostZygoteFork();
255 }
256 }
257
ZygoteHooks_nativePostForkSystemServer(JNIEnv * env ATTRIBUTE_UNUSED,jclass klass ATTRIBUTE_UNUSED)258 static void ZygoteHooks_nativePostForkSystemServer(JNIEnv* env ATTRIBUTE_UNUSED,
259 jclass klass ATTRIBUTE_UNUSED) {
260 Runtime::Current()->SetSystemServer(true);
261 // This JIT code cache for system server is created whilst the runtime is still single threaded.
262 // System server has a window where it can create executable pages for this purpose, but this is
263 // turned off after this hook. Consequently, the only JIT mode supported is the dual-view JIT
264 // where one mapping is R->RW and the other is RX. Single view requires RX->RWX->RX.
265 if (Runtime::Current()->GetJit() != nullptr) {
266 Runtime::Current()->GetJit()->GetCodeCache()->PostForkChildAction(
267 /* is_system_server= */ true, /* is_zygote= */ false);
268 }
269 // Allow picking up verity-protected files from the dalvik cache for pre-caching. This window will
270 // be closed in the common nativePostForkChild below.
271 Runtime::Current()->GetOatFileManager().SetOnlyUseSystemOatFiles(
272 /*enforce=*/false, /*assert_no_files_loaded=*/false);
273 }
274
ZygoteHooks_nativePostForkChild(JNIEnv * env,jclass,jlong token,jint runtime_flags,jboolean is_system_server,jboolean is_zygote,jstring instruction_set)275 static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
276 jclass,
277 jlong token,
278 jint runtime_flags,
279 jboolean is_system_server,
280 jboolean is_zygote,
281 jstring instruction_set) {
282 DCHECK(!(is_system_server && is_zygote));
283
284 Thread* thread = reinterpret_cast<Thread*>(token);
285 // Our system thread ID, etc, has changed so reset Thread state.
286 thread->InitAfterFork();
287 runtime_flags = EnableDebugFeatures(runtime_flags);
288 hiddenapi::EnforcementPolicy api_enforcement_policy = hiddenapi::EnforcementPolicy::kDisabled;
289
290 Runtime* runtime = Runtime::Current();
291
292 if ((runtime_flags & DISABLE_VERIFIER) != 0) {
293 runtime->DisableVerifier();
294 runtime_flags &= ~DISABLE_VERIFIER;
295 }
296
297 bool only_use_system_oat_files = false;
298 if ((runtime_flags & ONLY_USE_SYSTEM_OAT_FILES) != 0 || is_system_server) {
299 only_use_system_oat_files = true;
300 runtime_flags &= ~ONLY_USE_SYSTEM_OAT_FILES;
301 }
302 runtime->GetOatFileManager().SetOnlyUseSystemOatFiles(only_use_system_oat_files,
303 !is_system_server);
304
305 api_enforcement_policy = hiddenapi::EnforcementPolicyFromInt(
306 (runtime_flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT);
307 runtime_flags &= ~HIDDEN_API_ENFORCEMENT_POLICY_MASK;
308
309 bool profile_system_server = (runtime_flags & PROFILE_SYSTEM_SERVER) == PROFILE_SYSTEM_SERVER;
310 runtime_flags &= ~PROFILE_SYSTEM_SERVER;
311
312 runtime->SetLoadAppImageStartupCacheEnabled(
313 (runtime_flags & USE_APP_IMAGE_STARTUP_CACHE) != 0u);
314 runtime_flags &= ~USE_APP_IMAGE_STARTUP_CACHE;
315
316 if (runtime_flags != 0) {
317 LOG(ERROR) << StringPrintf("Unknown bits set in runtime_flags: %#x", runtime_flags);
318 }
319
320 runtime->GetHeap()->PostForkChildAction(thread);
321 if (runtime->GetJit() != nullptr) {
322 if (!is_system_server) {
323 // System server already called the JIT cache post fork action in `nativePostForkSystemServer`.
324 runtime->GetJit()->GetCodeCache()->PostForkChildAction(
325 /* is_system_server= */ false, is_zygote);
326 }
327 // This must be called after EnableDebugFeatures.
328 runtime->GetJit()->PostForkChildAction(is_system_server, is_zygote);
329 }
330
331 // Update tracing.
332 if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
333 Trace::TraceOutputMode output_mode = Trace::GetOutputMode();
334 Trace::TraceMode trace_mode = Trace::GetMode();
335 size_t buffer_size = Trace::GetBufferSize();
336
337 // Just drop it.
338 Trace::Abort();
339
340 // Only restart if it was streaming mode.
341 // TODO: Expose buffer size, so we can also do file mode.
342 if (output_mode == Trace::TraceOutputMode::kStreaming) {
343 static constexpr size_t kMaxProcessNameLength = 100;
344 char name_buf[kMaxProcessNameLength] = {};
345 int rc = pthread_getname_np(pthread_self(), name_buf, kMaxProcessNameLength);
346 std::string proc_name;
347
348 if (rc == 0) {
349 // On success use the pthread name.
350 proc_name = name_buf;
351 }
352
353 if (proc_name.empty() || proc_name == "zygote" || proc_name == "zygote64") {
354 // Either no process name, or the name hasn't been changed, yet. Just use pid.
355 pid_t pid = getpid();
356 proc_name = StringPrintf("%u", static_cast<uint32_t>(pid));
357 }
358
359 std::string trace_file = StringPrintf("/data/misc/trace/%s.trace.bin", proc_name.c_str());
360 Trace::Start(trace_file.c_str(),
361 buffer_size,
362 0, // TODO: Expose flags.
363 output_mode,
364 trace_mode,
365 0); // TODO: Expose interval.
366 if (thread->IsExceptionPending()) {
367 ScopedObjectAccess soa(env);
368 thread->ClearException();
369 }
370 }
371 }
372
373 bool do_hidden_api_checks = api_enforcement_policy != hiddenapi::EnforcementPolicy::kDisabled;
374 DCHECK(!(is_system_server && do_hidden_api_checks))
375 << "SystemServer should be forked with EnforcementPolicy::kDisable";
376 DCHECK(!(is_zygote && do_hidden_api_checks))
377 << "Child zygote processes should be forked with EnforcementPolicy::kDisable";
378 runtime->SetHiddenApiEnforcementPolicy(api_enforcement_policy);
379 runtime->SetDedupeHiddenApiWarnings(true);
380 if (api_enforcement_policy != hiddenapi::EnforcementPolicy::kDisabled &&
381 runtime->GetHiddenApiEventLogSampleRate() != 0) {
382 // Hidden API checks are enabled, and we are sampling access for the event log. Initialize the
383 // random seed, to ensure the sampling is actually random. We do this post-fork, as doing it
384 // pre-fork would result in the same sequence for every forked process.
385 std::srand(static_cast<uint32_t>(NanoTime()));
386 }
387
388 if (is_zygote) {
389 // If creating a child-zygote, do not call into the runtime's post-fork logic.
390 // Doing so would spin up threads for Binder and JDWP. Instead, the Java side
391 // of the child process will call a static main in a class specified by the parent.
392 return;
393 }
394
395 if (instruction_set != nullptr && !is_system_server) {
396 ScopedUtfChars isa_string(env, instruction_set);
397 InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
398 Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload;
399 if (isa != InstructionSet::kNone && isa != kRuntimeISA) {
400 action = Runtime::NativeBridgeAction::kInitialize;
401 }
402 runtime->InitNonZygoteOrPostFork(env, is_system_server, action, isa_string.c_str());
403 } else {
404 runtime->InitNonZygoteOrPostFork(
405 env,
406 is_system_server,
407 Runtime::NativeBridgeAction::kUnload,
408 /*isa=*/ nullptr,
409 profile_system_server);
410 }
411 }
412
ZygoteHooks_startZygoteNoThreadCreation(JNIEnv * env ATTRIBUTE_UNUSED,jclass klass ATTRIBUTE_UNUSED)413 static void ZygoteHooks_startZygoteNoThreadCreation(JNIEnv* env ATTRIBUTE_UNUSED,
414 jclass klass ATTRIBUTE_UNUSED) {
415 Runtime::Current()->SetZygoteNoThreadSection(true);
416 }
417
ZygoteHooks_stopZygoteNoThreadCreation(JNIEnv * env ATTRIBUTE_UNUSED,jclass klass ATTRIBUTE_UNUSED)418 static void ZygoteHooks_stopZygoteNoThreadCreation(JNIEnv* env ATTRIBUTE_UNUSED,
419 jclass klass ATTRIBUTE_UNUSED) {
420 Runtime::Current()->SetZygoteNoThreadSection(false);
421 }
422
423 static JNINativeMethod gMethods[] = {
424 NATIVE_METHOD(ZygoteHooks, nativePreFork, "()J"),
425 NATIVE_METHOD(ZygoteHooks, nativePostZygoteFork, "()V"),
426 NATIVE_METHOD(ZygoteHooks, nativePostForkSystemServer, "()V"),
427 NATIVE_METHOD(ZygoteHooks, nativePostForkChild, "(JIZZLjava/lang/String;)V"),
428 NATIVE_METHOD(ZygoteHooks, startZygoteNoThreadCreation, "()V"),
429 NATIVE_METHOD(ZygoteHooks, stopZygoteNoThreadCreation, "()V"),
430 };
431
register_dalvik_system_ZygoteHooks(JNIEnv * env)432 void register_dalvik_system_ZygoteHooks(JNIEnv* env) {
433 REGISTER_NATIVE_METHODS("dalvik/system/ZygoteHooks");
434 }
435
436 } // namespace art
437