Merge "Add product apk support from libnativeloader" am: 23d774105e
am: 5ddcafbb52
Change-Id: Ida1555d0818c5d8e2a3cf22b5f6f787587216b9d
This commit is contained in:
commit
df3995d6a7
3 changed files with 84 additions and 43 deletions
|
|
@ -36,14 +36,9 @@ extern "C" {
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
void InitializeNativeLoader();
|
void InitializeNativeLoader();
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default"))) jstring CreateClassLoaderNamespace(
|
||||||
jstring CreateClassLoaderNamespace(JNIEnv* env,
|
JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, jstring dex_path,
|
||||||
int32_t target_sdk_version,
|
jstring library_path, jstring permitted_path);
|
||||||
jobject class_loader,
|
|
||||||
bool is_shared,
|
|
||||||
bool is_for_vendor,
|
|
||||||
jstring library_path,
|
|
||||||
jstring permitted_path);
|
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void* OpenNativeLibrary(
|
__attribute__((visibility("default"))) void* OpenNativeLibrary(
|
||||||
JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader,
|
JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -140,10 +141,24 @@ static constexpr const char* kApexPath = "/apex/";
|
||||||
|
|
||||||
#if defined(__LP64__)
|
#if defined(__LP64__)
|
||||||
static constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/lib64";
|
static constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/lib64";
|
||||||
|
static constexpr const char* kVendorLibPath = "/vendor/lib64";
|
||||||
|
static constexpr const char* kProductLibPath = "/product/lib64:/system/product/lib64";
|
||||||
#else
|
#else
|
||||||
static constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/lib";
|
static constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/lib";
|
||||||
|
static constexpr const char* kVendorLibPath = "/vendor/lib";
|
||||||
|
static constexpr const char* kProductLibPath = "/product/lib:/system/product/lib";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const std::regex kVendorDexPathRegex("(^|:)/vendor/");
|
||||||
|
static const std::regex kProductDexPathRegex("(^|:)(/system)?/product/");
|
||||||
|
|
||||||
|
// Define origin of APK if it is from vendor partition or product partition
|
||||||
|
typedef enum {
|
||||||
|
APK_ORIGIN_DEFAULT = 0,
|
||||||
|
APK_ORIGIN_VENDOR = 1,
|
||||||
|
APK_ORIGIN_PRODUCT = 2,
|
||||||
|
} ApkOrigin;
|
||||||
|
|
||||||
static bool is_debuggable() {
|
static bool is_debuggable() {
|
||||||
bool debuggable = false;
|
bool debuggable = false;
|
||||||
#ifdef __BIONIC__
|
#ifdef __BIONIC__
|
||||||
|
|
@ -179,7 +194,7 @@ class LibraryNamespaces {
|
||||||
LibraryNamespaces() : initialized_(false) { }
|
LibraryNamespaces() : initialized_(false) { }
|
||||||
|
|
||||||
NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader,
|
NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader,
|
||||||
bool is_shared, bool is_for_vendor, jstring java_library_path,
|
bool is_shared, jstring dex_path, jstring java_library_path,
|
||||||
jstring java_permitted_path, std::string* error_msg) {
|
jstring java_permitted_path, std::string* error_msg) {
|
||||||
std::string library_path; // empty string by default.
|
std::string library_path; // empty string by default.
|
||||||
|
|
||||||
|
|
@ -188,6 +203,8 @@ class LibraryNamespaces {
|
||||||
library_path = library_path_utf_chars.c_str();
|
library_path = library_path_utf_chars.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApkOrigin apk_origin = GetApkOriginFromDexPath(env, dex_path);
|
||||||
|
|
||||||
// (http://b/27588281) This is a workaround for apps using custom
|
// (http://b/27588281) This is a workaround for apps using custom
|
||||||
// classloaders and calling System.load() with an absolute path which
|
// classloaders and calling System.load() with an absolute path which
|
||||||
// is outside of the classloader library search path.
|
// is outside of the classloader library search path.
|
||||||
|
|
@ -234,31 +251,50 @@ class LibraryNamespaces {
|
||||||
std::string system_exposed_libraries = system_public_libraries_;
|
std::string system_exposed_libraries = system_public_libraries_;
|
||||||
const char* namespace_name = kClassloaderNamespaceName;
|
const char* namespace_name = kClassloaderNamespaceName;
|
||||||
android_namespace_t* vndk_ns = nullptr;
|
android_namespace_t* vndk_ns = nullptr;
|
||||||
if (is_for_vendor && !is_shared) {
|
if ((apk_origin == APK_ORIGIN_VENDOR ||
|
||||||
LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
|
(apk_origin == APK_ORIGIN_PRODUCT && target_sdk_version > 29)) &&
|
||||||
|
!is_shared) {
|
||||||
|
LOG_FATAL_IF(is_native_bridge,
|
||||||
|
"Unbundled vendor / product apk must not use translated architecture");
|
||||||
|
|
||||||
// For vendor apks, give access to the vendor lib even though
|
// For vendor / product apks, give access to the vendor / product lib even though
|
||||||
// they are treated as unbundled; the libs and apks are still bundled
|
// they are treated as unbundled; the libs and apks are still bundled
|
||||||
// together in the vendor partition.
|
// together in the vendor / product partition.
|
||||||
#if defined(__LP64__)
|
const char* origin_partition;
|
||||||
std::string vendor_lib_path = "/vendor/lib64";
|
const char* origin_lib_path;
|
||||||
#else
|
|
||||||
std::string vendor_lib_path = "/vendor/lib";
|
switch (apk_origin) {
|
||||||
#endif
|
case APK_ORIGIN_VENDOR:
|
||||||
library_path = library_path + ":" + vendor_lib_path.c_str();
|
origin_partition = "vendor";
|
||||||
permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
|
origin_lib_path = kVendorLibPath;
|
||||||
|
break;
|
||||||
|
case APK_ORIGIN_PRODUCT:
|
||||||
|
origin_partition = "product";
|
||||||
|
origin_lib_path = kProductLibPath;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
origin_partition = "unknown";
|
||||||
|
origin_lib_path = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_FATAL_IF(is_native_bridge, "Unbundled %s apk must not use translated architecture",
|
||||||
|
origin_partition);
|
||||||
|
|
||||||
|
library_path = library_path + ":" + origin_lib_path;
|
||||||
|
permitted_path = permitted_path + ":" + origin_lib_path;
|
||||||
|
|
||||||
// Also give access to LLNDK libraries since they are available to vendors
|
// Also give access to LLNDK libraries since they are available to vendors
|
||||||
system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
|
system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
|
||||||
|
|
||||||
// Give access to VNDK-SP libraries from the 'vndk' namespace.
|
// Give access to VNDK-SP libraries from the 'vndk' namespace.
|
||||||
vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
|
vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
|
||||||
LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
|
LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, "Cannot find \"%s\" namespace for %s apks",
|
||||||
"Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
|
kVndkNamespaceName, origin_partition);
|
||||||
|
|
||||||
// Different name is useful for debugging
|
// Different name is useful for debugging
|
||||||
namespace_name = kVendorClassloaderNamespaceName;
|
namespace_name = kVendorClassloaderNamespaceName;
|
||||||
ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
|
ALOGD("classloader namespace configured for unbundled %s apk. library_path=%s",
|
||||||
|
origin_partition, library_path.c_str());
|
||||||
} else {
|
} else {
|
||||||
// oem and product public libraries are NOT available to vendor apks, otherwise it
|
// oem and product public libraries are NOT available to vendor apks, otherwise it
|
||||||
// would be system->vendor violation.
|
// would be system->vendor violation.
|
||||||
|
|
@ -660,6 +696,28 @@ class LibraryNamespaces {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApkOrigin GetApkOriginFromDexPath(JNIEnv* env, jstring dex_path) {
|
||||||
|
ApkOrigin apk_origin = APK_ORIGIN_DEFAULT;
|
||||||
|
|
||||||
|
if (dex_path != nullptr) {
|
||||||
|
ScopedUtfChars dex_path_utf_chars(env, dex_path);
|
||||||
|
|
||||||
|
if (std::regex_search(dex_path_utf_chars.c_str(), kVendorDexPathRegex)) {
|
||||||
|
apk_origin = APK_ORIGIN_VENDOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::regex_search(dex_path_utf_chars.c_str(), kProductDexPathRegex)) {
|
||||||
|
LOG_ALWAYS_FATAL_IF(apk_origin == APK_ORIGIN_VENDOR,
|
||||||
|
"Dex path contains both vendor and product partition : %s",
|
||||||
|
dex_path_utf_chars.c_str());
|
||||||
|
|
||||||
|
apk_origin = APK_ORIGIN_PRODUCT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apk_origin;
|
||||||
|
}
|
||||||
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
std::list<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
|
std::list<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
|
||||||
std::string system_public_libraries_;
|
std::string system_public_libraries_;
|
||||||
|
|
@ -690,31 +748,20 @@ void ResetNativeLoader() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring CreateClassLoaderNamespace(JNIEnv* env,
|
jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader,
|
||||||
int32_t target_sdk_version,
|
bool is_shared, jstring dex_path, jstring library_path,
|
||||||
jobject class_loader,
|
|
||||||
bool is_shared,
|
|
||||||
bool is_for_vendor,
|
|
||||||
jstring library_path,
|
|
||||||
jstring permitted_path) {
|
jstring permitted_path) {
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
|
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
|
||||||
|
|
||||||
std::string error_msg;
|
std::string error_msg;
|
||||||
bool success = g_namespaces->Create(env,
|
bool success = g_namespaces->Create(env, target_sdk_version, class_loader, is_shared, dex_path,
|
||||||
target_sdk_version,
|
library_path, permitted_path, &error_msg) != nullptr;
|
||||||
class_loader,
|
|
||||||
is_shared,
|
|
||||||
is_for_vendor,
|
|
||||||
library_path,
|
|
||||||
permitted_path,
|
|
||||||
&error_msg) != nullptr;
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return env->NewStringUTF(error_msg.c_str());
|
return env->NewStringUTF(error_msg.c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
|
UNUSED(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path);
|
||||||
library_path, permitted_path);
|
|
||||||
#endif
|
#endif
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -779,8 +826,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat
|
||||||
// In this case we create an isolated not-shared namespace for it.
|
// In this case we create an isolated not-shared namespace for it.
|
||||||
std::string create_error_msg;
|
std::string create_error_msg;
|
||||||
if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */,
|
if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */,
|
||||||
false /* is_for_vendor */, library_path, nullptr,
|
nullptr, library_path, nullptr, &create_error_msg)) == nullptr) {
|
||||||
&create_error_msg)) == nullptr) {
|
|
||||||
*error_msg = strdup(create_error_msg.c_str());
|
*error_msg = strdup(create_error_msg.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@ void InitializeNativeLoader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader,
|
jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader,
|
||||||
bool is_shared, bool is_for_vendor, jstring library_path,
|
bool is_shared, jstring dex_path, jstring library_path,
|
||||||
jstring permitted_path) {
|
jstring permitted_path) {
|
||||||
static auto f = GET_FUNC_PTR(CreateClassLoaderNamespace);
|
static auto f = GET_FUNC_PTR(CreateClassLoaderNamespace);
|
||||||
return f(env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path,
|
return f(env, target_sdk_version, class_loader, is_shared, dex_path, library_path,
|
||||||
permitted_path);
|
permitted_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue