整数溢出后将大字符串复制到小缓冲区时没有 SEG_FAULT
No SEG_FAULT when copying large string to small buffer after integer overflow
我正在尝试通过编写如下小代码来演示整数溢出错误及其后果:
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'`"
但令我惊讶的是,即使发生了整数溢出并且分配了一个非常小的缓冲区,程序也没有产生任何分段错误并且程序执行正常,没有任何问题到最后!
谁能解释这是为什么?
我正在 64 位 Ubuntu 系统上使用 GCC-5.2.1
和 运行 编译它。
更完整的代码版本可以是viewed here.
您在这里看到的只是未定义的行为。它有时可能会工作,但实际上是随机的,并且经常会在更复杂的情况下失败——比如分配另一个缓冲区,然后释放它们等等。
具体来说,这里的C库分配了更大的内存块,并根据需要进行分割。换句话说,缓冲区后面的内存仍然存在,并且从 OS 的角度来看它是有效的。但是在那里写入迟早会损坏另一个缓冲区或其链接,并且会导致错误或只是意外的内容。
我正在尝试通过编写如下小代码来演示整数溢出错误及其后果:
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'`"
但令我惊讶的是,即使发生了整数溢出并且分配了一个非常小的缓冲区,程序也没有产生任何分段错误并且程序执行正常,没有任何问题到最后!
谁能解释这是为什么?
我正在 64 位 Ubuntu 系统上使用 GCC-5.2.1
和 运行 编译它。
更完整的代码版本可以是viewed here.
您在这里看到的只是未定义的行为。它有时可能会工作,但实际上是随机的,并且经常会在更复杂的情况下失败——比如分配另一个缓冲区,然后释放它们等等。
具体来说,这里的C库分配了更大的内存块,并根据需要进行分割。换句话说,缓冲区后面的内存仍然存在,并且从 OS 的角度来看它是有效的。但是在那里写入迟早会损坏另一个缓冲区或其链接,并且会导致错误或只是意外的内容。