Skip to content

Commit 9f04ac0

Browse files
committed
[msan] Add 'MappingDesc::ALLOCATOR' type and check it is available
MSan divides the virtual address space into APP, INVALID, SHADOW and ORIGIN memory. The allocator usually just steals a bit of the APP address space: typically the bottom portion of the PIE binaries section, which works because the Linux kernel maps from the top of the PIE binaries section. However, if ASLR is very aggressive, the binary may end up mapped in the same location where the allocator wants to live; this results in a segfault. This patch adds in a MappingDesc::ALLOCATOR type and enforces that the memory range for the allocator is not occupied by anything else. Since the allocator range information is not readily available in msan.h, we duplicate the information from msan_allocator.cpp. Note: aggressive ASLR can also lead to a different type of failure, where the PIE binaries/libaries are mapped entirely outside of the APP/ALLOCATOR sections; that will be addressed in a separate patch (llvm#85142).
1 parent 8bed754 commit 9f04ac0

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

compiler-rt/lib/msan/msan.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@
3232
struct MappingDesc {
3333
uptr start;
3434
uptr end;
35-
enum Type {
36-
INVALID, APP, SHADOW, ORIGIN
37-
} type;
35+
enum Type { INVALID, ALLOCATOR, APP, SHADOW, ORIGIN } type;
3836
const char *name;
3937
};
4038

41-
39+
// Note: MappingDesc::ALLOCATOR entries are only used to check for memory
40+
// layout compatibility. The actual allocation settings are in
41+
// msan_allocator.cpp, which need to be kept in sync.
4242
#if SANITIZER_LINUX && defined(__mips64)
4343

4444
// MIPS64 maps:
@@ -84,7 +84,8 @@ const MappingDesc kMemoryLayout[] = {
8484
{0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"},
8585
{0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"},
8686
{0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"},
87-
{0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"},
87+
{0x0E00000000000, 0x0E40000000000, MappingDesc::ALLOCATOR, "allocator"},
88+
{0X0E40000000000, 0X1000000000000, MappingDesc::APP, "app-15"},
8889
};
8990
# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL)
9091
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL)
@@ -106,7 +107,8 @@ const MappingDesc kMemoryLayout[] = {
106107
{0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
107108
{0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
108109
{0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
109-
{0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
110+
{0x700000000000ULL, 0x740000000000ULL, MappingDesc::ALLOCATOR, "allocator"},
111+
{0x740000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
110112
# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
111113
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x100000000000ULL)
112114

@@ -118,7 +120,8 @@ const MappingDesc kMemoryLayout[] = {
118120
{0x180200000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
119121
{0x1C0000000000ULL, 0x2C0200000000ULL, MappingDesc::ORIGIN, "origin"},
120122
{0x2C0200000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"},
121-
{0x300000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
123+
{0x300000000000ULL, 0x320000000000ULL, MappingDesc::ALLOCATOR, "allocator"},
124+
{0x320000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
122125

123126
// Various kernels use different low end ranges but we can combine them into one
124127
// big range. They also use different high end ranges but we can map them all to
@@ -141,7 +144,8 @@ const MappingDesc kMemoryLayout[] = {
141144
{0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
142145
{0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"},
143146
{0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"},
144-
{0x440000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}};
147+
{0x440000000000ULL, 0x460000000000ULL, MappingDesc::ALLOCATOR, "allocator"},
148+
{0x460000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}};
145149

146150
#define MEM_TO_SHADOW(mem) \
147151
((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL)
@@ -208,7 +212,8 @@ const MappingDesc kMemoryLayout[] = {
208212
{0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
209213
{0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
210214
{0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
211-
{0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
215+
{0x700000000000ULL, 0x740000000000ULL, MappingDesc::ALLOCATOR, "allocator"},
216+
{0x740000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
212217
#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
213218
#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)
214219

@@ -236,7 +241,9 @@ inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
236241
return false;
237242
}
238243

239-
#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
244+
#define MEM_IS_APP(mem) \
245+
(addr_is_type((uptr)(mem), MappingDesc::APP) || \
246+
addr_is_type((uptr)(mem), MappingDesc::ALLOCATOR))
240247
#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
241248
#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
242249

compiler-rt/lib/msan/msan_allocator.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ struct MsanMapUnmapCallback {
4848
}
4949
};
5050

51+
// Note: to ensure that the allocator is compatible with the application memory
52+
// layout (especially with high-entropy ASLR), kSpaceBeg and kSpaceSize must be
53+
// duplicated as MappingDesc::ALLOCATOR in msan.h.
5154
#if defined(__mips64)
5255
static const uptr kMaxAllowedMallocSize = 2UL << 30;
5356

compiler-rt/lib/msan/msan_linux.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static void CheckMemoryLayoutSanity() {
8686
CHECK(addr_is_type(start, type));
8787
CHECK(addr_is_type((start + end) / 2, type));
8888
CHECK(addr_is_type(end - 1, type));
89-
if (type == MappingDesc::APP) {
89+
if (type == MappingDesc::APP || type == MappingDesc::ALLOCATOR) {
9090
uptr addr = start;
9191
CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));
9292
CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));
@@ -138,8 +138,13 @@ bool InitShadow(bool init_origins) {
138138
bool protect = type == MappingDesc::INVALID ||
139139
(!init_origins && type == MappingDesc::ORIGIN);
140140
CHECK(!(map && protect));
141-
if (!map && !protect)
142-
CHECK(type == MappingDesc::APP);
141+
if (!map && !protect) {
142+
CHECK(type == MappingDesc::APP || type == MappingDesc::ALLOCATOR);
143+
144+
if (type == MappingDesc::ALLOCATOR &&
145+
!CheckMemoryRangeAvailability(start, size))
146+
return false;
147+
}
143148
if (map) {
144149
if (!CheckMemoryRangeAvailability(start, size))
145150
return false;

0 commit comments

Comments
 (0)