linker: disallow W + E PT_LOAD segments
No mapped segment from the elf file can be writable and
executable at the same time. This commit adds a check
for malformed PT_LOAD segments in the elf-files.
Bug: http://b/30146890
Test: run bionic-unit-tests --gtest_filter=dlfcn.*
Change-Id: Ia23acbe5a48780b65d7e4a50bbe024cd528079f4
diff --git a/tests/Android.mk b/tests/Android.mk
index 0da3b88..b329831 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,6 +16,20 @@
LOCAL_PATH := $(call my-dir)
+# Move prebuilt test elf-files to $(TARGET_OUT_NATIVE_TESTS)
+include $(CLEAR_VARS)
+LOCAL_MULTILIB := both
+LOCAL_MODULE := libtest_invalid-rw_load_segment.so
+LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/prebuilt-elf-files
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/prebuilt-elf-files
+LOCAL_MODULE_CLASS := SHARED_LIBRARY
+
+LOCAL_SRC_FILES_arm := prebuilt-elf-files/arm/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := prebuilt-elf-files/arm64/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_x86 := prebuilt-elf-files/x86/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_x86_64 := prebuilt-elf-files/x86_64/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
build_host := true
else
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 5bf5861..a1c5801 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1142,3 +1142,23 @@
dlclose(handle);
}
+
+// Bionic specific tests
+#if defined(__BIONIC__)
+
+#if defined(__LP64__)
+#define NATIVE_TESTS_PATH "/nativetest64"
+#else
+#define NATIVE_TESTS_PATH "/nativetest"
+#endif
+
+#define PREBUILT_ELF_PATH NATIVE_TESTS_PATH "/prebuilt-elf-files"
+
+TEST(dlfcn, dlopen_invalid_rw_load_segment) {
+ std::string libpath = std::string(getenv("ANDROID_DATA")) + PREBUILT_ELF_PATH + "/libtest_invalid-rw_load_segment.so";
+ void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+ ASSERT_TRUE(handle == nullptr);
+ std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W + E load segments are not allowed";
+ ASSERT_STREQ(expected_dlerror.c_str(), dlerror());
+}
+#endif
diff --git a/tests/prebuilt-elf-files/arm/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/arm/libtest_invalid-rw_load_segment.so
new file mode 100755
index 0000000..00d91ff
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm/libtest_invalid-rw_load_segment.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so
new file mode 100755
index 0000000..f61d2ed
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/x86/libtest_invalid-rw_load_segment.so
new file mode 100755
index 0000000..7a343c9
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86/libtest_invalid-rw_load_segment.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so
new file mode 100755
index 0000000..b39d0ca
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so
Binary files differ