整数溢出后将大字符串复制到小缓冲区时没有 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 的角度来看它是有效的。但是在那里写入迟早会损坏另一个缓冲区或其链接,并且会导致错误或只是意外的内容。