如果整数溢出,结果是(unsigned int) * (int)
什么?unsigned
还是int
?数组索引运算符 ( operator[]
) 对char*
:int
或unsigned int
其他东西采用什么类型?
我正在审计下面的函数,突然出现了这个问题。该函数在第 17 行有一个漏洞。
// Create a character array and initialize it with init[]
// repeatedly. The size of this character array is specified by
// w*h.
char *function4(unsigned int w, unsigned int h, char *init)
{
char *buf;
int i;
if (w*h > 4096)
return (NULL);
buf = (char *)malloc(4096+1);
if (!buf)
return (NULL);
for (i=0; i<h; i++)
memcpy(&buf[i*w], init, w); // line 17
buf[4096] = '\0';
return buf;
}
考虑两者w
和h
都是非常大的无符号整数。第 9 行的乘法有机会通过验证。
int i
现在问题出现在第 17 行。乘以unsigned int w
:如果结果是int
,则乘积可能是负数,导致访问的位置是 before buf
。如果结果为unsigned int
,则乘积将始终为正,从而访问位于 之后的位置buf
。
很难编写代码来证明这一点:int
太大。有人对此有想法吗?
是否有任何文件说明产品的类型?我已经搜索过了,但到目前为止还没有找到任何东西。
我想就漏洞而言,是否(unsigned int) * (int)
产生unsigned int
或int
无关紧要,因为在编译的目标文件中,它们只是字节。无论产品类型如何,以下代码的工作方式都相同:
unsigned int x = 10;
int y = -10;
printf("%d\n", x * y); // print x * y in signed integer
printf("%u\n", x * y); // print x * y in unsigned integer
因此,乘法返回什么类型并不重要。消费者功能是否采用int
或很重要unsigned
。
这里的问题不是功能有多糟糕,或者如何改进功能以使其更好。该功能无疑存在漏洞。问题是关于函数的确切行为,基于标准中规定的行为。