Subject: bug#54587: chroot: incorrectly reporting "<command>: no such file or directory"

From: Kyle Glaws <[email-masked]>
Date: Sat, 26 Mar 2022 19:54:34 -0400

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 <[email-masked]> 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.
>
>