Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 3f66d42

Browse files
committed
Port to release/1.0.0: Fix PAL executable allocator locking
We call the ExecutableAllocator from two places in PAL. One is the VirtualAlloc when the allocation type contains MEM_RESERVE_EXECUTABLE. The other is MAPMapPEFile. While the former is called inside of the virtual_critsec critical section, the latter doesn't take that critical section and so in some race cases, we were returning the same address twice - once for VirtualAlloc and once for MAPMapPEFile. That resulted in strange memory corruption cases. The fix is to use the same critical section for the MAPMapPEFile too. I am also reverting the change in the virtual commit that was made when we have thought that the culprit might be in the mprotect.
1 parent 12a2d7b commit 3f66d42

File tree

3 files changed

+8
-14
lines changed

3 files changed

+8
-14
lines changed

src/pal/src/include/pal/virtual.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Function :
209209
that is located close to the coreclr library. The memory comes from the virtual
210210
address range that is managed by ExecutableMemoryAllocator.
211211
--*/
212-
void* ReserveMemoryFromExecutableAllocator(SIZE_T allocationSize);
212+
void* ReserveMemoryFromExecutableAllocator(CorUnix::CPalThread* pthrCurrent, SIZE_T allocationSize);
213213

214214
#endif /* _PAL_VIRTUAL_H_ */
215215

src/pal/src/map/map.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2445,7 +2445,7 @@ void * MAPMapPEFile(HANDLE hFile)
24452445
// First try to reserve virtual memory using ExecutableAllcator. This allows all PE images to be
24462446
// near each other and close to the coreclr library which also allows the runtime to generate
24472447
// more efficient code (by avoiding usage of jump stubs).
2448-
loadedBase = ReserveMemoryFromExecutableAllocator(virtualSize);
2448+
loadedBase = ReserveMemoryFromExecutableAllocator(pThread, virtualSize);
24492449
if (loadedBase == NULL)
24502450
{
24512451
// MAC64 requires we pass MAP_SHARED (or MAP_PRIVATE) flags - otherwise, the call is failed.

src/pal/src/map/virtual.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,17 +1197,7 @@ static LPVOID VIRTUALCommitMemory(
11971197
if (allocationType != MEM_COMMIT)
11981198
{
11991199
// Commit the pages
1200-
void * pRet = MAP_FAILED;
1201-
#ifndef __APPLE__
12021200
if (mprotect((void *) StartBoundary, MemSize, PROT_WRITE | PROT_READ) == 0)
1203-
pRet = (void *)StartBoundary;
1204-
#else // __APPLE__
1205-
// Using mprotect above on MacOS is suspect to cause intermittent crashes
1206-
// https://github.com/dotnet/coreclr/issues/5672
1207-
pRet = mmap((void *) StartBoundary, MemSize, PROT_WRITE | PROT_READ,
1208-
MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);
1209-
#endif // __APPLE__
1210-
if (pRet != MAP_FAILED)
12111201
{
12121202
#if MMAP_DOESNOT_ALLOW_REMAP
12131203
SIZE_T i;
@@ -2362,9 +2352,13 @@ Function :
23622352
that is located close to the coreclr library. The memory comes from the virtual
23632353
address range that is managed by ExecutableMemoryAllocator.
23642354
--*/
2365-
void* ReserveMemoryFromExecutableAllocator(SIZE_T allocationSize)
2355+
void* ReserveMemoryFromExecutableAllocator(CPalThread* pThread, SIZE_T allocationSize)
23662356
{
2367-
return g_executableMemoryAllocator.AllocateMemory(allocationSize);
2357+
InternalEnterCriticalSection(pThread, &virtual_critsec);
2358+
void* mem = g_executableMemoryAllocator.AllocateMemory(allocationSize);
2359+
InternalLeaveCriticalSection(pThread, &virtual_critsec);
2360+
2361+
return mem;
23682362
}
23692363

23702364
/*++

0 commit comments

Comments
 (0)