Various fixes:

1. imgp->image_header needs to be cleared for the bp == NULL && `goto
   interpret' case, else exec_fail_dealloc would free it twice after
   an error.

2. Moved the vp->v_writecount check in exec_check_permissions() to
   near the end.  This fixes execve("/dev/null", ...) returning the
   bogus errno ETXTBSY.  ETXTBSY is still returned for attempts to
   exec interpreted files that are open for writing.  The man page
   is very old and wrong here.  It says that ETXTBSY is for pure
   procedure (shared text) files that are open for writing or reading.

3. Moved the setuid disabling in exec_check_permissions() to the end.
   Cosmetic.  It's more natural to dispose of all the error cases
   first.

...plus a couple of other cosmetic changes.

Submitted by:	bde
This commit is contained in:
David Greenman 1997-04-04 04:17:11 +00:00
parent 5ea0ae111d
commit 6d5a0a8c23
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24609

View file

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: kern_exec.c,v 1.53 1997/03/31 11:10:55 davidg Exp $
* $Id: kern_exec.c,v 1.54 1997/04/04 01:30:33 davidg Exp $
*/
#include <sys/param.h>
@ -159,7 +159,6 @@ execve(p, uap, retval)
* Check file permissions (also 'opens' file)
*/
error = exec_check_permissions(imgp);
if (error) {
VOP_UNLOCK(imgp->vp, 0, p);
goto exec_fail_dealloc;
@ -187,9 +186,8 @@ execve(p, uap, retval)
UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, NULL, p);
}
VOP_UNLOCK(imgp->vp, 0, p);
if (error) {
if (error)
goto exec_fail_dealloc;
}
/*
* Loop through list of image activators, calling each one.
@ -204,7 +202,6 @@ execve(p, uap, retval)
error = (*execsw[i]->ex_imgact)(imgp);
else
continue;
if (error == -1)
continue;
if (error)
@ -216,6 +213,7 @@ execve(p, uap, retval)
bp = NULL;
} else {
free((void *)imgp->image_header, M_TEMP);
imgp->image_header = NULL;
}
/* free old vnode and name buffer */
vrele(ndp->ni_vp);
@ -573,14 +571,6 @@ exec_check_permissions(imgp)
struct vattr *attr = imgp->attr;
int error;
/*
* Check number of open-for-writes on the file and deny execution
* if there are any.
*/
if (vp->v_writecount) {
return (ETXTBSY);
}
/* Get file attributes */
error = VOP_GETATTR(vp, attr, p->p_ucred, p);
if (error)
@ -606,25 +596,34 @@ exec_check_permissions(imgp)
if (attr->va_size == 0)
return (ENOEXEC);
/*
* Disable setuid/setgid if the filesystem prohibits it or if
* the process is being traced.
*/
if ((vp->v_mount->mnt_flag & MNT_NOSUID) || (p->p_flag & P_TRACED))
attr->va_mode &= ~(VSUID | VSGID);
/*
* Check for execute permission to file based on current credentials.
* Then call filesystem specific open routine (which does nothing
* in the general case).
*/
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
if (error)
return (error);
/*
* Check number of open-for-writes on the file and deny execution
* if there are any.
*/
if (vp->v_writecount)
return (ETXTBSY);
/*
* Call filesystem specific open routine (which does nothing in the
* general case).
*/
error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
if (error)
return (error);
/*
* Disable setuid/setgid if the filesystem prohibits it or if
* the process is being traced.
*/
if ((vp->v_mount->mnt_flag & MNT_NOSUID) || (p->p_flag & P_TRACED))
attr->va_mode &= ~(VSUID | VSGID);
return (0);
}