From 617f495cf7a8e07b433058fb7f4c7611b584fda9 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 6 Apr 2016 18:24:08 -0700 Subject: [PATCH] Allow vendors to extend the list of public libs native_loader adds libraries specified in the (optional) file: /vendor/etc/public.libraries.txt to the list of public native libraries. Bug: http://b/27073931 Change-Id: I927193cce99d48c3395bd0e6c373ae9fad0f13f4 --- libnativeloader/native_loader.cpp | 47 +++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 899c98c55..f0360dbe1 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -36,7 +36,8 @@ namespace android { #if defined(__ANDROID__) -static constexpr const char* kPublicNativeLibrariesConfig = "/system/etc/public.libraries.txt"; +static constexpr const char* kPublicNativeLibrariesSystemConfig = "/system/etc/public.libraries.txt"; +static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; class LibraryNamespaces { public: @@ -93,35 +94,51 @@ class LibraryNamespaces { } void Initialize() { + std::vector sonames; + + LOG_ALWAYS_FATAL_IF(!ReadConfig(kPublicNativeLibrariesSystemConfig, &sonames), + "Error reading public native library list from \"%s\": %s", + kPublicNativeLibrariesSystemConfig, strerror(errno)); + // This file is optional, quietly ignore if the file does not exist. + ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); + + // android_init_namespaces() expects all the public libraries + // to be loaded so that they can be found by soname alone. + // + // TODO(dimitry): this is a bit misleading since we do not know + // if the vendor public library is going to be opened from /vendor/lib + // we might as well end up loading them from /system/lib + // For now we rely on CTS test to catch things like this but + // it should probably be addressed in the future. + for (const auto& soname : sonames) { + dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE); + } + + public_libraries_ = base::Join(sonames, ':'); + } + + private: + bool ReadConfig(const std::string& configFile, std::vector* sonames) { // Read list of public native libraries from the config file. std::string file_content; - LOG_ALWAYS_FATAL_IF(!base::ReadFileToString(kPublicNativeLibrariesConfig, &file_content), - "Error reading public native library list from \"%s\": %s", - kPublicNativeLibrariesConfig, strerror(errno)); + if(!base::ReadFileToString(configFile, &file_content)) { + return false; + } std::vector lines = base::Split(file_content, "\n"); - std::vector sonames; - for (const auto& line : lines) { auto trimmed_line = base::Trim(line); if (trimmed_line[0] == '#' || trimmed_line.empty()) { continue; } - sonames.push_back(trimmed_line); + sonames->push_back(trimmed_line); } - public_libraries_ = base::Join(sonames, ':'); - - // android_init_namespaces() expects all the public libraries - // to be loaded so that they can be found by soname alone. - for (const auto& soname : sonames) { - dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE); - } + return true; } - private: bool InitPublicNamespace(const char* library_path) { // (http://b/25844435) - Some apps call dlopen from generated code (mono jited // code is one example) unknown to linker in which case linker uses anonymous