Skip to content

Shouldn't allow randomly placing ByRef-like fields #12842

Closed
@MichalStrehovsky

Description

@MichalStrehovsky

We should probably prevent loading types that attempt to place byref-like fields at addresses that are not divisible by pointer size.

[StructLayout(LayoutKind.Explicit)]
ref struct RefStruct
{
    [FieldOffset(0)]
    public short X;
    [FieldOffset(2)]
    public Span<int> Y;
}

class Program
{
    static RefStruct GetRefStruct()
    {
        return new RefStruct { Y = new int[1] { 42 } };
    }

    static void Collect()
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }

    static void Main()
    {
        for (int i = 0; i < 1000; i++)
            GC.KeepAlive(new int[8]);
        RefStruct a = GetRefStruct();
        a.X = 1234;
        for (int i = 0; i < 1000; i++)
            GC.KeepAlive(new int[8]);

        Collect();
        Console.WriteLine(a.X);
        Console.WriteLine(a.Y[0]);
    }
}

This will print 1234/0 instead of 1234/42 (that gets printed if you remove the StructLayout(Explicit)).

Found while messing around with dotnet/coreclr#25056.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions