Add test for misaligned section header

Make sure linker does not crash when dlopening
elf-file with odd section header offset.

Bug: http://b/30795430
Bug: http://b/30687964
Test: bionic-unit-tests --gtest_filter=dlfcn.dlopen_invalid*
Change-Id: If59cb6da85b8752a69dc5687de85f9a9b74c92b4
diff --git a/tests/Android.mk b/tests/Android.mk
index b329831..96cd07b 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,13 +16,29 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# TODO(dimitry): replace with define once https://android-review.googlesource.com/247466 is reverted
+# https://github.com/google/kati/issues/83 is currently blocking it.
+
 # 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_MODULE_CLASS := EXECUTABLES
+
+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)
+
+include $(CLEAR_VARS)
+LOCAL_MULTILIB := both
+LOCAL_MODULE := libtest_invalid-unaligned_shdr_offset.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 := EXECUTABLES
 
 LOCAL_SRC_FILES_arm := prebuilt-elf-files/arm/$(LOCAL_MODULE)
 LOCAL_SRC_FILES_arm64 := prebuilt-elf-files/arm64/$(LOCAL_MODULE)
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index a1c5801..9419bf3 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1161,4 +1161,13 @@
   std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W + E load segments are not allowed";
   ASSERT_STREQ(expected_dlerror.c_str(), dlerror());
 }
+
+TEST(dlfcn, dlopen_invalid_unaligned_shdr_offset) {
+  std::string libpath = std::string(getenv("ANDROID_DATA")) + PREBUILT_ELF_PATH + "/libtest_invalid-unaligned_shdr_offset.so";
+  void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle == nullptr);
+  std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\" has invalid shdr offset/size: ";
+  ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
+}
+
 #endif
diff --git a/tests/prebuilt-elf-files/arm/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/arm/libtest_invalid-unaligned_shdr_offset.so
new file mode 100755
index 0000000..24bd96e
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm/libtest_invalid-unaligned_shdr_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so
new file mode 100755
index 0000000..7389d9c
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/x86/libtest_invalid-unaligned_shdr_offset.so
new file mode 100755
index 0000000..5c9501c
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86/libtest_invalid-unaligned_shdr_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so
new file mode 100755
index 0000000..0d42283
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so
Binary files differ