Can argc overflow?

I wandered around in SO and saw this question . Then I started to wonder if I could overrun argc.

The standard says that argv[argc] should be a null pointer, but that will be false if the overflow is argc.

(I wrote a small C program and a python script for testing, but got a MemoryError .)

Thank!




Justification for an international standard - Programming languages ​​- C §5.1.2.2.1 Starting a program

The specification of argc and argv as arguments to main recognizes extensive practice. argv[argc] is required to be a null pointer to provide redundant validation for the end of the list, also based on common practice.

+75
c integer-overflow
Jan 21 '15 at 19:32
source share
4 answers

According to standard

So from your quote:

argv[argc] is required to be a null pointer

Therefore, argc cannot overflow because the above statement will not be true.

On practice

In practice, the total size of the arguments passed to the program is limited.

On my Linux / x64 system:

 $ getconf ARG_MAX
 2097152

Consequently, the total size of the argument is about 2 megabytes, and argc cannot overflow. I believe this limit measures the combination of shared data in argv and the environment. If you exceed this limit when you try to execute a command, exec() will fail with an E2BIG error. From man 2 execve :

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

I believe that the 2 megabyte limit on my system is relatively large compared to other systems. My OS X system reports a limit of ~ 260KB.

But what if ARG_MAX were really big?

Well, suppose you are in an old / strange system, so int is 16 bits and ARG_MAX is more than 2 15 which is otherwise quite reasonable. Suppose you call execve() with more than two arguments 15 . Implementation has two options.

  • This may allow argc overflow ... basically, discarding your data, ensuring that the program you are running is executed in some unexpected and probably erroneous, and violates the C standard. Worst of all, the error is silent, so you never know.

  • Or it can simply return EOVERFLOW from execve() , telling you that it simply cannot start the image with so many parameters. Now the POSIX / SUS standards do not mention anything about this error result ... but I suspect that this is simply because standard authors never expected ARG_MAX be larger than INT_MAX .

Option No. 2 is the only reasonable option. If your system somehow chooses option number 1, then it is broken, and you should file a bug report.

Alternatively, you can try to run an old program compiled for a 16-bit system, but you run it through some kind of emulator or compatibility level. I expected that the emulator or compatibility level will give an error message if you try to pass more than 2 parameters to the program 15 .

+78
Jan 21 '15 at 19:38
source share

In practice, no, you cannot. Most systems set a relatively low limit on the total size of argv and envp . Limits of tens to low hundreds of KB are not uncommon; see http://www.in-ulm.de/~mascheck/various/argmax/ for a fairly complete listing of restrictions on various OSs.

+17
Jan 21 '15 at 19:38
source share

I tried this:

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; } 

Then used a large zipfile

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

Then read the file as parameters for the test program:

 ⚡⚡⚡ ./test $(more bigfile) 

Result:

 5 minutes nothing happend, then everything froze 

Then I tried a smaller file:

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

AND:

  ⚡⚡⚡ ./test $(more notsobigfile) bash: ./test: Argument list too long 
+10
Jan 22 '15 at 15:07
source share

As specified by the standard, argv [argc] must be a valid value.

So, if the runtime is in such a situation that it cannot guarantee this, it should not run the program.

+2
Jan 28 '15 at 14:12
source share



All Articles