[PATCH] posix: execvpe: skip $PATH components that are too long

Pádraig Brady P@draigBrady.com
Tue Nov 18 16:31:03 GMT 2025


On 18/11/2025 15:16, Zack Weinberg wrote:
> On Tue, Nov 18, 2025, at 8:27 AM, Pádraig Brady wrote:
>> Bruno Haible wrote:
>>   > Paul Eggert wrote:
>>   > > The situation for ENAMETOOLONG is the same.
>>   >
>>   > Well, in [1] I'm arguing that the situation for ENAMETOOLONG is
>>   > _not_ the same. If one ignores ENAMETOOLONG errors from earlier PATH
>>   > elements, a user's intent to hide (override) a certain program from
>>   > later PATH elements is no longer honored.
>>
>>   > One could consider this as security relevant. CCing Florian.
>>
>> In summary I don't think we should be treating ENAMETOOLONG
>> differently to how we treat EACCES or ENOTDIR.
>> If we can't access file through a path, then we should try the next one.
>>
>> There are a few cases to consider:
>>
>> 1. /many/path/file > PATH_MAX
>> 2. /path/longpath/file > NAME_MAX
>> 3. /path/longfile > NAME_MAX
> 
> I think the appropriate distinction is a little different:  I think it
> should be about whether the _directory_ or a _specific file_ is the problem.
> Concretely, suppose
> 
>     PATH = /very/long/path : /bin
> 
> (spaces for readability only)
> 
> If stat("/very/long/path") returns ENAMETOOLONG, i.e. _nothing_ in
> that directory can be accessed without hitting a length limit, then
> I do think we ought to skip that directory and go on to the next one.
> Otherwise, you could lock yourself out of all commands other than
> shell builtins by prepending an overlength directory to your PATH,
> and that could be a very confusing situation to be stuck in.
> 
> However, if stat("/very/long/path") succeeds but
> execve("/very/long/path/someprogram") returns ENAMETOOLONG, then
> I think Bruno is right and we should stop searching and return the
> error.  Again, for me this is about ease of troubleshooting.  If you
> _know_ you put a program with an unusually long name in your personal
> $HOME/.local/bin and you _know_ other programs under that directory
> do get used in preference to the system's, then having the program
> with the long name get silently ignored would also be very confusing.

That is a fair point,
but shells are the normal path executors and
testing bash/dash/kash here, they all already skip ENAMETOOLONG:

$ PATH=$(printf %256s ''):$PATH strace sh -c foo 2>&1 | grep foo
newfstatat(AT_FDCWD, "  .../foo", ...) = -1 ENAMETOOLONG
newfstatat(AT_FDCWD, "/usr/sbin/foo", ...) = -1 ENOENT
newfstatat(AT_FDCWD, "/usr/bin/foo", ...) = -1 ENOENT

Also...

> This distinction is also consistent with how we currently handle
> ENOTDIR and EACCES errors.  ENOTDIR from execve indicates a problem
> with a directory on the PATH - namely, that it isn't a directory -
> not with the specific program that's trying to be executed, so we
> skip it and go on to the next one.  EACCES errors are reported when
> the program file that can't be accessed, whether or not there's a
> usable program by the same name later in the PATH; but not when an
> entire directory is inaccessible.

EACCES _is_ reported if only a directory is not accessible:

$ mkdir eacces
$ chmod a-x eacces
$ PATH=$PWD/eacces:$PATH strace -e execve -f \
    install -s --strip-program=true /bin/true true
execve("/usr/bin/install", ["install", "-s",...) = 0
strace: Process 433035 attached
[pid 433035] execve("/home/padraig/eacces/true", ...) = -1 EACCES
[pid 433035] execve("/usr/sbin/true", ...) = -1 ENOENT
[pid 433035] execve("/usr/bin/true", ...) = 0
[pid 433035] +++ exited with 0 +++
+++ exited with 0 +++

I.e. EACCES or ENAMETOOLONG don't distinguish between dir or file.

I suppose it is slightly different in that for EACCES all files
in a certain inaccessible dir would be ignored, but for
ENAMETOOLONG (case 1 above) only some of file may be inaccessible.

I suppose you could skip only
if (errno==ENAMETOOLONG && strlen("path/file") <= PATH_MAX)
though that would be adding more complexity and inconsistency
with other path lookup implementations.

cheers,
Padraig


More information about the Libc-alpha mailing list