ash: fix execution of shell scripts without shebang
We were assuming #!/bin/sh, whereas we had to simply re-enter ash. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8b6b472f4e
commit
aefe1c260e
29
shell/ash.c
29
shell/ash.c
@ -7396,8 +7396,6 @@ static int builtinloc = -1; /* index in path of %builtin, or -1 */
|
|||||||
static void
|
static void
|
||||||
tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
|
tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
int repeated = 0;
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_SH_STANDALONE
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
if (applet_no >= 0) {
|
if (applet_no >= 0) {
|
||||||
if (APPLET_IS_NOEXEC(applet_no)) {
|
if (APPLET_IS_NOEXEC(applet_no)) {
|
||||||
@ -7421,25 +7419,36 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
|
|||||||
#else
|
#else
|
||||||
execve(cmd, argv, envp);
|
execve(cmd, argv, envp);
|
||||||
#endif
|
#endif
|
||||||
if (repeated) {
|
if (cmd == (char*) bb_busybox_exec_path) {
|
||||||
|
/* We already visited ENOEXEC branch below, don't do it again */
|
||||||
|
//TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up?
|
||||||
free(argv);
|
free(argv);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (errno == ENOEXEC) {
|
if (errno == ENOEXEC) {
|
||||||
|
/* Run "cmd" as a shell script:
|
||||||
|
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
|
||||||
|
* "If the execve() function fails with ENOEXEC, the shell
|
||||||
|
* shall execute a command equivalent to having a shell invoked
|
||||||
|
* with the command name as its first operand,
|
||||||
|
* with any remaining arguments passed to the new shell"
|
||||||
|
*
|
||||||
|
* That is, do not use $SHELL, user's shell, or /bin/sh;
|
||||||
|
* just call ourselves.
|
||||||
|
*/
|
||||||
char **ap;
|
char **ap;
|
||||||
char **new;
|
char **new;
|
||||||
|
|
||||||
for (ap = argv; *ap; ap++)
|
for (ap = argv; *ap; ap++)
|
||||||
continue;
|
continue;
|
||||||
ap = new = ckmalloc((ap - argv + 2) * sizeof(ap[0]));
|
new = ckmalloc((ap - argv + 2) * sizeof(new[0]));
|
||||||
ap[1] = cmd;
|
new[0] = (char*) "ash";
|
||||||
ap[0] = cmd = (char *)DEFAULT_SHELL;
|
new[1] = cmd;
|
||||||
ap += 2;
|
ap = new + 2;
|
||||||
argv++;
|
while ((*ap++ = *++argv) != NULL)
|
||||||
while ((*ap++ = *argv++) != NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
cmd = (char*) bb_busybox_exec_path;
|
||||||
argv = new;
|
argv = new;
|
||||||
repeated++;
|
|
||||||
goto repeat;
|
goto repeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user