C 整数溢出后将大字符串复制到小缓冲区时没有SEG_错误

C 整数溢出后将大字符串复制到小缓冲区时没有SEG_错误,c,buffer-overflow,integer-overflow,C,Buffer Overflow,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; } 此程序的安全输入

我试图通过编写如下小代码来演示一个整数溢出错误及其后果:

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'`"
用于演示整数溢出的不安全输入如下所示:

./program  16  "This is a string"
./program  18446744073709551613  "`perl -e 'print "This is a very very large string "x20'`"
然而,令我惊讶的是,即使整数溢出正在发生,并且分配了一个非常小的缓冲区,程序也不会产生任何分段错误,并且程序执行良好,没有任何问题

有人能解释为什么会这样吗

我正在用GCC-5.2.1编译这篇文章,并在64位Ubuntu系统上运行


更完整的代码版本可以是。

您在这里看到的只是未定义的行为。它有时可能会工作,但实际上是随机的,在更复杂的场景中经常会失败——比如分配另一个缓冲区,然后释放它们等等


特别是在这里,C库分配更大的内存块,并根据需要将其拆分。换句话说,缓冲区后面的内存仍然存在,从操作系统的角度来看,它是有效的。但是在那里写东西迟早会损坏另一个缓冲区或其链接,并会导致错误或只是意外的内容。

未定义的行为是未定义的。它不需要做任何特别的事情,包括“撞车”。将这个问题标记为“”的副本是荒谬的!这个问题不是问我们为什么需要
malloc
,而是问:为什么将一个大字符串复制到堆上的一个小缓冲区不会导致SEG_错误。@SeyedMohammad同意它不是最好的副本,但问题是相同的。在分配的内存之外写入时,任何事情都可能发生。没有人需要给你一个seg故障。就像你在高速公路上慢跑时不一定会被车撞到一样。即使你很可能会被车撞到,你也可以把它解开。这次,谢谢。实际的问题是,我期望得到类似于“基于堆栈的溢出”的即时反馈;虽然像这样一个小而简单的程序中的“基于堆的溢出”可能永远不会产生崩溃。。。为什么?因为堆上有很多空间,并且它不会影响程序控制流(与堆栈相反),除非完成其他一些分配和释放。