Merge "Preserve x18 while preloading SP-HALs in the zygote."
am: 23fd045842
Change-Id: Ief47ab35d80e4020c6a7c6461d958a699749cc58
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,21 +16,58 @@
|
||||
|
||||
#define LOG_TAG "Zygote"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <ui/GraphicBufferMapper.h>
|
||||
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user