[MSan] Simulate OOM in mmap_interceptor()

Summary:
Some kernels can provide 16EiB worth of mappings to each process, which
causes mmap test to run for a very long time. In order to make it stop
after a few seconds, make mmap_interceptor() fail when the original
mmap() returns an address which is outside of the application range.

Reviewers: eugenis

Reviewed By: eugenis

Subscribers: #sanitizers, Andreas-Krebbel, stefansf, jonpa, uweigand

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D76426
This commit is contained in:
Ilya Leoshkevich 2020-03-19 13:19:28 -07:00 committed by Evgenii Stepanov
parent 796fb2e474
commit c985b244ee
1 changed files with 15 additions and 2 deletions

View File

@ -953,7 +953,9 @@ void __sanitizer_dtor_callback(const void *data, uptr size) {
template <class Mmap>
static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
int prot, int flags, int fd, OFF64_T offset) {
if (addr && !MEM_IS_APP(addr)) {
SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
void *end_addr = (char *)addr + (rounded_length - 1);
if (addr && (!MEM_IS_APP(addr) || !MEM_IS_APP(end_addr))) {
if (flags & map_fixed) {
errno = errno_EINVAL;
return (void *)-1;
@ -962,7 +964,18 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
}
}
void *res = real_mmap(addr, length, prot, flags, fd, offset);
if (res != (void *)-1) __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
if (res != (void *)-1) {
void *end_res = (char *)res + (rounded_length - 1);
if (MEM_IS_APP(res) && MEM_IS_APP(end_res)) {
__msan_unpoison(res, rounded_length);
} else {
// Application has attempted to map more memory than is supported by
// MSAN. Act as if we ran out of memory.
internal_munmap(res, length);
errno = errno_ENOMEM;
return (void *)-1;
}
}
return res;
}