Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Prevent loading byref-like types with invalid layout (#7584)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky authored Jul 3, 2019
1 parent 050ad73 commit d6f1d52
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataTy

foreach (var fieldAndOffset in layoutMetadata.Offsets)
{
var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);
TypeDesc fieldType = fieldAndOffset.Field.FieldType;
var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, packingSize);

largestAlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequired);

Expand All @@ -324,12 +325,13 @@ private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataTy

LayoutInt computedOffset = fieldAndOffset.Offset + cumulativeInstanceFieldPos;

if (fieldAndOffset.Field.FieldType.IsGCPointer && !computedOffset.IsIndeterminate)
// GC pointers MUST be aligned.
// We treat byref-like structs as GC pointers too.
if (!computedOffset.IsIndeterminate && (fieldType.IsGCPointer || fieldType.IsByRefLike))
{
int offsetModulo = computedOffset.AsInt % type.Context.Target.PointerSize;
if (offsetModulo != 0)
{
// GC pointers MUST be aligned.
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadExplicitLayout, type, fieldAndOffset.Offset.ToStringInvariant());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ public class ExplicitEmptyClass
public struct ExplicitEmptyStruct
{
}

[StructLayout(LayoutKind.Explicit)]
ref struct MisalignedPointer
{
[FieldOffset(2)]
public object O;
}

[StructLayout(LayoutKind.Explicit)]
ref struct MisalignedByRef
{
[FieldOffset(2)]
public ByRefStruct O;
}

ref struct ByRefStruct
{
}
}

namespace Sequential
Expand Down
14 changes: 14 additions & 0 deletions src/ILCompiler.TypeSystem/tests/InstanceFieldLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ public void TestExplicitTypeLayoutWithInheritance()
}
}

[Fact]
public void TestInvalidExplicitTypeLayout()
{
{
DefType type = _testModule.GetType("Explicit", "MisalignedPointer");
Assert.Throws<TypeSystemException.TypeLoadException>(() => type.ComputeInstanceLayout(InstanceLayoutKind.TypeAndFields));
}

{
DefType type = _testModule.GetType("Explicit", "MisalignedByRef");
Assert.Throws<TypeSystemException.TypeLoadException>(() => type.ComputeInstanceLayout(InstanceLayoutKind.TypeAndFields));
}
}

[Fact]
public void TestSequentialTypeLayout()
{
Expand Down

0 comments on commit d6f1d52

Please sign in to comment.