August 23, 2015

Fully Managed C# Can Corrupt Memory

In this post I'm writing about memory corruption in fully managed C# code. On the internet, many people advocate that managed C# should be immune against memory corruption. Even reputable organizations mention the same but provide no reference so people can't check the source of the information for themselves.

The fact is, Microsoft don't explicitly claim whether or not managed C# should introduce memory corruption in your app.

Input Sanitization

The materials made by Microsoft mentions the importance of sanitizing input values in managed code. This also means that things can go wrong if you just pass untrusted values to framework APIs.

AccessViolationException

.NET Framework has the AccessViolationException exception class for accessing protected memory. The description says:
An access violation occurs in unmanaged or unsafe code when it attempts to read or write to memory that has not been allocated, or to which it does not have access.
This is quite true, however, AccessViolationException can be originated from fully managed code, too.

In the past months, I was doing some C# development, and during the testing, I experienced several times that my app had terminated with the sign of memory corruption:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
It looks this error is commonly seen in the search result.

Memory Corruption

I did a bit of research on this topic, and wrote a simplified testcase for one of such corruption. I sent it to the people at MSRC. When they finished their investigation I received a reply from them:
We have successfully reproduced the issue and can confirm that the memory corruption is happening within the application itself and not the system.  As such, this does not appear to be a security issue and I will be closing this case.
The statement above is a bit vague but this is my understanding of what it means.

If there is a C# API that's designed to handle untrusted data (such as a decompression API) and there is a memory corruption bug in the way the API handles the data the bug may be a security issue, and so it has to be fixed by Microsoft.

However, if the bug is triggered due to an erroneous use of the C# API, such as a non-sanitized parameter is supplied, then the bug is considered to be fixed in the application.

Whether the bug is in the system or application you can end up corrupting the memory in the process so it can affect the security of your app. Despite this the bug may not be qualified for a fix in the .NET framework.

.NET framework manages the memory to eliminate the memory problems but this doesn't guarantee that it eliminates all the memory problems. Memory corruption in fully managed C# is possible.

Testcase

The testcase is a Visual Studio 2013 project that reproduces the memory corruption on Windows Phone 8.1 device and Windows Phone 8.1 Emulator.

The testcase creates an array of pixels with the use of IRandomAccessStream, BitmapEncoder and Stream. When checksumming the bytes in the array the checksum changes every time the vulnerability is triggered.

Checksumming is simple like this (the idea is borrowed from one of the public Flash infoleak made by Chris Evans).

            int checksum = 0;
            foreach (byte i in arr)
            {
                checksum += arr[i];
            }

Sometimes the testcase crashes with AccessViolationException but most of the time it's observed that the app continues to run after the memory corruption.

  This blog is written and maintained by Attila Suszter. Read in Feed Reader.