Skip to content

Commit

Permalink
Fix VTableCallHolder writeable mapping size with W^X (#70093)
Browse files Browse the repository at this point in the history
The size of this holder is dynamic, but when we are creating the writeable
mapping of this holder to initialize its code, we don't take that into account.
So in case the holder is located at the end of a memory page and crosses its
boundary, the writeable mapping covers only the beginning of the holder and
so we either crash during the initialization if the following memory page is
not mapped or read only, or we corrupt a completely unrelated memory page
in case it is mapped and writeable.

The fix is to use the real size of the holder instead of sizeof(...).
  • Loading branch information
janvorli authored Jun 1, 2022
1 parent 5772d54 commit 9d84900
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/coreclr/vm/virtualcallstub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,8 +1179,9 @@ VTableCallHolder* VirtualCallStubManager::GenerateVTableCallStub(DWORD slot)
} CONTRACT_END;

//allocate from the requisite heap and copy the template over it.
VTableCallHolder * pHolder = (VTableCallHolder*)(void*)vtable_heap->AllocAlignedMem(VTableCallHolder::GetHolderSize(slot), CODE_SIZE_ALIGN);
ExecutableWriterHolder<VTableCallHolder> vtableWriterHolder(pHolder, sizeof(VTableCallHolder));
size_t vtableHolderSize = VTableCallHolder::GetHolderSize(slot);
VTableCallHolder * pHolder = (VTableCallHolder*)(void*)vtable_heap->AllocAlignedMem(vtableHolderSize, CODE_SIZE_ALIGN);
ExecutableWriterHolder<VTableCallHolder> vtableWriterHolder(pHolder, vtableHolderSize);
vtableWriterHolder.GetRW()->Initialize(slot);

ClrFlushInstructionCache(pHolder->stub(), pHolder->stub()->size());
Expand Down

0 comments on commit 9d84900

Please sign in to comment.