如果整数溢出,结果是(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。
这里的问题不是功能有多糟糕,或者如何改进功能以使其更好。该功能无疑存在漏洞。问题是关于函数的确切行为,基于标准中规定的行为。