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:
parent
5ea0ae111d
commit
6d5a0a8c23
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24609
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user