Open zackw opened 3 years ago
Update: after further investigation I have determined that Perl's exec
is simply calling the C library function execvp
(via Perl_do_aexec5
, on Unixy platforms) and that the POSIX spec for execvp
actually requires it to invoke a shell when direct execution fails with ENOEXEC. I consider this to be a defect in POSIX, and have reported it to the Austin Group.
Please consider this bug report to be a request to rewrite Perl_do_aexec5
, and all other functions that may call execvp
, so that they do not call execvp
anymore, but instead implement PATH-walking themselves and call execv
or execve
, which do not have this design defect.
I'm inclined to wait on the Austin group ticket here.
As one poster there mentioned, this may break existing code that expects a non #! shell script to run.
I don't really see this as a security issue, and it's not perl itself invoking the shell, but the underlying implementation.
The
exec
built-in is documented not to invoke a shell when passed an indirect object and a list, even if the list has only one argument. However, if the underlying execve(2) system call fails with errno code ENOEXEC,exec
will still invoke a shell. (The argument list is not interpreted as a shell command, but the program is passed to/bin/sh
as if it were a shell script to be executed. This is just as undesirable.)Demonstration:
The behavior when execve fails with ENOEXEC should match the behavior when it fails with any other error code.
This bug consistently happens with all the perl versions I can conveniently test:
5.00503 5.6.1 5.8.8 5.10.1 5.14.1 5.14.2 5.14.4 5.20.0 5.20.2 5.20.3 5.22.1 5.22.2 5.22.3 5.22.4 5.24.1 5.24.3 5.32.0
(I happen to have a shell account on a machine with a frankly quite silly number of perl versions installed.)
(If there is something I can do in my code to make this not happen, please tell me; I was specifically trying to use perl to wrap invocation of binary executables that might have been compiled for the wrong CPU.)