7
Catching Integer Overflows in C Note: This document and the macros make two important assumptions: 1. There are 8 bits in a char. This is not guaranteed by the C standard, and is in fact not true on all platforms, most notably some ancient mainframes. You could work around this with CHAR_BIT from limits.h, if you really cared. 2. The integers use two's complement. This is also not guaranteed by the C standard, but you will be hard pressed to find a platform where it is not true. Integer Overflows are arithmetic errors. Integers have finite ranges in computers, for example a 32-bit unsigned integer goes from 0 to 0xffffffff. If you add one to 0xffffffff, you get 0 again. Since the addition operation in the CPU is agnostic to whether the integer is signed or unsigned, the same goes for signed integers. For 32-bit signed integers, the minimum value is 0x80000000 (-2147483648) and the maximum value is 0x7fffffff (2147483647). Note that there is no value than can hold 2147483648, so if you negate (int)0x80000000, you get (int)0x80000000 again. That is something to look out for, because it means abs() returns a negative value when fed -2147483648. So, if you want to add two integers a and b (b >= 0), the easiest way to find out if that overflows is to check whether a+b<a (or b; some people think you have to check against min(a,b), but that is unnecessary). Issue 1: abs(-2147483648) < 0 The abs function returns the argument if it is positive, or the negated argument if it is negative. Unfortunately, -(-2147483648) is still -2147483648 (on a 32-bit platform). So don't rely on abs() on untrusted data to return a non-negative number!

Catching Integer Overflows in C

Embed Size (px)

DESCRIPTION

C language

Citation preview

Catching Integer Overflows in CNote: This document and the macros make two important assumptions: 1. There are 8 bits in a char. This is not guaranteed by the C standard, and is in fact not true on all platforms, most notably some ancient mainframes. You could work around this with CHAR_BIT from limits.h, if you really cared. 2. The integers use two's complement. This is also not guaranteed by the C standard, but you will be hard pressed to find a platform where it is not true. Integer Overflows are arithmetic errors. Integers have finite ranges in computers, for example a 32-bit unsigned integer goes from 0 to 0xffffffff. If you add one to 0xffffffff, you get 0 again.Since the addition operation in the CPU is agnostic to whether the integer is signed or unsigned, the same goes for signed integers. For 32-bit signed integers, the minimum value is 0x80000000 (-2147483648) and the maximum value is 0x7fffffff (2147483647). Note that there is no value than can hold 2147483648, so if you negate (int)0x80000000, you get (int)0x80000000 again. That is something to look out for, because it means abs() returns a negative value when fed -2147483648.So, if you want to add two integers a and b (b >= 0), the easiest way to find out if that overflows is to check whether a+b64 multiplication we just used to check for overflow for 32-bit numbers. This is shifted by 32 bits, so we have an overflow if the upper half of it is nonzero. Since we already know that either a1 or b1 is zero, we can simply calculate a=(uint64_t)(a1)*b0+(uint64_t)(a0)*b1;At least one half of this term will be zero, so we can't have an overflow in the addition. Then, if a > 0xffffffff, we have an overflow in the multiplication and can abort. If we got this far, the result is (a