}
SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
void *end_addr = (char *)addr + (rounded_length - 1);
- if (addr && (!MemIsApp(reinterpret_cast<uptr>(addr)) ||
- !MemIsApp(reinterpret_cast<uptr>(end_addr)))) {
+ if (addr && length &&
+ (!MemIsApp(reinterpret_cast<uptr>(addr)) ||
+ !MemIsApp(reinterpret_cast<uptr>(end_addr)))) {
// User requested an address that is incompatible with HWASan's
// memory layout. Use a different address if allowed, else fail.
if (flags & map_fixed) {
}
}
void *res = real_mmap(addr, length, prot, flags, fd, offset);
- if (res != (void *)-1) {
- void *end_res = (char *)res + (rounded_length - 1);
- if (!MemIsApp(reinterpret_cast<uptr>(res)) ||
- !MemIsApp(reinterpret_cast<uptr>(end_res))) {
+ if (length && res != (void *)-1) {
+ uptr beg = reinterpret_cast<uptr>(res);
+ DCHECK(IsAligned(beg, GetPageSize()));
+ if (!MemIsApp(beg) || !MemIsApp(beg + rounded_length - 1)) {
// Application has attempted to map more memory than is supported by
// HWASan. Act as if we ran out of memory.
internal_munmap(res, length);
errno = errno_ENOMEM;
return (void *)-1;
}
- __hwasan::TagMemory(reinterpret_cast<uptr>(addr), length, 0);
+ __hwasan::TagMemoryAligned(beg, rounded_length, 0);
}
return res;
template <class Munmap>
static int munmap_interceptor(Munmap real_munmap, void *addr, SIZE_T length) {
- __hwasan::TagMemory(reinterpret_cast<uptr>(addr), length, 0);
+ // We should not tag if munmap fail, but it's to late to tag after
+ // real_munmap, as the pages could be mmaped by another thread.
+ uptr beg = reinterpret_cast<uptr>(addr);
+ if (length && IsAligned(beg, GetPageSize())) {
+ SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
+ // Protect from unmapping the shadow.
+ if (!MemIsApp(beg) || !MemIsApp(beg + rounded_length - 1)) {
+ errno = errno_EINVAL;
+ return -1;
+ }
+ __hwasan::TagMemoryAligned(beg, rounded_length, 0);
+ }
return real_munmap(addr, length);
}
// RUN: %clang_hwasan %s -o %t
-// RUN: %run %t 2>&1
+// RUN: %run %t 1 2>&1
+// RUN: %run %t 2 2>&1
// REQUIRES: pointer-tagging
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
+#include <unistd.h>
int main(int argc, char **argv) {
- const int kSize = 4096;
+ const size_t kPS = sysconf(_SC_PAGESIZE);
+ const int kSize = kPS / atoi(argv[1]);
const int kTag = 47;
// Get any mmaped pointer.
}
// Manually tag the pointer and the memory.
- __hwasan_tag_memory(r, kTag, kSize);
+ __hwasan_tag_memory(r, kTag, kPS);
int *p1 = __hwasan_tag_pointer(r, kTag);
// Check that the pointer and the tag match.
- if (__hwasan_test_shadow(p1, kSize) != -1) {
+ if (__hwasan_test_shadow(p1, kPS) != -1) {
fprintf(stderr, "Failed to tag.\n");
abort();
}
+ if (munmap((char *)r + 1, kSize) == 0) {
+ perror("munmap should fail: ");
+ abort();
+ }
+
+ if (__hwasan_test_shadow(p1, kPS) != -1) {
+ fprintf(stderr, "Still must be tagged.\n");
+ abort();
+ }
+
// First munmmap and then mmap the same pointer using MAP_FIXED.
if (munmap((char *)r, kSize) != 0) {
perror("Failed to unmap: ");
abort();
}
- if (__hwasan_test_shadow(r, kSize) != -1) {
+ if (__hwasan_test_shadow(r, kPS) != -1) {
fprintf(stderr, "Shadow memory was not cleaned by munmap.\n");
abort();
}
- __hwasan_tag_memory(r, kTag, kSize);
+ __hwasan_tag_memory(r, kTag, kPS);
int *p2 = (int *)mmap(r, kSize, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
}
// Make sure we can access the shadow with an untagged pointer.
- if (__hwasan_test_shadow(p2, kSize) != -1) {
+ if (__hwasan_test_shadow(p2, kPS) != -1) {
fprintf(stderr, "Shadow memory was not cleaned by mmap.\n");
abort();
}