forked from OSchip/llvm-project
[msan] Unpoison memory that is returned to the OS and flush its shadow.
llvm-svn: 195244
This commit is contained in:
parent
115ef14548
commit
584fd96e9e
|
@ -22,15 +22,29 @@ struct Metadata {
|
|||
uptr requested_size;
|
||||
};
|
||||
|
||||
struct MsanMapUnmapCallback {
|
||||
void OnMap(uptr p, uptr size) const {}
|
||||
void OnUnmap(uptr p, uptr size) const {
|
||||
__msan_unpoison((void *)p, size);
|
||||
|
||||
// We are about to unmap a chunk of user memory.
|
||||
// Mark the corresponding shadow memory as not needed.
|
||||
FlushUnneededShadowMemory(MEM_TO_SHADOW(p), size);
|
||||
if (__msan_get_track_origins())
|
||||
FlushUnneededShadowMemory(MEM_TO_ORIGIN(p), size);
|
||||
}
|
||||
};
|
||||
|
||||
static const uptr kAllocatorSpace = 0x600000000000ULL;
|
||||
static const uptr kAllocatorSize = 0x80000000000; // 8T.
|
||||
static const uptr kMetadataSize = sizeof(Metadata);
|
||||
static const uptr kMaxAllowedMallocSize = 8UL << 30;
|
||||
|
||||
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
|
||||
DefaultSizeClassMap> PrimaryAllocator;
|
||||
DefaultSizeClassMap,
|
||||
MsanMapUnmapCallback> PrimaryAllocator;
|
||||
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
|
||||
typedef LargeMmapAllocator<> SecondaryAllocator;
|
||||
typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
|
||||
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
|
||||
SecondaryAllocator> Allocator;
|
||||
|
||||
|
|
|
@ -3571,3 +3571,26 @@ TEST(MemorySanitizer, MlockTest) {
|
|||
EXPECT_EQ(0, munlockall());
|
||||
EXPECT_EQ(0, munlock((void*)0x987, 0x654));
|
||||
}
|
||||
|
||||
// Test that LargeAllocator unpoisons memory before releasing it to the OS.
|
||||
TEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) {
|
||||
void *p = malloc(1024 * 1024);
|
||||
free(p);
|
||||
|
||||
typedef void *(*mmap_fn)(void *, size_t, int, int, int, off_t);
|
||||
mmap_fn real_mmap = (mmap_fn)dlsym(RTLD_NEXT, "mmap");
|
||||
|
||||
// Allocate the page that was released to the OS in free() with the real mmap,
|
||||
// bypassing the interceptor.
|
||||
char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
ASSERT_NE((char *)0, q);
|
||||
|
||||
ASSERT_TRUE(q <= p);
|
||||
ASSERT_TRUE(q + 4096 > p);
|
||||
|
||||
EXPECT_NOT_POISONED(q[0]);
|
||||
EXPECT_NOT_POISONED(q[10]);
|
||||
EXPECT_NOT_POISONED(q[100]);
|
||||
|
||||
munmap(q, 4096);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue