execvpe limits PATH environment variable to PATH_MAX

Adhemerval Zanella adhemerval.zanella@linaro.org
Tue Mar 31 12:15:03 GMT 2020



On 31/03/2020 00:56, DJ Delorie wrote:
> 
> Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org> writes:
>> And I don't think it would be a good practice to use a different
>> semantic for execvpe, i.e, allow arbitrary size paths.
> 
> Does the standard allow arbitrary sized environment strings?  If so, we
> should not limit our implementation. (it doesn't but it doesn't limit
> $PATH to PATH_MAX either)
> 
> Also, PATH_MAX has nothing to do with environment strings - it's the
> maximum size of a filesystem pathname.  Let's not abuse it.
> 
> If anything, we should use ARG_MAX [1][2].  I will note that PATH_MAX is
> 4,096 on my system, but ARG_MAX is 131,072.  That might break alloca.

The problem with ARG_MAX is it might not represent what underlying system
actually support.  Linux, for instance, check the total of argv and
envp to a limit of MAX_ARG_STRINGS (0x7FFFFFFF) and then check the to
resulting size against 1/4 of the max stack size or 3/4 of RLIMIT_STACK.
So I don't think ARG_MAX represents the path limit.

The pathname limit on Linux is related to the underlying filesystem, so
glibc either need to impose no limit or add an large artificial one
(and I don't think adding a extra stat call to obtain the _PC_PATH_MAX
and _PC_NAME_MAX it worth here). And the problem with former is how to
allocate the required buffer in a safer and scalable manner. 

I really would like to avoid an unbounded stack allocation and with
the async-signal-safe restriction it is tricky to get a representable
value.  One option might to increase to the artificial value to something
close to 32768, since it is what posix_spawn uses as an auxiliary
stack for the execvpe/execve call (value which was increase so
posix_spawn could work with gcc stack check).

> 
> [E2BIG]
>   The number of bytes used by the new process image's argument list and
>   environment list is greater than the system-imposed limit of {ARG_MAX}
>   bytes.
> 
> The only mention of PATH_MAX in exec*() is
> 
> [ENAMETOOLONG]
>   The length of the path argument or the length of the pathname
>   constructed from the file argument exceeds {PATH_MAX}, or pathname
>   resolution of a symbolic link produced an intermediate result with a
>   length that exceeds {PATH_MAX}.
> 
> ... which only refers to the pathname to the image to be exec'd, not the
> arguments or environment.
>   
> [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
> 
> [2] https://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
> {ARG_MAX}
>   Maximum length of argument to the exec functions including environment
>   data.  Minimum Acceptable Value: {_POSIX_ARG_MAX}
> 


More information about the Libc-alpha mailing list