• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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