argc可以溢出吗?

时间:2015-01-21 19:32:06

标签: c integer-overflow

我在SO中徘徊,看到了this question。然后我开始想知道我是否可以溢出argc。

标准表示argv[argc]必须是空指针,但如果argc溢出则为false。

(我wrote一个小C程序和一个python脚本来测试它但得到了MemoryError。)

谢谢!


  

Rationale for International Standard — Programming Languages — C§5.1.2.2.1程序启动

     

作为argc的参数的argvmain的规范认可了广泛的先前实践。 argv[argc]必须是一个空指针,以便在列表末尾提供冗余检查,同样基于通常的做法。

4 个答案:

答案 0 :(得分:78)

根据标准

所以,从你的引用:

  

argv[argc]必须是空指针

因此,argc不能溢出,因为上面的陈述不会是真的。

在实践中

实际上,传递给程序的参数的总大小是有限的。

在我的Linux / x64系统上:

$ getconf ARG_MAX
2097152

因此,总参数大小约为2兆字节,argc不能溢出。我认为此限制衡量的是argv中的总数据与环境的组合。如果在尝试运行命令时超出此限制,exec()将失败并显示E2BIG。来自man 2 execve

E2BIG  The total number of bytes in the environment (envp) and argument
       list (argv) is too large.

我认为与其他系统相比,我系统的~2兆字节限制相对慷慨。我的OS X系统报告的限制为~260KB。

但如果ARG_MAX真的很大怎么办?

好吧,我们假设您使用的是旧的/奇怪的系统,因此int为16位,ARG_MAX远远超过2 15 ,否则非常合理。现在,假设您使用超过2个 15 参数调用execve()。实施有两个选择。

  1. 它可以允许argc溢出...基本上,丢弃您的数据,确保您正在运行的程序以某种意外的,可能是错误的方式执行,并违反C标准。最糟糕的是,错误是沉默的,所以你可能永远不会知道。

  2. 或者,它只能从EOVERFLOW返回execve(),告知您它无法运行包含那么多参数的图像。现在,POSIX / SUS标准没有提到有关此错误结果的任何内容......但是,我怀疑这只是因为标准编写者从未期望ARG_MAX大于INT_MAX

  3. 选项#2是唯一的合理选项。如果您的系统以某种方式选择选项#1,那么已损坏并且您应该提交错误报告。

    或者,您可能尝试运行为16位系统编译的旧程序,但是您通过某种仿真器或兼容层运行它。如果您尝试将超过2个 15 参数传递给程序,我希望仿真器或兼容性层会给出错误消息。

答案 1 :(得分:17)

在实践中,不,你不能。大多数系统对argvenvp的总组合大小设置相对较低的限制。数十至数百KB的限制并不罕见;请参阅http://www.in-ulm.de/~mascheck/various/argmax/,了解各种操作系统限制的相当全面的列表。

答案 2 :(得分:10)

我试过了:

test.c:

 ⚡⚡⚡  more test.c 
#include <stdio.h>
int main(int argc, char **argv)
{
    printf("argc = %d\n", argc);
    printf("Size of argc = %d\n", sizeof(argc));
    return 0;
}

然后使用了一个大的zipfile

 ⚡⚡⚡  ls -h bigfile 
-rw-r--r-- 1 ehwas ehwas 355M Jan 22 16:54 bigfile

然后将该文件作为测试程序的参数读取:

⚡⚡⚡  ./test $(more bigfile)

结果:

5 minutes nothing happend, then everything froze

然后我尝试了一个较小的文件:

 ⚡⚡⚡  ls -h notsobigfile 
-rw-r--r-- 1 ehwas ehwas 6.7M Jan 22 17:04 notsobigfile

并且:

 ⚡⚡⚡  ./test $(more notsobigfile)
bash: ./test: Argument list too long

答案 3 :(得分:2)

如标准所示,argv [argc]必须是有效值。

因此,如果运行时环境处于无法保证的状态,则不应启动该程序。