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