summaryrefslogtreecommitdiffstats
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
commit3a9059effb1c6ec79c6edde44d10690c43c3f52e (patch)
tree1aae10b36780b0901de672ca81523fdd70eeb8a1
parent8416f20f2f5581cf1710f8c6f96f100683777fc6 (diff)
downloadbcm5719-llvm-3a9059effb1c6ec79c6edde44d10690c43c3f52e.tar.gz
bcm5719-llvm-3a9059effb1c6ec79c6edde44d10690c43c3f52e.zip
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 llvm-svn: 368351
-rw-r--r--compiler-rt/lib/hwasan/hwasan.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp
index f0330247a8d..999b51183f6 100644
--- a/compiler-rt/lib/hwasan/hwasan.cpp
+++ b/compiler-rt/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);
OpenPOWER on IntegriCloud