summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2019-08-08 21:40:00 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2019-08-08 21:40:00 +0000
commit228ee15cf7c5c30461d094a22aaeeef453b324d7 (patch)
tree96940d2baa9cf6c84c78bab1bb0a428e93433748
parentddf4f111bd336db92a0a9ae1ebc31bbd64c62511 (diff)
downloadcompiler-rt-228ee15cf7c5c30461d094a22aaeeef453b324d7.tar.gz
hwasan: Add a code model check for tagged globals.
See D65364 for the code model requirements for tagged globals. Because of the relocations used these requirements cannot be checked at link time so they must be checked at runtime. Differential Revision: https://reviews.llvm.org/D65968 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@368351 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/hwasan/hwasan.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/hwasan/hwasan.cpp b/lib/hwasan/hwasan.cpp
index f0330247a..999b51183 100644
--- a/lib/hwasan/hwasan.cpp
+++ b/lib/hwasan/hwasan.cpp
@@ -240,13 +240,39 @@ struct hwasan_global_note {
s32 end_relptr;
};
+// Check that the given library meets the code model requirements for tagged
+// globals. These properties are not checked at link time so they need to be
+// checked at runtime.
+static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum) {
+ ElfW(Addr) min_addr = -1ull, max_addr = 0;
+ for (unsigned i = 0; i != phnum; ++i) {
+ if (phdr[i].p_type != PT_LOAD)
+ continue;
+ ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz;
+ if (min_addr > lo)
+ min_addr = lo;
+ if (max_addr < hi)
+ max_addr = hi;
+ }
+
+ if (max_addr - min_addr > 1ull << 32) {
+ Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n");
+ Die();
+ }
+ if (max_addr > 1ull << 48) {
+ Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n");
+ Die();
+ }
+}
+
static void InitGlobalsFromPhdrs(ElfW(Addr) base, const ElfW(Phdr) * phdr,
ElfW(Half) phnum) {
- for (; phnum != 0; ++phdr, --phnum) {
- if (phdr->p_type != PT_NOTE)
+ for (unsigned i = 0; i != phnum; ++i) {
+ if (phdr[i].p_type != PT_NOTE)
continue;
- const char *note = reinterpret_cast<const char *>(base + phdr->p_vaddr);
- const char *nend = note + phdr->p_memsz;
+ const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr);
+ const char *nend = note + phdr[i].p_memsz;
while (note < nend) {
auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note);
const char *name = note + sizeof(ElfW(Nhdr));
@@ -257,6 +283,10 @@ static void InitGlobalsFromPhdrs(ElfW(Addr) base, const ElfW(Phdr) * phdr,
continue;
}
+ // Only libraries with instrumented globals need to be checked against the
+ // code model since they use relocations that aren't checked at link time.
+ CheckCodeModel(base, phdr, phnum);
+
auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc);
auto *global_begin = reinterpret_cast<const hwasan_global *>(
note + global_note->begin_relptr);