diff options
author | dillon <dillon@FreeBSD.org> | 2000-04-26 20:58:40 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2000-04-26 20:58:40 +0000 |
commit | ce08285d5ac062de6a96e6491313b81bea80ecaa (patch) | |
tree | 9c48fa81d6c9503f7a1fd3b5440dc0d58696221e /sys/kern | |
parent | c816580dfb530d84c2396d9f0d10a9f8e44d4ea4 (diff) | |
download | FreeBSD-src-ce08285d5ac062de6a96e6491313b81bea80ecaa.zip FreeBSD-src-ce08285d5ac062de6a96e6491313b81bea80ecaa.tar.gz |
Fix #! script exec under linux emulation. If a script is exec'd from a
program running under linux emulation, the script binary is checked for
in /compat/linux first. Without this patch the wrong script binary
(i.e. the FreeBSD binary) will be run instead of the linux binary.
For example, #!/bin/sh, thus breaking out of linux compatibility mode.
This solves a number of problems people have had installing linux
software on FreeBSD boxes.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/imgact_shell.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 63 |
2 files changed, 37 insertions, 32 deletions
diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c index 78479da..a15b56c 100644 --- a/sys/kern/imgact_shell.c +++ b/sys/kern/imgact_shell.c @@ -39,15 +39,11 @@ #define SHELLMAGIC 0x2321 #endif -#define MAXSHELLCMDLEN 64 - -static int exec_shell_imgact __P((struct image_params *imgp)); - /* * Shell interpreter image activator. A interpreter name beginning * at imgp->stringbase is the minimal successful exit requirement. */ -static int +int exec_shell_imgact(imgp) struct image_params *imgp; { diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 6f40dcc..41a20df 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -106,6 +106,7 @@ execve(p, uap) int error, len, i; struct image_params image_params, *imgp; struct vattr attr; + int (*img_first) __P((struct image_params *)); imgp = &image_params; @@ -174,41 +175,49 @@ interpret: goto exec_fail_dealloc; /* - * Loop through list of image activators, calling each one. - * If there is no match, the activator returns -1. If there - * is a match, but there was an error during the activation, - * the error is returned. Otherwise 0 means success. If the - * image is interpreted, loop back up and try activating - * the interpreter. + * If the current process has a special image activator it + * wants to try first, call it. For example, emulating shell + * scripts differently. */ - for (i = 0; execsw[i]; ++i) { - if (execsw[i]->ex_imgact) - error = (*execsw[i]->ex_imgact)(imgp); - else - continue; - if (error == -1) + error = -1; + if ((img_first = imgp->proc->p_sysent->sv_imgact_try) != NULL) + error = img_first(imgp); + + /* + * Loop through the list of image activators, calling each one. + * An activator returns -1 if there is no match, 0 on success, + * and an error otherwise. + */ + for (i = 0; error == -1 && execsw[i]; ++i) { + if (execsw[i]->ex_imgact == NULL || + execsw[i]->ex_imgact == img_first) { continue; - if (error) - goto exec_fail_dealloc; - if (imgp->interpreted) { - exec_unmap_first_page(imgp); - /* free name buffer and old vnode */ - NDFREE(ndp, NDF_ONLY_PNBUF); - vrele(ndp->ni_vp); - /* set new name to that of the interpreter */ - NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, - UIO_SYSSPACE, imgp->interpreter_name, p); - goto interpret; } - break; + error = (*execsw[i]->ex_imgact)(imgp); } - /* If we made it through all the activators and none matched, exit. */ - if (error == -1) { - error = ENOEXEC; + + if (error) { + if (error == -1) + error = ENOEXEC; goto exec_fail_dealloc; } /* + * Special interpreter operation, cleanup and loop up to try to + * activate the interpreter. + */ + if (imgp->interpreted) { + exec_unmap_first_page(imgp); + /* free name buffer and old vnode */ + NDFREE(ndp, NDF_ONLY_PNBUF); + vrele(ndp->ni_vp); + /* set new name to that of the interpreter */ + NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, + UIO_SYSSPACE, imgp->interpreter_name, p); + goto interpret; + } + + /* * Copy out strings (args and env) and initialize stack base */ stack_base = exec_copyout_strings(imgp); |