|
|
||
If the input is character strings, try feeding the application sizes that tend to cause errors. For example, strings that are 64K or 64K1 bytes long can often cause problems. Other common problem lengths are 127, 128, and 255, as well as just on either side of 32K. Any time that adding one to a number results in either changing sign or flipping back to zero, you have a good test case.
In the cases where youre allowed to feed the
programmer numbers directlyone example would be
a structured documenttry making the
|
|
||
A search on integer overflow in SecurityFocus vulnerabilities list yields more than 50 hits and the Common Vulnerabilities and Exposures (CVE) database yields 65 entries as of this writing. Heres a few:
From the CVE (CAN-2003-0010) description:
Integer overflow in JsArrayFunctionHeapSort function used by Windows Script Engine for JScript (JScript.dll) on various Windows operating system allows remote
attackers to execute arbitrary code via a malicious web page or HTML e-mail that uses a large array index value that enables a heap-based buffer overflow attack.
The interesting thing about this overflow is that it allows for arbitrary code execution by a scripting language that doesnt allow for direct memory access. The Microsoft bulletin can be found at www.microsoft.com/technet/security/bulletin/MS03-008.mspx.
Another scripting language attack, CVE entry CAN-2004-0722, is more thoroughly described on the Red Hat Linux web site (www.redhat.com) as:
Zen Parse
reported improper input validation to the SOAPParameter object constructor leading to an integer overflow and controllable heap corruption. Malicious JavaScript could be written to utilize this flaw and could allow
arbitrary code execution.
In the same report, the following was also detailed:
During a source code audit, Chris Evans
discovered a buffer overflow and integer overflows, which affect the libpng code inside Mozilla. An attacker could create acarefully crafted PNG file in such a way that it would cause Mozilla to crash or execute arbitrary code when the image wasviewed .
Shortly after this problem was announced in June, 2002,
widespread attacks were seen against affected IIS servers. More
details can be found at www.microsoft.com/
technet/security/Bulletin/MS02-028.mspx, but the root cause was
because the HTR handler accepted a length of 64K
-
1 from the
|
|
||
Redemption from integer overflows can only truly be had by
Avoid clever codemake your checks for integer problems straightforward and easy to understand. Heres an example of a check for addition overflows that was too smart by half:
int a, b, c; c = a + b; if(a ^ b ^c < 0) return BAD_INPUT;
This test suffers from a lot of problems. Many of us need a few minutes to figure out just what it is trying to do, and then it also has a problem with false positives and false
int a, b, c; c = a * b; if(c < 0) return BAD_INPUT;
Even allowing for positive inputs to start with, the code only checks for some overflowsconsider (2^30 + 1) * 8; thats 2^33 + 8and once truncated back to 32-bit, it yields 8, which is both incorrect and not negative. A safer way to do the same thing is to store a 32-bit multiplication in a 64-bit number, and then check to see if the high order bits are set, indicating an overflow.
For code like this:
unsigned a,b;
...
if (a * b < MAX) {
...
}
you could simply bound the a and b
#include "limits.h"
#define MAX_A 10000
#define MAX_B 250
assert(UINT_MAX / MAX_A >= MAX_B); // check that MAX_A and MAX_B are small enough
if (a < MAX_A && b < MAX_B) {
...
}
If youd like to thoroughly
size_t CalcAllocSize(int HowMany, int Size, int HeaderLen)
{
try{
SafeInt<size_t> tmp(HowMany);
return tmp * Size + SafeInt<size_t>(HeaderLen);
}
catch(SafeIntException)
{
return (size_t)~0;
}
}
Signed integers are used as an input for illustrationthis function should be written exclusively with the size_t type. Lets take a look at what happens under the covers. The first is that the value of HowMany is checked to see if it is negative. Trying to assign a negative value to an unsigned SafeInt throws an exception. Next, operator precedence causes you to multiply a SafeInt by Size, which is an int, and will be checked both for overflow and valid range. The result of SafeInt * int is another SafeInt, so you now perform a checked addition. Note that you need to change the incoming int to a SafeInt, because a negative header length would be valid math but doesnt make sensesizes are best represented as unsigned numbers. Finally, in the return, the SafeInt<size_t> is cast back to a size_t, which is a no-op. Theres a lot of complex checking going on, but your code is simple and easy to read.
If youre programming with C#, compile with /checked, and use unchecked statements to exempt individual lines from checking.