summaryrefslogtreecommitdiff
path: root/src/vm/methodtablebuilder.cpp
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2019-06-18 09:07:15 +0200
committerGitHub <noreply@github.com>2019-06-18 09:07:15 +0200
commit84dc3732c6fd0f4739214eb83ffd643a33a5da17 (patch)
tree5170ba2ac10b890ca5f2a43f595eb6a6cb0487ea /src/vm/methodtablebuilder.cpp
parent2b85852af5e4e46973af07ce36c4d2f2a0e30616 (diff)
downloadcoreclr-84dc3732c6fd0f4739214eb83ffd643a33a5da17.tar.gz
coreclr-84dc3732c6fd0f4739214eb83ffd643a33a5da17.tar.bz2
coreclr-84dc3732c6fd0f4739214eb83ffd643a33a5da17.zip
Prevent loading byref-like types with invalid layout (#25200)
First approximation of a fix for #25057. This has two problems: * We're checking for any byref-like typed fields. Types that don't actually contain interior pointers but were marked as `ref struct` will fail to load when not aligned properly. * We're not doing the deep validation that we do for reference types to make sure the `ByReference<T>` field doesn't overlap with another non-byreference field. Question is whether we're okay with those limitations, or whether we need a better fix. Better fix would likely entail inefficiently walking over the fields à la `FindByRefPointerOffsetsInByRefLikeObject` (doing the more efficient thing that we do for object references below would require a GCDesc representation of byrefness). Contributes to #25057.
Diffstat (limited to 'src/vm/methodtablebuilder.cpp')
-rw-r--r--src/vm/methodtablebuilder.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index bec874ef45..f5038138f1 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -8397,6 +8397,16 @@ MethodTableBuilder::HandleExplicitLayout(
if (pFD->IsByValue())
{
MethodTable *pByValueMT = pByValueClassCache[valueClassCacheIndex];
+ if (pByValueMT->IsByRefLike())
+ {
+ if ((pFD->GetOffset_NoLogging() & ((ULONG)TARGET_POINTER_SIZE - 1)) != 0)
+ {
+ // If we got here, then a byref-like valuetype was misaligned.
+ badOffset = pFD->GetOffset_NoLogging();
+ fieldTrust.SetTrust(ExplicitFieldTrust::kNone);
+ break;
+ }
+ }
if (pByValueMT->ContainsPointers())
{
if ((pFD->GetOffset_NoLogging() & ((ULONG)TARGET_POINTER_SIZE - 1)) == 0)