summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 09:37:14 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-12-15 09:37:14 +0000
commit945237a9606b24d0efec5f1aff28292ff04599be (patch)
treeed79e3f89e5cdf5059216a85b0bfdfee343ef60a
parent49c303187bd85a6a5135d15bdf1421a4c540877a (diff)
parenta588cc1e19f4f6992bf2dc6ce50825d1f1d48b52 (diff)
downloadapex-aml_tz5_341510010.tar.gz
Snap for 11224086 from a588cc1e19f4f6992bf2dc6ce50825d1f1d48b52 to mainline-tzdata5-releaseaml_tz5_341510070aml_tz5_341510050aml_tz5_341510010aml_tz5_341510010
Change-Id: Ie8693623923663a6c94c3a3b5ee7cb7a525ab67f
-rw-r--r--tests/native/Android.bp3
-rw-r--r--tests/native/apex_shared_libraries_test.cpp79
2 files changed, 66 insertions, 16 deletions
diff --git a/tests/native/Android.bp b/tests/native/Android.bp
index 79152223..879c8853 100644
--- a/tests/native/Android.bp
+++ b/tests/native/Android.bp
@@ -34,11 +34,12 @@ cc_test {
},
shared_libs: [
- "libbase",
"liblog",
+ "libdl_android",
],
static_libs: [
+ "libbase",
"libc++fs",
"libfs_mgr",
],
diff --git a/tests/native/apex_shared_libraries_test.cpp b/tests/native/apex_shared_libraries_test.cpp
index 9f536dc6..e68e5c92 100644
--- a/tests/native/apex_shared_libraries_test.cpp
+++ b/tests/native/apex_shared_libraries_test.cpp
@@ -19,6 +19,7 @@
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/strings.h>
+#include <android/dlext.h>
#include <dlfcn.h>
#include <fstab/fstab.h>
#include <gtest/gtest.h>
@@ -26,6 +27,7 @@
#include <filesystem>
#include <fstream>
+#include <regex>
#include <string>
using android::base::GetBoolProperty;
@@ -36,8 +38,23 @@ using android::fs_mgr::ReadFstabFromFile;
namespace fs = std::filesystem;
-static constexpr const char* kApexRoot = "/apex";
-static constexpr const char* kApexSharedLibsRoot = "/apex/sharedlibs";
+// No header available for these symbols
+extern "C" struct android_namespace_t* android_get_exported_namespace(
+ const char* name);
+
+extern "C" struct android_namespace_t* android_create_namespace(
+ const char* name, const char* ld_library_path,
+ const char* default_library_path, uint64_t type,
+ const char* permitted_when_isolated_path,
+ struct android_namespace_t* parent);
+
+#if !defined(__LP64__)
+static constexpr const char LIB[] = "lib";
+#else // !__LP64__
+static constexpr const char LIB[] = "lib64";
+#endif // !__LP64_
+
+static constexpr const char kApexSharedLibsRoot[] = "/apex/sharedlibs";
TEST(apex_shared_libraries, symlink_libraries_loadable) {
if (!GetBoolProperty("ro.apex.updatable", false)) {
@@ -47,31 +64,32 @@ TEST(apex_shared_libraries, symlink_libraries_loadable) {
Fstab fstab;
ASSERT_TRUE(ReadFstabFromFile("/proc/mounts", &fstab));
+ // Regex to use when checking if a mount is for an active APEX or not. Note
+ // that non-active APEX mounts don't have the @<number> marker.
+ std::regex active_apex_pattern(R"(/apex/(.*)@\d+)");
+
// Traverse mount points to identify apexs.
for (auto& entry : fstab) {
- if (fs::path(entry.mount_point).parent_path() != kApexRoot) {
- continue;
- }
-
- // Focus on "active" apexs.
- if (entry.mount_point.find('@') != std::string::npos) {
+ std::cmatch m;
+ if (!std::regex_match(entry.mount_point.c_str(), m, active_apex_pattern)) {
continue;
}
- std::string dev_file = fs::path(entry.blk_device).filename();
+ // Linker namespace name of the apex com.android.foo is com_android_foo.
+ std::string apex_namespace_name = m[1];
+ std::replace(apex_namespace_name.begin(), apex_namespace_name.end(), '.',
+ '_');
// Filter out any mount irrelevant (e.g. tmpfs)
+ std::string dev_file = fs::path(entry.blk_device).filename();
if (!StartsWith(dev_file, "loop") && !StartsWith(dev_file, "dm-")) {
continue;
}
-#if !defined(__LP64__)
- auto lib = fs::path(entry.mount_point) / "lib";
-#else // !__LP64__
- auto lib = fs::path(entry.mount_point) / "lib64";
-#endif // !__LP64__
+ auto lib = fs::path(entry.mount_point) / LIB;
if (!fs::is_directory(lib)) {
continue;
}
+
for (auto& p : fs::directory_iterator(lib)) {
std::error_code ec;
if (!fs::is_symlink(p, ec)) {
@@ -95,7 +113,38 @@ TEST(apex_shared_libraries, symlink_libraries_loadable) {
// Library loading validity check.
dlerror(); // Clear any pending errors.
- void* handle = dlopen(p.path().c_str(), RTLD_NOW);
+ android_namespace_t* ns =
+ android_get_exported_namespace(apex_namespace_name.c_str());
+ if (ns == nullptr) {
+ // In case the apex namespace doesn't exist (actually not accessible),
+ // create a new one that can search libraries from the apex directory
+ // and can load (but not search) from the shared lib APEX.
+ std::string search_paths = lib;
+ search_paths.push_back(':');
+ // Adding "/system/lib[64]" is not ideal; we need to link to the
+ // namespace that is capable of loading libs from the directory.
+ // However, since the namespace (the `system` namespace) is not
+ // exported, we can't make a link. Instead, we allow this new namespace
+ // to search/load libraries from the directory.
+ search_paths.append(std::string("/system/") + LIB);
+ std::string permitted_paths = "/apex";
+ ns = android_create_namespace(
+ apex_namespace_name.c_str(),
+ /* ld_library_path=*/nullptr,
+ /* default_library_path=*/search_paths.c_str(),
+ /* type=*/3, // ISOLATED and SHARED
+ /* permitted_when_isolated_path=*/permitted_paths.c_str(),
+ /* parent=*/nullptr);
+ }
+
+ EXPECT_TRUE(ns != nullptr)
+ << "Cannot find namespace " << apex_namespace_name;
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = ns,
+ };
+
+ void* handle = android_dlopen_ext(p.path().c_str(), RTLD_NOW, &dlextinfo);
EXPECT_TRUE(handle != nullptr) << dlerror();
if (handle == nullptr) {
continue;