Why is a fixed size buffers (arrays) must be unsafe?

brickner picture brickner · May 21, 2010 · Viewed 7.5k times · Source

Let's say I want to have a value type of 7 bytes (or 3 or 777).

I can define it like that:

public struct Buffer71
{
    public byte b0;
    public byte b1;
    public byte b2;
    public byte b3;
    public byte b4;
    public byte b5;
    public byte b6;
}

A simpler way to define it is using a fixed buffer

public struct Buffer72
{
    public unsafe fixed byte bs[7];
}

Of course the second definition is simpler. The problem lies with the unsafe keyword that must be provided for fixed buffers. I understand that this is implemented using pointers and hence unsafe.

My question is why does it have to be unsafe? Why can't C# provide arbitrary constant length arrays and keep them as a value type instead of making it a C# reference type array or unsafe buffers?

Answer

Hans Passant picture Hans Passant · May 21, 2010

Because a "fixed buffer" is not a real array. It is a custom value type, about the only way to generate one in the C# language that I know. There is no way for the CLR to verify that indexing of the array is done in a safe way. The code is not verifiable either. The most graphic demonstration of this:

using System;

class Program {
    static unsafe void Main(string[] args) {
        var buf = new Buffer72();
        Console.WriteLine(buf.bs[8]);
        Console.ReadLine();
    }
}
public struct Buffer72 {
    public unsafe fixed byte bs[7];
}

You can arbitrarily access the stack frame in this example. The standard buffer overflow injection technique would be available to malicious code to patch the function return address and force your code to jump to an arbitrary location.

Yes, that's quite unsafe.