[Bug 15481] New: /bin/sh does not work when invoked with argv[0] different from "sh"
bugzilla at busybox.net
bugzilla at busybox.net
Wed Mar 22 16:01:03 UTC 2023
https://bugs.busybox.net/show_bug.cgi?id=15481
Bug ID: 15481
Summary: /bin/sh does not work when invoked with argv[0]
different from "sh"
Product: Busybox
Version: 1.35.x
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P5
Component: Standard Compliance
Assignee: unassigned at busybox.net
Reporter: lersek at redhat.com
CC: busybox-cvs at busybox.net
Target Milestone: ---
The POSIX specification (Issue 7, TC2 applied) explains at
https://pubs.opengroup.org/onlinepubs/9699919799/functions/execvp.html
that, if
execvp(file, { argv[0], argv[1], ..., NULL })
were to fail with -1/ENOEXEC, then execvp() must retry "as if" with
execv(<shell path>, { argv[0], file, argv[1], ..., NULL })
In other words, if direct execution of "file" failed because "file" "has the
appropriate access permission but has an unrecognized format", then execvp() is
required to try executing "file" as a shell script. For that, <shell path> is
left unspecified by POSIX, but the arguments of the shell are specified:
- Argv[0] remains the same. That is, what we wanted "file" to know itself as,
is what we now want *the shell executable* to know itself as.
- argv[1] becomes "file" -- this is the script that the shell is supposed to
run.
- argv[2] and onwards become positional parameters $1, $2, ... for the shell
script.
On a system where "/bin/sh" is provided by busybox (that is, "/bin/sh" is a
symlink to "/bin/busybox"), any execvp() implementation that uses "/bin/sh" for
<shell path> will break the required ENOEXEC behavior, in the general case.
That's because busybox will not recognize from argv[0] (= file) that it's
supposed to behave as the shell.
The simplest way to demonstrate the bug is this:
bash$ ( exec -a foobar /bin/sh <<< "echo hello" )
foobar: applet not found
(Unfortunately, the bug cannot be demonstrated via widely used C libraries,
such as glibc and musl. The reason is that *both* glibc and musl have bugs that
*hide* the busybox bug.
- In musl, the ENOEXEC path is not handled at all, so musl doesn't even try to
invoke the shell.
- In glibc, the POSIX-mandated argument list for the shell is not implemented
properly. Again, the argument list is supposed to be
execv(<shell path>, { argv[0], file, argv[1], ..., NULL })
but glibc does
execv(<shell path>, { <shell path>, file, argv[1], ..., NULL })
which is precisely what masks this busybox bug.
Refer to _PATH_BSHELL in historical glibc commit 6a032d815819, and in today's
glibc file "posix/execvpe.c".)
The ask here is to provide a standalone /bin/sh binary that is not sensitive to
what argv[0] it is invoked under. Thanks.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the busybox-cvs
mailing list