9.6.4 整数溢出攻击

计算机进行定长整型数的运算,整型数的长度一般有8位、16位、32位和64位。如果相加或相乘的结果超过了整型数可以表示的最大值,就称溢出发生了。C程序并不会捕捉这个错误,而是会将错误的结果存储下来并继续使用。一种特别的情况是,当变量为有符号整数时,两个整数相加或想成的结果可能因为溢出而成为负数。如果变量是无符号整数,溢出的结果依然是整数,不过会围绕0和最大值进行循环(wrap around)。例如,两个16位无符号整数的值都是40 000,如果将其相乘的结果存入另一个一个16位的无符号整型变量中,其结果将会是4096。

由于这种溢出不会被检测,因此可能被用作攻击的手段。一种方式就是给程序传入两个合法的(但是非常大)的参数,它们的和或乘积将导致溢出。例如,一些图形程序要求通过命令行传入图像文件的高和宽,以便对输入的图像进行大小转换。如果传入的高度和宽度会导致面积的“溢出”,程序就会错误地计算存储图像所需要的内存空间,从而可能申请一块比实际小得多的内存。至此缓冲区溢出攻击的时机已经成熟。对于有符号整型数,也可以采用相似的办法进行攻击。