Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f653eaa3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Load vendor public libraries to sphal namespace"

parents f9259b59 882cad2d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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.
+16 −6
Original line number Diff line number Diff line
@@ -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.
@@ -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)) {
+2 −0
Original line number Diff line number Diff line
@@ -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__ */
+41 −10
Original line number Diff line number Diff line
@@ -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.
@@ -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",
@@ -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);
    }
@@ -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.
    //
@@ -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() {
@@ -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();
@@ -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();
@@ -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);
};