posix_spawn and script execution

Adhemerval Zanella adhemerval.zanella@linaro.org
Wed Jun 6 13:21:00 GMT 2018



On 05/06/2018 16:05, Daniel Drake wrote:
> Hi,

Hi,

> 
> The posix_spawn man page says:
> 
>> The  only  difference  between  posix_spawn() and posix_spawnp() is the
>> manner in which they specify the file  to  be  executed  by  the  child
>> process.   With  posix_spawn(),  the  executable file is specified as a
>> pathname (which can be absolute or relative).  With posix_spawnp(), the
>> executable  file is specified as a simple filename; the system searches
>> for this file in the list of directories specified by PATH (in the same
>> way  as for execvp(3)).  For the remainder of this page, the discussion
>> is phrased in terms  of  posix_spawn(),  with  the  understanding  that
>> posix_spawnp() differs only on the point just described.
> 
> That seems rather definitive in communicating that there are no other
> differences other than the path-searching behavioural aspect.

The man-pages is not the canonical documentation for glibc, but rather its
own manual [1] (this is a common misconception).  And since for 
posix_spawn{p} there is no canonical documentation, the usual expectation
is it should follow the standard, in this case POSIX in this most recent
version.  We try to document any deviation or extension, but it might be
cases where documentation is not on par with implementation (patches are
welcome btw).

> 
> However, I have found another difference:
> 
> posix_spawnp() can execute scripts, by that I mean a text file that
> has executable permissions that does not have a shebang. When used in
> this way, it will use the shell to execute the script.
> 
> You can try this by taking the sample program in the posix_spawn man
> page and switching it between posix_spawn/posix_spawnp and launching a
> script created with:
> 
>   echo "/bin/echo hello" > test.sh
>   chmod a+x test.sh
> 
> posix_spawn fails to execute it, but it runs fine with posix_spawnp.
> 
> Is this an omission in the man page that should be corrected, to state
> that a second difference between posix_spawn and posix_spawnp is that
> the spawnp variant can execute scripts, in the same way that exec(3)
> documents the exact same behavioural exception for execlp/execvp?
> 
> Or is the presence of this behavioural difference a bug in glibc?
> 
> Looking at the history, posix_spawn() used to be able to launch
> scripts too, but this behaviour was changed here:
> https://sourceware.org/bugzilla/show_bug.cgi?id=13134
> 
> The resulting commit looks like it tries to make the change both for
> posix_spawn and posix_spawnp, in that it creates compat versions of
> both functions that set SPAWN_XFLAGS_TRY_SHELL while also omitting
> that flag from the "fixed" functions:
> https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d96de9634a334af16c0ac711074c15ac1762b23c
> 
> however ultimately posix_spawnp script execution is still possible
> today because the spawnp variant uses __execvpe. Check the source code
> for __execvpe and you can clearly see the script exec ENOEXEC
> fallback, and I believe that's why posix_spawnp can run scripts.
> 
> Clarifications appreciated!
> 
> Thanks
> Daniel

This is clearly a regression, thanks for bring this up.  The posix_spawnp
should not try to ENOEXEC files as default, only in compatibility mode.
Thanks to bring this up, I will work on a patch.


[1] https://www.gnu.org/software/libc/manual/



More information about the Libc-help mailing list