From 6f4986b67c77305a30fda0f4b3d1f16f879c1a14 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 26 Oct 2018 14:52:14 -0700 Subject: Preserve x18 while preloading SP-HALs in the zygote. Shadow call stack (SCS) is a security mitigation that uses a separate stack (the SCS) for return addresses. In versions of Android newer than P, the compiler cooperates with the system to ensure that the SCS address is always stored in register x18, as long as the app was compiled with a new enough compiler and does not use features that rely on SP-HALs (this restriction is because the SP-HALs might not preserve x18 due to potentially having been compiled with an old compiler as a consequence of Treble; it generally means that the app must be a system app without a UI). This change makes it so that we temporarily store the address on the stack while preloading the SP-HALs, so that such apps can use the same zygote as everything else. Bug: 112907825 Change-Id: I5300fe89a0bba514894bdfb58237091d80fd0db8 --- core/java/com/android/internal/os/ZygoteInit.java | 3 +- core/jni/com_android_internal_os_ZygoteInit.cpp | 37 +++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 8f87f9193c1f..8bdb000aad0e 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -173,12 +173,13 @@ public class ZygoteInit { } native private static void nativePreloadAppProcessHALs(); + native private static void nativePreloadOpenGL(); private static void preloadOpenGL() { String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) && (driverPackageName == null || driverPackageName.isEmpty())) { - EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); + nativePreloadOpenGL(); } } diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp index 258a55c7123a..ac0e60030fc5 100644 --- a/core/jni/com_android_internal_os_ZygoteInit.cpp +++ b/core/jni/com_android_internal_os_ZygoteInit.cpp @@ -16,21 +16,58 @@ #define LOG_TAG "Zygote" +#include #include #include "core_jni_helpers.h" namespace { +// Shadow call stack (SCS) is a security mitigation that uses a separate stack +// (the SCS) for return addresses. In versions of Android newer than P, the +// compiler cooperates with the system to ensure that the SCS address is always +// stored in register x18, as long as the app was compiled with a new enough +// compiler and does not use features that rely on SP-HALs (this restriction is +// because the SP-HALs might not preserve x18 due to potentially having been +// compiled with an old compiler as a consequence of Treble; it generally means +// that the app must be a system app without a UI). This struct is used to +// temporarily store the address on the stack while preloading the SP-HALs, so +// that such apps can use the same zygote as everything else. +struct ScopedSCSExit { +#ifdef __aarch64__ + void* scs; + + ScopedSCSExit() { + __asm__ __volatile__("str x18, [%0]" ::"r"(&scs)); + } + + ~ScopedSCSExit() { + __asm__ __volatile__("ldr x18, [%0]; str xzr, [%0]" ::"r"(&scs)); + } +#else + // Silence unused variable warnings in non-SCS builds. + ScopedSCSExit() {} + ~ScopedSCSExit() {} +#endif +}; + void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) { + ScopedSCSExit x; android::GraphicBufferMapper::preloadHal(); // Add preloading here for other HALs that are (a) always passthrough, and // (b) loaded by most app processes. } +void android_internal_os_ZygoteInit_nativePreloadOpenGL(JNIEnv* env, jclass) { + ScopedSCSExit x; + eglGetDisplay(EGL_DEFAULT_DISPLAY); +} + const JNINativeMethod gMethods[] = { { "nativePreloadAppProcessHALs", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs }, + { "nativePreloadOpenGL", "()V", + (void*)android_internal_os_ZygoteInit_nativePreloadOpenGL }, }; } // anonymous namespace -- cgit v1.2.3-59-g8ed1b