From 1946856b1f18a27c51ba30bb9e304f25b722ee05 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 20 Jul 2015 17:30:33 +0000 Subject: [PATCH] Revert "make vdso function pointers read-only at runtime" This reverts commit df1a3c6d21702e3e96cfcddadee4a50bfac82110. This change prevented N9 from booting (http://b/22568628). Change-Id: I071d6d6a0ae7881d65641839e665acdcf58462b4 --- libc/bionic/vdso.cpp | 45 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp index d4aea986b..a2406634d 100644 --- a/libc/bionic/vdso.cpp +++ b/libc/bionic/vdso.cpp @@ -30,14 +30,8 @@ #define VDSO_GETTIMEOFDAY_SYMBOL "__vdso_gettimeofday" #endif -#include -#include -#include #include -#include "private/bionic_prctl.h" -#include "private/libc_logging.h" - extern "C" int __clock_gettime(int, timespec*); extern "C" int __gettimeofday(timeval*, struct timezone*); @@ -52,33 +46,28 @@ enum { VDSO_END }; -static const vdso_entry vdso_entries_template[] = { +static vdso_entry vdso_entries[] = { [VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, reinterpret_cast(__clock_gettime) }, [VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, reinterpret_cast(__gettimeofday) }, }; -static vdso_entry* vdso_entries; - int clock_gettime(int clock_id, timespec* tp) { - int (*vdso_clock_gettime)(int, timespec*) = + static int (*vdso_clock_gettime)(int, timespec*) = reinterpret_cast(vdso_entries[VDSO_CLOCK_GETTIME].fn); return vdso_clock_gettime(clock_id, tp); } int gettimeofday(timeval* tv, struct timezone* tz) { - int (*vdso_gettimeofday)(timeval*, struct timezone*) = + static int (*vdso_gettimeofday)(timeval*, struct timezone*) = reinterpret_cast(vdso_entries[VDSO_GETTIMEOFDAY].fn); return vdso_gettimeofday(tv, tz); } -static void __libc_init_vdso_entries() { - // Set up the defaults in case we don't have a vdso or can't find everything we're looking for. - memcpy(vdso_entries, vdso_entries_template, sizeof(vdso_entries_template)); - +void __libc_init_vdso() { // Do we have a vdso? uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR); ElfW(Ehdr)* vdso_ehdr = reinterpret_cast(vdso_ehdr_addr); - if (vdso_ehdr == nullptr) { + if (vdso_ehdr == NULL) { return; } @@ -96,7 +85,7 @@ static void __libc_init_vdso_entries() { // Where's the dynamic table? ElfW(Addr) vdso_addr = 0; - ElfW(Dyn)* vdso_dyn = nullptr; + ElfW(Dyn)* vdso_dyn = NULL; ElfW(Phdr)* vdso_phdr = reinterpret_cast(vdso_ehdr_addr + vdso_ehdr->e_phoff); for (size_t i = 0; i < vdso_ehdr->e_phnum; ++i) { if (vdso_phdr[i].p_type == PT_DYNAMIC) { @@ -105,13 +94,13 @@ static void __libc_init_vdso_entries() { vdso_addr = vdso_ehdr_addr + vdso_phdr[i].p_offset - vdso_phdr[i].p_vaddr; } } - if (vdso_addr == 0 || vdso_dyn == nullptr) { + if (vdso_addr == 0 || vdso_dyn == NULL) { return; } // Where are the string and symbol tables? - const char* strtab = nullptr; - ElfW(Sym)* symtab = nullptr; + const char* strtab = NULL; + ElfW(Sym)* symtab = NULL; for (ElfW(Dyn)* d = vdso_dyn; d->d_tag != DT_NULL; ++d) { if (d->d_tag == DT_STRTAB) { strtab = reinterpret_cast(vdso_addr + d->d_un.d_ptr); @@ -119,7 +108,7 @@ static void __libc_init_vdso_entries() { symtab = reinterpret_cast(vdso_addr + d->d_un.d_ptr); } } - if (strtab == nullptr || symtab == nullptr) { + if (strtab == NULL || symtab == NULL) { return; } @@ -133,20 +122,6 @@ static void __libc_init_vdso_entries() { } } -void __libc_init_vdso() { - static_assert(PAGE_SIZE >= sizeof(vdso_entries_template), "vdso_entries_template too large"); - vdso_entries = reinterpret_cast(mmap(nullptr, sizeof(vdso_entries_template), PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)); - if (vdso_entries == MAP_FAILED) { - __libc_fatal("failed to allocate vdso function pointer table: %s", strerror(errno)); - } - __libc_init_vdso_entries(); - if (mprotect(vdso_entries, sizeof(vdso_entries_template), PROT_READ) == -1) { - __libc_fatal("failed to mprotect PROT_READ vdso function pointer table: %s", strerror(errno)); - } - prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, vdso_entries, sizeof(vdso_entries_template), "vdso function pointer table"); -} - #else void __libc_init_vdso() {