Loading include/nativebridge/native_bridge.h +12 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,9 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n // Use NativeBridgeLoadLibrary() instead in non-namespace scenario. void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns); // Returns vendor namespace if it is enabled for the device and null otherwise native_bridge_namespace_t* NativeBridgeGetVendorNamespace(); // Native bridge interfaces to runtime. struct NativeBridgeCallbacks { // Version number of the interface. Loading Loading @@ -348,6 +351,15 @@ struct NativeBridgeCallbacks { // Starting with v3, NativeBridge has two scenarios: with/without namespace. // Use loadLibrary instead in non-namespace scenario. void* (*loadLibraryExt)(const char* libpath, int flag, native_bridge_namespace_t* ns); // Get native bridge version of vendor namespace. // The vendor namespace is the namespace used to load vendor public libraries. // With O release this namespace can be different from the default namespace. // For the devices without enable vendor namespaces this function should return null // // Returns: // vendor namespace or null if it was not set up for the device native_bridge_namespace_t* (*getVendorNamespace)(); }; // Runtime interfaces to native bridge. Loading libnativebridge/native_bridge.cc +16 −6 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ enum NativeBridgeImplementationVersion { SIGNAL_VERSION = 2, // The version which namespace semantic is introduced. NAMESPACE_VERSION = 3, // The version with vendor namespaces VENDOR_NAMESPACE_VERSION = 4, }; // Whether we had an error at some point. Loading Loading @@ -621,6 +623,14 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n return false; } native_bridge_namespace_t* NativeBridgeGetVendorNamespace() { if (!NativeBridgeInitialized() || !isCompatibleWith(VENDOR_NAMESPACE_VERSION)) { return nullptr; } return callbacks->getVendorNamespace(); } void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) { if (NativeBridgeInitialized()) { if (isCompatibleWith(NAMESPACE_VERSION)) { Loading libnativeloader/include/nativeloader/dlext_namespaces.h +2 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,8 @@ extern bool android_link_namespaces(android_namespace_t* from, */ extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size); extern android_namespace_t* android_get_exported_namespace(const char* name); __END_DECLS #endif /* __ANDROID_DLEXT_NAMESPACES_H__ */ libnativeloader/native_loader.cpp +41 −10 Original line number Diff line number Diff line Loading @@ -83,6 +83,12 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot = static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; // The device may be configured to have the vendor libraries loaded to a separate namespace. // For historical reasons this namespace was named sphal but effectively it is intended // to use to load vendor libraries to separate namespace with controlled interface between // vendor and system namespaces. static constexpr const char* kVendorNamespaceName = "sphal"; // (http://b/27588281) This is a workaround for apps using custom classloaders and calling // System.load() with an absolute path which is outside of the classloader library search path. // This list includes all directories app is allowed to access this way. Loading Loading @@ -170,11 +176,23 @@ class LibraryNamespaces { return false; } if (!android_link_namespaces(ns, nullptr, public_libraries_.c_str())) { // Note that when vendor_ns is not configured this function will return nullptr // and it will result in linking vendor_public_libraries_ to the default namespace // which is expected behavior in this case. android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { *error_msg = dlerror(); return false; } if (!vendor_public_libraries_.empty()) { if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { *error_msg = dlerror(); return false; } } native_loader_ns = NativeLoaderNamespace(ns); } else { native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", Loading @@ -183,15 +201,25 @@ class LibraryNamespaces { namespace_type, permitted_path.c_str(), parent_ns.get_native_bridge_ns()); if (ns == nullptr) { *error_msg = NativeBridgeGetError(); return false; } if (!NativeBridgeLinkNamespaces(ns, nullptr, public_libraries_.c_str())) { native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { *error_msg = NativeBridgeGetError(); return false; } if (!vendor_public_libraries_.empty()) { if (!NativeBridgeLinkNamespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { *error_msg = NativeBridgeGetError(); return false; } } native_loader_ns = NativeLoaderNamespace(ns); } Loading Loading @@ -249,9 +277,6 @@ class LibraryNamespaces { } } // 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. // Loading @@ -266,7 +291,13 @@ class LibraryNamespaces { soname.c_str(), dlerror()); } public_libraries_ = base::Join(sonames, ':'); system_public_libraries_ = base::Join(sonames, ':'); sonames.clear(); // This file is optional, quietly ignore if the file does not exist. ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); vendor_public_libraries_ = base::Join(sonames, ':'); } void Reset() { Loading Loading @@ -325,7 +356,7 @@ class LibraryNamespaces { // code is one example) unknown to linker in which case linker uses anonymous // namespace. The second argument specifies the search path for the anonymous // namespace which is the library_path of the classloader. initialized_ = android_init_anonymous_namespace(public_libraries_.c_str(), initialized_ = android_init_anonymous_namespace(system_public_libraries_.c_str(), is_native_bridge ? nullptr : library_path); if (!initialized_) { *error_msg = dlerror(); Loading @@ -334,7 +365,7 @@ class LibraryNamespaces { // and now initialize native bridge namespaces if necessary. if (NativeBridgeInitialized()) { initialized_ = NativeBridgeInitAnonymousNamespace(public_libraries_.c_str(), initialized_ = NativeBridgeInitAnonymousNamespace(system_public_libraries_.c_str(), is_native_bridge ? library_path : nullptr); if (!initialized_) { *error_msg = NativeBridgeGetError(); Loading Loading @@ -371,8 +402,8 @@ class LibraryNamespaces { bool initialized_; std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_; std::string public_libraries_; std::string system_public_libraries_; std::string vendor_public_libraries_; DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; Loading Loading
include/nativebridge/native_bridge.h +12 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,9 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n // Use NativeBridgeLoadLibrary() instead in non-namespace scenario. void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns); // Returns vendor namespace if it is enabled for the device and null otherwise native_bridge_namespace_t* NativeBridgeGetVendorNamespace(); // Native bridge interfaces to runtime. struct NativeBridgeCallbacks { // Version number of the interface. Loading Loading @@ -348,6 +351,15 @@ struct NativeBridgeCallbacks { // Starting with v3, NativeBridge has two scenarios: with/without namespace. // Use loadLibrary instead in non-namespace scenario. void* (*loadLibraryExt)(const char* libpath, int flag, native_bridge_namespace_t* ns); // Get native bridge version of vendor namespace. // The vendor namespace is the namespace used to load vendor public libraries. // With O release this namespace can be different from the default namespace. // For the devices without enable vendor namespaces this function should return null // // Returns: // vendor namespace or null if it was not set up for the device native_bridge_namespace_t* (*getVendorNamespace)(); }; // Runtime interfaces to native bridge. Loading
libnativebridge/native_bridge.cc +16 −6 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ enum NativeBridgeImplementationVersion { SIGNAL_VERSION = 2, // The version which namespace semantic is introduced. NAMESPACE_VERSION = 3, // The version with vendor namespaces VENDOR_NAMESPACE_VERSION = 4, }; // Whether we had an error at some point. Loading Loading @@ -621,6 +623,14 @@ bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_n return false; } native_bridge_namespace_t* NativeBridgeGetVendorNamespace() { if (!NativeBridgeInitialized() || !isCompatibleWith(VENDOR_NAMESPACE_VERSION)) { return nullptr; } return callbacks->getVendorNamespace(); } void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) { if (NativeBridgeInitialized()) { if (isCompatibleWith(NAMESPACE_VERSION)) { Loading
libnativeloader/include/nativeloader/dlext_namespaces.h +2 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,8 @@ extern bool android_link_namespaces(android_namespace_t* from, */ extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size); extern android_namespace_t* android_get_exported_namespace(const char* name); __END_DECLS #endif /* __ANDROID_DLEXT_NAMESPACES_H__ */
libnativeloader/native_loader.cpp +41 −10 Original line number Diff line number Diff line Loading @@ -83,6 +83,12 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot = static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; // The device may be configured to have the vendor libraries loaded to a separate namespace. // For historical reasons this namespace was named sphal but effectively it is intended // to use to load vendor libraries to separate namespace with controlled interface between // vendor and system namespaces. static constexpr const char* kVendorNamespaceName = "sphal"; // (http://b/27588281) This is a workaround for apps using custom classloaders and calling // System.load() with an absolute path which is outside of the classloader library search path. // This list includes all directories app is allowed to access this way. Loading Loading @@ -170,11 +176,23 @@ class LibraryNamespaces { return false; } if (!android_link_namespaces(ns, nullptr, public_libraries_.c_str())) { // Note that when vendor_ns is not configured this function will return nullptr // and it will result in linking vendor_public_libraries_ to the default namespace // which is expected behavior in this case. android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { *error_msg = dlerror(); return false; } if (!vendor_public_libraries_.empty()) { if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { *error_msg = dlerror(); return false; } } native_loader_ns = NativeLoaderNamespace(ns); } else { native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", Loading @@ -183,15 +201,25 @@ class LibraryNamespaces { namespace_type, permitted_path.c_str(), parent_ns.get_native_bridge_ns()); if (ns == nullptr) { *error_msg = NativeBridgeGetError(); return false; } if (!NativeBridgeLinkNamespaces(ns, nullptr, public_libraries_.c_str())) { native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { *error_msg = NativeBridgeGetError(); return false; } if (!vendor_public_libraries_.empty()) { if (!NativeBridgeLinkNamespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { *error_msg = NativeBridgeGetError(); return false; } } native_loader_ns = NativeLoaderNamespace(ns); } Loading Loading @@ -249,9 +277,6 @@ class LibraryNamespaces { } } // 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. // Loading @@ -266,7 +291,13 @@ class LibraryNamespaces { soname.c_str(), dlerror()); } public_libraries_ = base::Join(sonames, ':'); system_public_libraries_ = base::Join(sonames, ':'); sonames.clear(); // This file is optional, quietly ignore if the file does not exist. ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); vendor_public_libraries_ = base::Join(sonames, ':'); } void Reset() { Loading Loading @@ -325,7 +356,7 @@ class LibraryNamespaces { // code is one example) unknown to linker in which case linker uses anonymous // namespace. The second argument specifies the search path for the anonymous // namespace which is the library_path of the classloader. initialized_ = android_init_anonymous_namespace(public_libraries_.c_str(), initialized_ = android_init_anonymous_namespace(system_public_libraries_.c_str(), is_native_bridge ? nullptr : library_path); if (!initialized_) { *error_msg = dlerror(); Loading @@ -334,7 +365,7 @@ class LibraryNamespaces { // and now initialize native bridge namespaces if necessary. if (NativeBridgeInitialized()) { initialized_ = NativeBridgeInitAnonymousNamespace(public_libraries_.c_str(), initialized_ = NativeBridgeInitAnonymousNamespace(system_public_libraries_.c_str(), is_native_bridge ? library_path : nullptr); if (!initialized_) { *error_msg = NativeBridgeGetError(); Loading Loading @@ -371,8 +402,8 @@ class LibraryNamespaces { bool initialized_; std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_; std::string public_libraries_; std::string system_public_libraries_; std::string vendor_public_libraries_; DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; Loading