summaryrefslogtreecommitdiff
path: root/libs/graphicsenv/GraphicsEnv.cpp
diff options
context:
space:
mode:
author Yiwei Zhang <zzyiwei@google.com> 2018-11-27 19:58:29 -0800
committer Yiwei Zhang <zzyiwei@google.com> 2018-11-28 20:59:58 -0800
commit64d89214fceecc3f7765052dece33aa1f1a1527f (patch)
treea3203f47db6612efd922c883a0838b6ded5603f2 /libs/graphicsenv/GraphicsEnv.cpp
parent910c0aa1384ee3122a4d3929ca3b94943a3dc539 (diff)
Updatable Driver: Decouple gfx_driver from sphal
This change manually constructs updatable graphics driver namespace without inheriting from sphal namespace. Manually link against default namespace to access llndk libraries and link against vndk namespace to access vndksp libraries. Then the newly created namespace will not have access to libraries under /vendor/lib[64]/. Bug: 120106759 Test: Manual. Install updatable driver apk with/without some missing libraries to verify the namespace isolation working as intended. Change-Id: I6225bb018028bbb72f77b288c3b5bf60a5b86422
Diffstat (limited to 'libs/graphicsenv/GraphicsEnv.cpp')
-rw-r--r--libs/graphicsenv/GraphicsEnv.cpp140
1 files changed, 114 insertions, 26 deletions
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index afa32b6d63..c2a6764338 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -18,32 +18,99 @@
#define LOG_TAG "GraphicsEnv"
#include <graphicsenv/GraphicsEnv.h>
-#include <sys/prctl.h>
-
-#include <mutex>
+#include <dlfcn.h>
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>
+#include <sys/prctl.h>
+
+#include <mutex>
// TODO(b/37049319) Get this from a header once one exists
extern "C" {
- android_namespace_t* android_get_exported_namespace(const char*);
- android_namespace_t* android_create_namespace(const char* name,
- const char* ld_library_path,
- const char* default_library_path,
- uint64_t type,
- const char* permitted_when_isolated_path,
- android_namespace_t* parent);
+android_namespace_t* android_get_exported_namespace(const char*);
+android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path,
+ const char* default_library_path, uint64_t type,
+ const char* permitted_when_isolated_path,
+ android_namespace_t* parent);
+bool android_link_namespaces(android_namespace_t* from, android_namespace_t* to,
+ const char* shared_libs_sonames);
- enum {
- ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
- ANDROID_NAMESPACE_TYPE_SHARED = 2,
- };
+enum {
+ ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
+ ANDROID_NAMESPACE_TYPE_SHARED = 2,
+};
}
namespace android {
+enum NativeLibrary {
+ LLNDK = 0,
+ VNDKSP = 1,
+};
+
+static constexpr const char* kNativeLibrariesSystemConfigPath[] = {"/etc/llndk.libraries.txt",
+ "/etc/vndksp.libraries.txt"};
+
+static std::string vndkVersionStr() {
+#ifdef __BIONIC__
+ std::string version = android::base::GetProperty("ro.vndk.version", "");
+ if (version != "" && version != "current") {
+ return "." + version;
+ }
+#endif
+ return "";
+}
+
+static void insertVndkVersionStr(std::string* fileName) {
+ LOG_ALWAYS_FATAL_IF(!fileName, "fileName should never be nullptr");
+ size_t insertPos = fileName->find_last_of(".");
+ if (insertPos == std::string::npos) {
+ insertPos = fileName->length();
+ }
+ fileName->insert(insertPos, vndkVersionStr());
+}
+
+static bool readConfig(const std::string& configFile, std::vector<std::string>* soNames) {
+ // Read list of public native libraries from the config file.
+ std::string fileContent;
+ if (!base::ReadFileToString(configFile, &fileContent)) {
+ return false;
+ }
+
+ std::vector<std::string> lines = base::Split(fileContent, "\n");
+
+ for (auto& line : lines) {
+ auto trimmedLine = base::Trim(line);
+ if (!trimmedLine.empty()) {
+ soNames->push_back(trimmedLine);
+ }
+ }
+
+ return true;
+}
+
+static const std::string getSystemNativeLibraries(NativeLibrary type) {
+ static const char* androidRootEnv = getenv("ANDROID_ROOT");
+ static const std::string rootDir = androidRootEnv != nullptr ? androidRootEnv : "/system";
+
+ std::string nativeLibrariesSystemConfig = rootDir + kNativeLibrariesSystemConfigPath[type];
+
+ insertVndkVersionStr(&nativeLibrariesSystemConfig);
+
+ std::vector<std::string> soNames;
+ if (!readConfig(nativeLibrariesSystemConfig, &soNames)) {
+ ALOGE("Failed to retrieve library names from %s", nativeLibrariesSystemConfig.c_str());
+ return "";
+ }
+
+ return base::Join(soNames, ':');
+}
+
/*static*/ GraphicsEnv& GraphicsEnv::getInstance() {
static GraphicsEnv env;
return env;
@@ -59,8 +126,8 @@ int GraphicsEnv::getCanLoadSystemLibraries() {
void GraphicsEnv::setDriverPath(const std::string path) {
if (!mDriverPath.empty()) {
- ALOGV("ignoring attempt to change driver path from '%s' to '%s'",
- mDriverPath.c_str(), path.c_str());
+ ALOGV("ignoring attempt to change driver path from '%s' to '%s'", mDriverPath.c_str(),
+ path.c_str());
return;
}
ALOGV("setting driver path to '%s'", path.c_str());
@@ -102,7 +169,7 @@ void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std::
mAppNamespace = appNamespace;
} else {
ALOGV("Vulkan layer search path already set, not clobbering with '%s' for namespace %p'",
- layerPaths.c_str(), appNamespace);
+ layerPaths.c_str(), appNamespace);
}
}
@@ -154,20 +221,41 @@ void GraphicsEnv::setDebugLayersGLES(const std::string layers) {
android_namespace_t* GraphicsEnv::getDriverNamespace() {
static std::once_flag once;
std::call_once(once, [this]() {
- if (mDriverPath.empty())
- return;
- // If the sphal namespace isn't configured for a device, don't support updatable drivers.
- // We need a parent namespace to inherit the default search path from.
- auto sphalNamespace = android_get_exported_namespace("sphal");
- if (!sphalNamespace) return;
+ if (mDriverPath.empty()) return;
+
+ auto vndkNamespace = android_get_exported_namespace("vndk");
+ if (!vndkNamespace) return;
+
mDriverNamespace = android_create_namespace("gfx driver",
mDriverPath.c_str(), // ld_library_path
mDriverPath.c_str(), // default_library_path
- ANDROID_NAMESPACE_TYPE_SHARED |
- ANDROID_NAMESPACE_TYPE_ISOLATED,
+ ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr, // permitted_when_isolated_path
- sphalNamespace);
+ nullptr);
+
+ const std::string llndkLibraries = getSystemNativeLibraries(NativeLibrary::LLNDK);
+ if (llndkLibraries.empty()) {
+ mDriverNamespace = nullptr;
+ return;
+ }
+ if (!android_link_namespaces(mDriverNamespace, nullptr, llndkLibraries.c_str())) {
+ ALOGE("Failed to link default namespace[%s]", dlerror());
+ mDriverNamespace = nullptr;
+ return;
+ }
+
+ const std::string vndkspLibraries = getSystemNativeLibraries(NativeLibrary::VNDKSP);
+ if (vndkspLibraries.empty()) {
+ mDriverNamespace = nullptr;
+ return;
+ }
+ if (!android_link_namespaces(mDriverNamespace, vndkNamespace, vndkspLibraries.c_str())) {
+ ALOGE("Failed to link vndk namespace[%s]", dlerror());
+ mDriverNamespace = nullptr;
+ return;
+ }
});
+
return mDriverNamespace;
}