我试图通过编写如下的小代码来演示整数溢出错误及其后果:
int main(int argc, char** argv)
{
size_t len = 0;
sscanf (argv[1], "%lu", &len);
char* buffer = malloc(len + 5);
strcpy (buffer, argv[2]);
printf("str = \'%s\'\n", buffer)
return 0;
}
此程序的安全输入如下:
./program 16 "This is a string"
演示整数溢出的不安全输入是这样的:
./program 18446744073709551613 "`perl -e 'print "This is a very very large string "x20'`"
令我惊讶的是,即使整数溢出正在发生并且正在分配一个非常小的缓冲区,程序也不会产生任何SEGMENTATION FAULT,并且程序执行正常而没有任何问题到最后!
有人可以解释为什么会这样吗?
我正在用GCC-5.2.1
编译它并在64位Ubuntu系统上运行。
更完整的代码版本可以是viewed here。
答案 0 :(得分:2)
您在这里看到的只是未定义的行为。它可能会起作用,但实际上是随机的,并且通常会在更复杂的情况下失败 - 比如分配另一个缓冲区,然后将它们释放出来等等。
具体来说,C库分配更大的内存块并根据需求进行拆分。换句话说,缓冲区后面的内存仍然存在,从OS的角度来看它是有效的。但是写在那里迟早会损坏另一个缓冲区或它的链接并导致错误或只是意外的内容。