.NET Numeric Overflow

Posted by on July 27, 2011

When programming with Microsoft .Net, there is not as much concern for overflow vulnerabilities.  With the managed runtime, buffer overflows are handled for the most part.  However, there is still the possibility for numeric overflows.  A numeric overflow exists when arithmetic is performed on two values causing the result to roll past the max or min of the specified data type giving an unexpected result. 

For example, say that you are adding two “Short” values together.  A short is an unsigned value ranging from (–32767) – 32767.  Lets look at the following operations:

32767 + 5 = 32772

This simple math operation creates what appears to be a valid, expected result.  However, a “short” cannot contain a value that high.  So what really happens when we try to add these values together as 2 “shorts” being stored in a “short”?

32767 + 5 = -32764

Notice how the result is now at the opposite spectrum from what was expected.  This happens because the most significant bit is saved for the sign.  When we add these numbers together using binary form (which the computer uses) the carry over changes the sign and the overall value.

This could cause a big problem in an ecommerce type of site where price and tax are added together as one example.  The user modifies the price so that when the tax is added, the total rolls over (like a odometer in our car) and now the customer has a credit in stead of a debit.

The following code snippet shows a few different ways that .Net handles numeric overflows.  “Shorts” are used but this applies to other numeric types as well.  I will discuss each of these techniques below.

  1: short x = short.MaxValue;   // 32767
  2: short y = 5;
  3: short z;
  5: z = x + y;  // Design Time Error!!
  7: z = (short)(x + y);  // -32764
  9: z = checked((short)(x + y));   // OverFlowException
 11: checked
 12: {
 13:    z = (short)(x + y);  // OverFlowException
 14: }
 16: unchecked
 17: {
 18:    z = (short)(x + y);  // -32764
 19: }
 21: y += x;    // -32764

Line 5 – This code will cause a design time error so it will be caught before you can successfully build your application.  The reason this causes an error is that the (+) operator for two shorts is overridden to return an “int”.  This would make sense that the two values could be greater than the max value of a “short” and to protect itself, the framework upgrades to an “int”.  If z had been declared as an “int” this would not cause a problem.

Line 7 – To remediate the design time error, this example casts the result to a “short”.  However, as shown in the comment, the value overflows and the result is not what is expected by the developer. 

Line 9 – This example builds upon the last example, but wraps the operation in the “checked” method.  The “checked” method will check to see if the operation overflows the result and if so, throws an OverflowException.

Lines 11-14 – This is the same concept as the last example, but uses a “checked” block instead of the method.  This is useful if there are multiple operations that need to be performed near each other.  It will also throw the OverflowException.

Lines 16-19 – Here we are going to tell the runtime we do not want to check the values.  This will not throw an exception and the result could be different that what is expected.

Line 21 – Finally, this example shows how the different operations have different results.  We saw in the first example in Line 5 that the + operator returned an “int” datatype.  When using the “+=” combination, the return value is of the original type.  So in this instance, it will return a short.  Notice this will not throw a design time error or the runtime error.  It is susceptible to overflow and could lead to an unexpected return value. 

These are very simple examples to demonstrate what numeric overflows are in .Net, how they can present themselves, and what methods .Net provides to help protect against them.  These are just examples and are not meant to be used for production environments.  Use this information at your own risk.


Comments are closed.