[PATCH] argv[0] of execvp when ENOEXEC

Rich Felker dalias at aerifal.cx
Wed Aug 21 03:16:18 UTC 2013


On Tue, Aug 20, 2013 at 02:02:27PM -0400, Rich Felker wrote:
> On Wed, Aug 21, 2013 at 12:42:57AM +0800, Wei-cheng Wang wrote:
> > Hi,
> > 
> > When execvp executes the file and gets NOEXECV, it shall execute
> > a command interpreter as if the process is invoked by sh, and the
> > argv[0] shall point to the filename being started.  Therefore,
> > a script file without hashbang (#!) is still executed by sh utility.
> > 
> > However, currently uClibc set argv[0] to be the filename of the script
> > itself instead of the name of shell, e.g., "/bin/sh", and it is
> > inconsistent with the behaviors of other libc (e.g., BSD libc, glibc,
> > bionic libc) and how Linux kernel passed interpreter as argv[0] in
> > binfmt_script.   Although it’s not mandatory in terms of POSIX.1, but
> > busybox relies on argv[0] for "sh" applet to be run.
> 
> POSIX mandates the current uClibc behavior:
> 
>   There are two distinct ways in which the contents of the process
>   image file may cause the execution to fail, distinguished by the
>   setting of errno to either [ENOEXEC] or [EINVAL] (see the ERRORS
>   section). In the cases where the other members of the exec family of
>   functions would fail and set errno to [ENOEXEC], the execlp() and
>   execvp() functions shall execute a command interpreter and the
>   environment of the executed command shall be as if the process
>   invoked the sh utility using execl() as follows:
> 
>   execl(<shell path>, arg0, file, arg1, ..., (char *)0);
> 
>   where <shell path> is an unspecified pathname for the sh utility,
>   file is the process image file, and for execvp(), where arg0, arg1,
>   and so on correspond to the values passed to execvp() in argv[0],
>   argv[1], and so on.
> 
> > Without this patch, busybox complains "foo.sh: applet not found"
> > when executing a shell script without hashbang.
> > 
> > Any comment?
> 
> Hopefully there is some other way around this; I think it needs to be
> fixed in busybox, not uClibc...

I have a potential fix that could be discussed for inclusion in
busybox: using the AT_EXECFN of the aux vector, if available, instead
of argv[0]. This is set to the pathname that was passed as the first
argument to the execve syscall. The only problem might be getting at
the aux vector. glibc provides a function getauxval() that can be
used, but uclibc lacks it (and so does musl at present). The
alternative method is looping through environ[] to one slot past the
end, but this is rather hackish and would not work if the libc init
code copied environ[] to new storage.

Rich


More information about the uClibc mailing list