Merge "Improve linker_namespaces CTS test"
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 3ffabc3..55ac4f9 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -67,6 +67,22 @@
"libz.so"
};
+// This is not complete list - just a small subset
+// of the libraries that should reside in /system/lib
+// (in addition to kSystemPublicLibraries)
+static std::unordered_set<std::string> kSystemLibraries = {
+ "libart.so",
+ "libandroid_runtime.so",
+ "libbinder.so",
+ "libcutils.so",
+ "libgui.so",
+ "libmedia.so",
+ "libnativehelper.so",
+ "libstagefright.so",
+ "libui.so",
+ "libutils.so",
+ };
+
template <typename F>
static bool for_each_file(const std::string& dir, F functor, std::string* error_msg) {
auto dir_deleter = [](DIR* handle) { closedir(handle); };
@@ -113,8 +129,44 @@
return kSystemLibraryPath + "/libdl.so" == path;
}
+static bool check_lib(const std::string& public_library_path,
+ const std::unordered_set<std::string>& public_libraries,
+ const std::string& path,
+ std::string* error_msg) {
+ if (is_libdl(path)) {
+ // TODO (dimitry): we skip check for libdl.so because
+ // 1. Linker will fail to check accessibility because it imposes as libdl.so (see http://b/27106625)
+ // 2. It is impractical to dlopen libdl.so because this library already depends
+ // on it in order to have dlopen()
+ return true;
+ }
+
+ auto dlcloser = [](void* handle) { dlclose(handle); };
+ std::unique_ptr<void, decltype(dlcloser)> handle(dlopen(path.c_str(), RTLD_NOW), dlcloser);
+ if (should_be_accessible(public_library_path, public_libraries, path)) {
+ if (handle.get() == nullptr) {
+ *error_msg = "The library \"" + path + "\" should be accessible but isn't: " + dlerror();
+ return false;
+ }
+ } else if (handle != nullptr) {
+ *error_msg = "The library \"" + path + "\" should not be accessible";
+ return false;
+ } else { // (handle == nullptr && !shouldBeAccessible(path))
+ // Check the error message
+ std::string err = dlerror();
+
+ if (err.find("dlopen failed: library \"" + path + "\"") != 0 ||
+ err.find("is not accessible for the namespace \"classloader-namespace\"") == std::string::npos) {
+ *error_msg = "unexpected dlerror: " + err;
+ return false;
+ }
+ }
+ return true;
+}
+
static bool check_libs(const std::string& public_library_path,
const std::unordered_set<std::string>& public_libraries,
+ const std::unordered_set<std::string>& mandatory_files,
std::string* error) {
std::list<std::string> dirs;
dirs.push_back(public_library_path);
@@ -129,40 +181,20 @@
return true;
}
- if (is_libdl(path)) {
- // TODO (dimitry): we skip check for libdl.so because
- // 1. Linker will fail to check accessibility because it imposes as libdl.so (see http://b/27106625)
- // 2. It is impractical to dlopen libdl.so because this library already depends
- // on it in order to have dlopen()
- return true;
- }
-
- auto dlcloser = [](void* handle) { dlclose(handle); };
- std::unique_ptr<void, decltype(dlcloser)> handle(dlopen(path.c_str(), RTLD_NOW), dlcloser);
- if (should_be_accessible(public_library_path, public_libraries, path)) {
- if (handle.get() == nullptr) {
- *error_msg = "The library \"" + path + "\" should be accessible but isn't: " + dlerror();
- return false;
- }
- } else if (handle != nullptr) {
- *error_msg = "The library \"" + path + "\" should not be accessible";
- return false;
- } else { // (handle == nullptr && !shouldBeAccessible(path))
- // Check the error message
- std::string err = dlerror();
-
- if (err.find("dlopen failed: library \"" + path + "\"") != 0 ||
- err.find("is not accessible for the namespace \"classloader-namespace\"") == std::string::npos) {
- *error_msg = "unexpected dlerror: " + err;
- return false;
- }
- }
- return true;
+ return check_lib(public_library_path, public_libraries, path, error_msg);
}, error);
if (!success) {
return false;
}
+
+ // Check mandatory files - the grey list
+ for (const auto& name : mandatory_files) {
+ std::string path = public_library_path + "/" + name;
+ if (!check_lib(public_library_path, public_libraries, path, error)) {
+ return false;
+ }
+ }
}
return true;
@@ -189,10 +221,11 @@
std::string error;
std::unordered_set<std::string> vendor_public_libraries;
+ std::unordered_set<std::string> empty_set;
load_vendor_libraries(env, java_vendor_public_libraries, &vendor_public_libraries);
- if (!check_libs(kSystemLibraryPath, kSystemPublicLibraries, &error) ||
- !check_libs(kVendorLibraryPath, vendor_public_libraries, &error)) {
+ if (!check_libs(kSystemLibraryPath, kSystemPublicLibraries, kSystemLibraries, &error) ||
+ !check_libs(kVendorLibraryPath, vendor_public_libraries, empty_set, &error)) {
return env->NewStringUTF(error.c_str());
}