Load GL graphics drivers explicitly from sphal namespace
In Treble term, GL wrappers (libEGL.so, libGLES*.so, ...) are called
SP-NDK and actual drivers (libEGL_*.so, libGLESv2_*.so, ...)
are called SP-HALs. (SP = Same-Process).
SP-HALs are developed by vendors and thus they can use only a subset of
framework libraries that we call vndk-stable and subset of NDK
libraries. It consists of libc, libm, liblog, libz, libnativewindow,
libc++, ..., but not framework-only libraries such as libui, libandroid,
etc.
In order to enforce such restriction at run-time, we will use the linker
namespace. Specifically, we create a new namespace named 'sphal' and
configure it so that...
1) it can only search and load libraries from /vendor/lib,
2) it redirects the load/link request to the default namespace when the
allowed list of libraries are requested from the caller, and
3) it rejects to search/load any library other than 1) and 2).
The problem here is, GL wrapper need to tell the linker to load the
drivers from the separate namespace (the 'sphal' namespace other than
the default namespace. To specify the namespace, we need to use
android_dlopen_ext() instead of dlopen().`
Bug: 34407260
Bug: 37049319
Test: none, no op for now since we haven't create sphal namespace.
Change-Id: I376dd9e5cc904452f669c27eb85c59b30b43dc39
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 683e6ca..7d20ba1 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -33,6 +33,10 @@
#include "egl_trace.h"
#include "egldefs.h"
+extern "C" {
+ android_namespace_t* android_get_exported_namespace(const char*);
+}
+
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@@ -106,6 +110,11 @@
return dlopen(path, mode);
}
+static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
+ ATRACE_CALL();
+ return android_dlopen_ext(path, mode, info);
+}
+
// ----------------------------------------------------------------------------
Loader::driver_t::driver_t(void* gles)
@@ -414,6 +423,27 @@
}
const char* const driver_absolute_path = absolutePath.c_str();
+ // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
+ // the original routine when the namespace does not exist or the load from
+ // the namespace fails.
+ // See /system/core/rootdir/etc/ld.config.txt for the configuration of the
+ // sphal namespace.
+ android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
+ if (sphal_namespace != NULL) {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = sphal_namespace,
+ };
+ void* dso = do_android_dlopen_ext(driver_absolute_path, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ if (dso) {
+ ALOGD("loaded %s from sphal namespace", driver_absolute_path);
+ return dso;
+ }
+ else {
+ ALOGW("failed to load %s from sphal namespace: %s", driver_absolute_path, dlerror());
+ }
+ }
+
void* dso = do_dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
@@ -426,11 +456,6 @@
return dso;
}
-static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
- ATRACE_CALL();
- return android_dlopen_ext(path, mode, info);
-}
-
static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
"ro.hardware.egl",
"ro.board.platform",