Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 45f0a3b

Browse files
committed
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
1 parent 7e958d0 commit 45f0a3b

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

libc/private/WriteProtected.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ class WriteProtected {
4646

4747
WriteProtectedContents<T> contents;
4848

49+
int set_protection(int prot) {
50+
auto addr = reinterpret_cast<uintptr_t>(&contents);
51+
#if __has_feature(hwaddress_sanitizer)
52+
// The mprotect system call does not currently untag pointers, so do it
53+
// ourselves.
54+
addr &= (1ULL << 56) - 1;
55+
#endif
56+
return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot);
57+
}
58+
4959
public:
5060
WriteProtected() = default;
5161
BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
@@ -55,7 +65,7 @@ class WriteProtected {
5565
// multiple times by accident.
5666
memset(&contents, 0, sizeof(contents));
5767

58-
if (mprotect(&contents, PAGE_SIZE, PROT_READ)) {
68+
if (set_protection(PROT_READ)) {
5969
async_safe_fatal("failed to make WriteProtected nonwritable in initialize");
6070
}
6171
}
@@ -70,12 +80,12 @@ class WriteProtected {
7080

7181
template <typename Mutator>
7282
void mutate(Mutator mutator) {
73-
if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
83+
if (set_protection(PROT_READ | PROT_WRITE) != 0) {
7484
async_safe_fatal("failed to make WriteProtected writable in mutate: %s",
7585
strerror(errno));
7686
}
7787
mutator(&contents.value);
78-
if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) {
88+
if (set_protection(PROT_READ) != 0) {
7989
async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s",
8090
strerror(errno));
8191
}

libdl/libdl_cfi.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ extern "C" size_t __cfi_shadow_size() {
4545

4646
static uint16_t shadow_load(void* p) {
4747
uintptr_t addr = reinterpret_cast<uintptr_t>(p);
48+
#ifdef __aarch64__
49+
// Untag the pointer to move it into the address space covered by the shadow.
50+
addr &= (1ULL << 56) - 1;
51+
#endif
4852
uintptr_t ofs = CFIShadow::MemToShadowOffset(addr);
4953
if (ofs > CFIShadow::kShadowSize) return CFIShadow::kInvalidShadow;
5054
return *reinterpret_cast<uint16_t*>(shadow_base_storage.v + ofs);

0 commit comments

Comments
 (0)