Clear pointer tags as required for HWASAN for globals.
A future version of HWASAN will set pointer tags when taking the address of a global. This means that we need to untag pointers in a couple of cases where potential global pointers are passed to an interface that expects untagged pointers: - The WriteProtected class, whose only instances are globals, passes its own address to mprotect. However, our device kernels do not currently untag pointers passed to mprotect (the proposed upstream kernel patches do, however, untag these pointers), so once HWASAN starts tagging global pointers, this will start failing. - The shadow_load function loads from a shadow that corresponds to the address space bounds of loaded binaries. Since these address space bounds are untagged, the pointer needs to be untagged to match. Test: boots Change-Id: I3f11ce6eb7261752e5ff6d039d04dd45516b236f
This commit is contained in:
parent
7e958d0ce0
commit
45f0a3b642
|
@ -46,6 +46,16 @@ class WriteProtected {
|
|||
|
||||
WriteProtectedContents<T> contents;
|
||||
|
||||
int set_protection(int prot) {
|
||||
auto addr = reinterpret_cast<uintptr_t>(&contents);
|
||||
#if __has_feature(hwaddress_sanitizer)
|
||||
// The mprotect system call does not currently untag pointers, so do it
|
||||
// ourselves.
|
||||
addr &= (1ULL << 56) - 1;
|
||||
#endif
|
||||
return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot);
|
||||
}
|
||||
|
||||
public:
|
||||
WriteProtected() = default;
|
||||
BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
|
||||
|
@ -55,7 +65,7 @@ class WriteProtected {
|
|||
// multiple times by accident.
|
||||
memset(&contents, 0, sizeof(contents));
|
||||
|
||||
if (mprotect(&contents, PAGE_SIZE, PROT_READ)) {
|
||||
if (set_protection(PROT_READ)) {
|
||||
async_safe_fatal("failed to make WriteProtected nonwritable in initialize");
|
||||
}
|
||||
}
|
||||
|
@ -70,12 +80,12 @@ class WriteProtected {
|
|||
|
||||
template <typename Mutator>
|
||||
void mutate(Mutator mutator) {
|
||||
if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
|
||||
if (set_protection(PROT_READ | PROT_WRITE) != 0) {
|
||||
async_safe_fatal("failed to make WriteProtected writable in mutate: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
mutator(&contents.value);
|
||||
if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) {
|
||||
if (set_protection(PROT_READ) != 0) {
|
||||
async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ 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 ofs = CFIShadow::MemToShadowOffset(addr);
|
||||
if (ofs > CFIShadow::kShadowSize) return CFIShadow::kInvalidShadow;
|
||||
return *reinterpret_cast<uint16_t*>(shadow_base_storage.v + ofs);
|
||||
|
|
Loading…
Reference in New Issue