1 /*
2 * Copyright (C) 2017 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 #define LOG_TAG "Zygote"
18
19 #include <android/graphics/jni_runtime.h>
20 #include <ui/GraphicBufferMapper.h>
21
22 #include "core_jni_helpers.h"
23
24 namespace {
25
26 // Shadow call stack (SCS) is a security mitigation that uses a separate stack
27 // (the SCS) for return addresses. In versions of Android newer than P, the
28 // compiler cooperates with the system to ensure that the SCS address is always
29 // stored in register x18, as long as the app was compiled with a new enough
30 // compiler and does not use features that rely on SP-HALs (this restriction is
31 // because the SP-HALs might not preserve x18 due to potentially having been
32 // compiled with an old compiler as a consequence of Treble; it generally means
33 // that the app must be a system app without a UI). This struct is used to
34 // temporarily store the address on the stack while preloading the SP-HALs, so
35 // that such apps can use the same zygote as everything else.
36 struct ScopedSCSExit {
37 #ifdef __aarch64__
38 void* scs;
39
ScopedSCSExit__anonf093bb110110::ScopedSCSExit40 ScopedSCSExit() {
41 __asm__ __volatile__("str x18, [%0]" ::"r"(&scs));
42 }
43
~ScopedSCSExit__anonf093bb110110::ScopedSCSExit44 ~ScopedSCSExit() {
45 __asm__ __volatile__("ldr x18, [%0]; str xzr, [%0]" ::"r"(&scs));
46 }
47 #else
48 // Silence unused variable warnings in non-SCS builds.
49 ScopedSCSExit() {}
50 ~ScopedSCSExit() {}
51 #endif
52 };
53
android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv * env,jclass)54 void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) {
55 ScopedSCSExit x;
56 android::GraphicBufferMapper::preloadHal();
57 // Add preloading here for other HALs that are (a) always passthrough, and
58 // (b) loaded by most app processes.
59 }
60
android_internal_os_ZygoteInit_nativePreloadGraphicsDriver(JNIEnv * env,jclass)61 void android_internal_os_ZygoteInit_nativePreloadGraphicsDriver(JNIEnv* env, jclass) {
62 ScopedSCSExit x;
63 zygote_preload_graphics();
64 }
65
66 const JNINativeMethod gMethods[] = {
67 { "nativePreloadAppProcessHALs", "()V",
68 (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs },
69 { "nativePreloadGraphicsDriver", "()V",
70 (void*)android_internal_os_ZygoteInit_nativePreloadGraphicsDriver },
71 };
72
73 } // anonymous namespace
74
75 namespace android {
76
register_com_android_internal_os_ZygoteInit(JNIEnv * env)77 int register_com_android_internal_os_ZygoteInit(JNIEnv* env) {
78 return RegisterMethodsOrDie(env, "com/android/internal/os/ZygoteInit",
79 gMethods, NELEM(gMethods));
80 }
81
82 } // namespace android
83