Use the system namespace to get the right permitted paths for loading OAT files.
The ART namespace doesn't permit e.g. /product/apps, and there may be
other locations too that need to be configurable from the system linker
config.
Test: Boot
Bug: 188078687
Bug: 130340935
Change-Id: Id23c45dec6aef8379b125d70f2a47289f34c5a3a
diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h
index bdabf5a..ac611ad 100644
--- a/libartbase/base/file_utils.h
+++ b/libartbase/base/file_utils.h
@@ -28,12 +28,12 @@
namespace art {
-static constexpr const char* kAndroidArtApexDefaultPath = "/apex/com.android.art";
-static constexpr const char* kArtApexDataDefaultPath = "/data/misc/apexdata/com.android.art";
-static constexpr const char* kAndroidConscryptApexDefaultPath = "/apex/com.android.conscrypt";
-static constexpr const char* kAndroidI18nApexDefaultPath = "/apex/com.android.i18n";
+static constexpr const char kAndroidArtApexDefaultPath[] = "/apex/com.android.art";
+static constexpr const char kArtApexDataDefaultPath[] = "/data/misc/apexdata/com.android.art";
+static constexpr const char kAndroidConscryptApexDefaultPath[] = "/apex/com.android.conscrypt";
+static constexpr const char kAndroidI18nApexDefaultPath[] = "/apex/com.android.i18n";
-static constexpr const char* kArtImageExtension = "art";
+static constexpr const char kArtImageExtension[] = "art";
// These methods return the Android Root, which is the historical location of
// the Android "system" directory, containing the built Android artifacts. On
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 95666b9..1867894 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -375,6 +375,9 @@
"thread_android.cc",
"metrics/statsd.cc",
],
+ header_libs: [
+ "libnativeloader-headers", // For dlext_namespaces.h
+ ],
shared_libs: [
"libdl_android",
"libicu",
@@ -417,7 +420,7 @@
},
},
generated_sources: [
- "art_operator_srcs"
+ "art_operator_srcs",
],
// asm_support_gen.h (used by asm_support.h) is generated with cpp-define-generator
generated_headers: ["cpp-define-generator-asm-support"],
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index d4afe0c..8a5ad63 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -31,6 +31,7 @@
// dlopen_ext support from bionic.
#ifdef ART_TARGET_ANDROID
#include "android/dlext.h"
+#include "nativeloader/dlext_namespaces.h"
#endif
#include <android-base/logging.h>
@@ -1138,6 +1139,26 @@
return success;
}
+#ifdef ART_TARGET_ANDROID
+static struct android_namespace_t* GetSystemLinkerNamespace() {
+ static struct android_namespace_t* system_ns = []() {
+ // The system namespace is called "default" for binaries in /system and
+ // "system" for those in the ART APEX. Try "system" first since "default"
+ // always exists.
+ // TODO(b/185587109): Get rid of this error prone logic.
+ struct android_namespace_t* ns = android_get_exported_namespace("system");
+ if (ns == nullptr) {
+ ns = android_get_exported_namespace("default");
+ if (ns == nullptr) {
+ LOG(FATAL) << "Failed to get system namespace for loading OAT files";
+ }
+ }
+ return ns;
+ }();
+ return system_ns;
+}
+#endif // ART_TARGET_ANDROID
+
bool DlOpenOatFile::Dlopen(const std::string& elf_filename,
/*inout*/MemMap* reservation,
/*out*/std::string* error_msg) {
@@ -1167,6 +1188,19 @@
extinfo.reserved_addr = reservation->Begin();
extinfo.reserved_size = reservation->Size();
}
+
+ if (strncmp(kAndroidArtApexDefaultPath,
+ absolute_path.get(),
+ sizeof(kAndroidArtApexDefaultPath) - 1) != 0 ||
+ absolute_path.get()[sizeof(kAndroidArtApexDefaultPath) - 1] != '/') {
+ // Use the system namespace for OAT files outside the ART APEX. Search
+ // paths and links don't matter here, but permitted paths do, and the
+ // system namespace is configured to allow loading from all appropriate
+ // locations.
+ extinfo.flags |= ANDROID_DLEXT_USE_NAMESPACE;
+ extinfo.library_namespace = GetSystemLinkerNamespace();
+ }
+
dlopen_handle_ = android_dlopen_ext(absolute_path.get(), RTLD_NOW, &extinfo);
if (reservation != nullptr && dlopen_handle_ != nullptr) {
// Find used pages from the reservation.