diff options
-rw-r--r-- | libc/private/WriteProtected.h | 4 | ||||
-rw-r--r-- | libc/private/bionic_macros.h | 9 | ||||
-rw-r--r-- | libdl/libdl_cfi.cpp | 5 | ||||
-rw-r--r-- | linker/linker.cpp | 10 | ||||
-rw-r--r-- | tests/dlext_test.cpp | 6 | ||||
-rw-r--r-- | tests/libs/segment_gap_outer.lds | 2 |
6 files changed, 23 insertions, 13 deletions
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h index d240e1465..26c239ca1 100644 --- a/libc/private/WriteProtected.h +++ b/libc/private/WriteProtected.h @@ -47,11 +47,11 @@ class WriteProtected { WriteProtectedContents<T> contents; int set_protection(int prot) { - auto addr = reinterpret_cast<uintptr_t>(&contents); + auto addr = &contents; #if __has_feature(hwaddress_sanitizer) // The mprotect system call does not currently untag pointers, so do it // ourselves. - addr &= (1ULL << 56) - 1; + addr = untag_address(addr); #endif return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot); } diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h index 4800e3af9..13934e5f6 100644 --- a/libc/private/bionic_macros.h +++ b/libc/private/bionic_macros.h @@ -87,3 +87,12 @@ char (&ArraySizeHelper(T (&array)[N]))[N]; // NOLINT(readability/casting) #else #define __BIONIC_FALLTHROUGH #endif + +template <typename T> +static inline T* untag_address(T* p) { +#if defined(__aarch64__) + return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & ((1ULL << 56) - 1)); +#else + return p; +#endif +} diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp index 14461436c..3b68fc7d3 100644 --- a/libdl/libdl_cfi.cpp +++ b/libdl/libdl_cfi.cpp @@ -44,11 +44,8 @@ extern "C" size_t __cfi_shadow_size() { } static uint16_t shadow_load(void* p) { - uintptr_t addr = reinterpret_cast<uintptr_t>(p); -#ifdef __aarch64__ // Untag the pointer to move it into the address space covered by the shadow. - addr &= (1ULL << 56) - 1; -#endif + uintptr_t addr = reinterpret_cast<uintptr_t>(untag_address(p)); uintptr_t ofs = CFIShadow::MemToShadowOffset(addr); if (ofs > CFIShadow::kShadowSize) return CFIShadow::kInvalidShadow; return *reinterpret_cast<uint16_t*>(shadow_base_storage.v + ofs); diff --git a/linker/linker.cpp b/linker/linker.cpp index 0361a8ab3..e41194d1a 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -951,7 +951,9 @@ static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns, } soinfo* find_containing_library(const void* p) { - ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p); + // Addresses within a library may be tagged if they point to globals. Untag + // them so that the bounds check succeeds. + ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(untag_address(p)); for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) { if (address < si->base || address - si->base >= si->size) { continue; @@ -1901,13 +1903,13 @@ bool find_libraries(android_namespace_t* ns, // flag is set. link_extinfo = extinfo; } + if (__libc_shared_globals()->load_hook) { + __libc_shared_globals()->load_hook(si->load_bias, si->phdr, si->phnum); + } if (!si->link_image(global_group, local_group, link_extinfo, &relro_fd_offset) || !get_cfi_shadow()->AfterLoad(si, solist_get_head())) { return false; } - if (__libc_shared_globals()->load_hook) { - __libc_shared_globals()->load_hook(si->load_bias, si->phdr, si->phnum); - } } return true; diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp index 59cf2f771..e7274f704 100644 --- a/tests/dlext_test.cpp +++ b/tests/dlext_test.cpp @@ -361,8 +361,10 @@ TEST_F(DlExtTest, ReservedRecursive) { uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number")); ASSERT_DL_NOTNULL(taxicab_number); - EXPECT_GE(reinterpret_cast<void*>(taxicab_number), start); - EXPECT_LT(reinterpret_cast<void*>(taxicab_number), reinterpret_cast<char*>(start) + kLibSize); + // Untag the pointer so that it can be compared with start, which will be untagged. + void* addr = reinterpret_cast<void*>(untag_address(taxicab_number)); + EXPECT_GE(addr, start); + EXPECT_LT(addr, reinterpret_cast<char*>(start) + kLibSize); EXPECT_EQ(1729U, *taxicab_number); } diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds index f326aab26..c2961b2c6 100644 --- a/tests/libs/segment_gap_outer.lds +++ b/tests/libs/segment_gap_outer.lds @@ -22,6 +22,6 @@ SECTIONS { # Place end_of_gap at the end of the gap. . = 0x1000000; .bss.end_of_gap : { - *(.bss.end_of_gap); + *(.bss.*end_of_gap*); } } |