aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/dlext_test.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 299b40808..14dff2bc8 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -17,8 +17,14 @@
#include <gtest/gtest.h>
#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
#include <android/dlext.h>
#include <sys/mman.h>
+#include <sys/wait.h>
#define ASSERT_DL_NOTNULL(ptr) \
@@ -27,10 +33,14 @@
#define ASSERT_DL_ZERO(i) \
ASSERT_EQ(0, i) << "dlerror: " << dlerror()
+#define ASSERT_NOERROR(i) \
+ ASSERT_NE(-1, i) << "errno: " << strerror(errno)
+
typedef int (*fn)(void);
#define LIBNAME "libdlext_test.so"
#define LIBSIZE 1024*1024 // how much address space to reserve for it
+#define RELRO_FILE "/data/local/tmp/libdlext_test.relro"
class DlExtTest : public ::testing::Test {
@@ -134,3 +144,49 @@ TEST_F(DlExtTest, ReservedHintTooSmall) {
reinterpret_cast<char*>(start) + PAGE_SIZE));
EXPECT_EQ(4, f());
}
+
+TEST_F(DlExtTest, RelroShareChildWrites) {
+ void* start = mmap(NULL, LIBSIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ ASSERT_TRUE(start != MAP_FAILED);
+ android_dlextinfo extinfo;
+ extinfo.reserved_addr = start;
+ extinfo.reserved_size = LIBSIZE;
+
+ int relro_fd;
+ relro_fd = open(RELRO_FILE, O_CREAT | O_RDWR | O_TRUNC, 0644);
+ extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO;
+ ASSERT_NOERROR(relro_fd);
+ extinfo.relro_fd = relro_fd;
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ // child process
+ void* handle = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
+ if (handle == NULL) {
+ fprintf(stderr, "in child: %s\n", dlerror());
+ exit(1);
+ }
+ exit(0);
+ }
+
+ // continuing in parent
+ ASSERT_NOERROR(close(relro_fd));
+ ASSERT_NOERROR(pid);
+ int status;
+ ASSERT_EQ(pid, waitpid(pid, &status, 0));
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(0, WEXITSTATUS(status));
+
+ relro_fd = open(RELRO_FILE, O_RDONLY);
+ ASSERT_NOERROR(relro_fd);
+ extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO;
+ extinfo.relro_fd = relro_fd;
+ handle_ = android_dlopen_ext(LIBNAME, RTLD_NOW, &extinfo);
+ ASSERT_NOERROR(close(relro_fd));
+
+ ASSERT_DL_NOTNULL(handle_);
+ fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(4, f());
+}