GNU bug report logs - #54587
chroot: incorrectly reporting "<command>: no such file or directory"

Previous Next

Package: coreutils;

Reported by: Kyle Glaws <kyle.glaws <at> gmail.com>

Date: Sat, 26 Mar 2022 21:27:02 UTC

Severity: normal

To reply to this bug, email your comments to 54587 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#54587; Package coreutils. (Sat, 26 Mar 2022 21:27:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Kyle Glaws <kyle.glaws <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Sat, 26 Mar 2022 21:27:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Kyle Glaws <kyle.glaws <at> gmail.com>
To: bug-coreutils <at> gnu.org
Subject: chroot: incorrectly reporting "<command>: no such file or directory"
Date: Sat, 26 Mar 2022 17:16:04 -0400
[Message part 1 (text/plain, inline)]
Hello,
I have encountered an issue with chroot (from Coreutils version 9.0), but I
think this email might fall more under the category of "comment" or maybe
"question" rather than "bug report", since it's not clear that the observed
behavior is unintentional.

I have noticed that chroot will incorrectly report that a command could not
be found, when in fact it is a shared library which the command needs
that could not be found, while the command itself is actually present.

Example:
say you have the bare minimum dependencies to run 'bash' in some isolated
directory:
$ cd ~/my_isolated_env
$ ldd usr/bin/bash
...
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
$ sudo chroot . /usr/bin/bash -c "echo hello" # successful execution
hello
$ rm ./lib/x86_64-linux-gnu/libc.so.6 # delete shared library that bash
needs
$ sudo chroot . /usr/bin/bash -c "echo hello" # unsuccessful execution
chroot: failed to run command '/usr/bin/bash': No such file or directory

Looking at the source code in chroot.c, it doesn't seem impossible to add
some logic that makes this error message more accurate (i.e. that a shared
library is missing, not the executable itself). Unless this behaviour is
well known and intentional (which wouldn't surprise me). In which case, my
question would be: why is that? Is this error message not to be considered
misleading? Is there some practical reason for not being more specific in
this error message?
[Message part 2 (text/html, inline)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#54587; Package coreutils. (Sat, 26 Mar 2022 22:32:01 GMT) Full text and rfc822 format available.

Message #8 received at 54587 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Kyle Glaws <kyle.glaws <at> gmail.com>, 54587 <at> debbugs.gnu.org
Subject: Re: bug#54587: chroot: incorrectly reporting "<command>: no such file
 or directory"
Date: Sat, 26 Mar 2022 17:31:00 -0500
On 3/26/22 16:16, Kyle Glaws wrote:
> Looking at the source code in chroot.c, it doesn't seem impossible to add
> some logic that makes this error message more accurate (i.e. that a shared
> library is missing, not the executable itself).

How? More details, please.





Information forwarded to bug-coreutils <at> gnu.org:
bug#54587; Package coreutils. (Sun, 27 Mar 2022 01:40:01 GMT) Full text and rfc822 format available.

Message #11 received at 54587 <at> debbugs.gnu.org (full text, mbox):

From: Kyle Glaws <kyle.glaws <at> gmail.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 54587 <at> debbugs.gnu.org
Subject: Re: bug#54587: chroot: incorrectly reporting "<command>: no such file
 or directory"
Date: Sat, 26 Mar 2022 19:54:34 -0400
[Message part 1 (text/plain, inline)]
Here are the last few lines in chroot.c::main for reference:
  ...
  /* Execute the given command.  */
  execvp (argv[0], argv);

  int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
  error (0, errno, _("failed to run command %s"), quote (argv[0]));
  return exit_status;
}

When the shared library is missing, execvp will set errno to ENOENT. In
that event, it might be possible to stat the path to the command to confirm
that the command does not exist. If stat says the path does *not* exist,
the existing error message makes sense. If it *does* exist however, I'm not
positive, but it might be safe to infer that the command is actually
missing some dependency, and that this is the only other cause for an
ENOENT. To take things further, it might be possible to iterate through the
command's dependencies, and determine which specifically are missing, and
indicate that in the error message. That last bit might be overly ambitious
though, as I have no clue how it could be implemented. Perhaps by
directly parsing the command's elf headers? I have not tried implementing
any of this myself, but as I said, it does not seem impossible to at least
slightly improve the error message for this case.

I've roughly modified the above snippet to illustrate:

  ...
  /* Execute the given command. */
  execvp(argv[0], argv);

  int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;

  if (exit_status == EXIT_ENOENT && stat(argv[0]) == 0) {
          // the command exists
          fprintf(stderr, "'%s' is missing dependencies\n", argv[0]);
          return exit_status; // or possibly determine which dependencies
are missing, and print those before exiting
  }

  error (0, errno, _("failed to run command %s"), quote (argv[0]));
  return exit_status;
}

On Sat, Mar 26, 2022 at 6:31 PM Paul Eggert <eggert <at> cs.ucla.edu> wrote:

> On 3/26/22 16:16, Kyle Glaws wrote:
> > Looking at the source code in chroot.c, it doesn't seem impossible to add
> > some logic that makes this error message more accurate (i.e. that a
> shared
> > library is missing, not the executable itself).
>
> How? More details, please.
>
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#54587; Package coreutils. (Sun, 27 Mar 2022 04:56:02 GMT) Full text and rfc822 format available.

Message #14 received at 54587 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Kyle Glaws <kyle.glaws <at> gmail.com>
Cc: 54587 <at> debbugs.gnu.org
Subject: Re: bug#54587: chroot: incorrectly reporting "<command>: no such file
 or directory"
Date: Sat, 26 Mar 2022 23:54:39 -0500
On 3/26/22 18:54, Kyle Glaws wrote:
> When the shared library is missing, execvp will set errno to ENOENT. In
> that event, it might be possible to stat the path to the command to confirm
> that the command does not exist.

> That would lead to a race condition, in case the file in question is 
> removed or created between the time that execvp fails and stat is called.
>
> Plus: why should chroot be any different from other commands that 
> invoke execvp and then rely on errno to say why execvp failed? Will we 
> need to modify every command that invokes execvp? If so, this would 
> indicate a bug in execvp rather than in every command that uses execvp.
>





This bug report was last modified 2 years and 39 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.