turn vn_open() into a wrapper around vn_open_cred() which allows

one to perform a vn_open using temporary/other/fake credentials.

Modify the nfs client side locking code to use vn_open_cred() passing
proc0's ucred instead of the old way which was to temporary raise
privs while running vn_open().  This should close the race hopefully.
This commit is contained in:
Alfred Perlstein 2001-11-11 22:39:07 +00:00
parent 81f645ca10
commit f03e89de68
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=86278
3 changed files with 15 additions and 17 deletions

View File

@ -75,6 +75,16 @@ struct fileops vnops = {
vn_statfile, vn_closefile
};
int
vn_open(ndp, flagp, cmode)
register struct nameidata *ndp;
int *flagp, cmode;
{
struct thread *td = ndp->ni_cnd.cn_thread;
return (vn_open_cred(ndp, flagp, cmode, td->td_proc->p_ucred));
}
/*
* Common code for vnode open operations.
* Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
@ -83,14 +93,14 @@ struct fileops vnops = {
* due to the NDINIT being done elsewhere.
*/
int
vn_open(ndp, flagp, cmode)
vn_open_cred(ndp, flagp, cmode, cred)
register struct nameidata *ndp;
int *flagp, cmode;
struct ucred *cred;
{
struct vnode *vp;
struct mount *mp;
struct thread *td = ndp->ni_cnd.cn_thread;
struct ucred *cred = td->td_proc->p_ucred;
struct vattr vat;
struct vattr *vap = &vat;
int mode, fmode, error;

View File

@ -83,7 +83,6 @@ nfs_dolock(struct vop_advlock_args *ap)
LOCKD_MSG msg;
struct nameidata nd;
struct thread *td;
uid_t saved_uid;
struct vnode *vp, *wvp;
int error, error1;
struct flock *fl;
@ -156,21 +155,8 @@ nfs_dolock(struct vop_advlock_args *ap)
*/
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, _PATH_LCKFIFO, td);
/*
* XXX Hack to temporarily allow this process (regardless of it's creds)
* to open the fifo we need to write to. vn_open() really should
* take a ucred (and once it does, this code should be fixed to use
* proc0's ucred.
*
* XXX: This introduces an exploitable race condition allowing
* a local attacker to gain root privilege.
*/
saved_uid = p->p_ucred->cr_uid;
p->p_ucred->cr_uid = 0; /* temporarly run the vn_open as root */
fmode = FFLAGS(O_WRONLY);
error = vn_open(&nd, &fmode, 0);
p->p_ucred->cr_uid = saved_uid;
error = vn_open_cred(&nd, &fmode, 0, proc0.p_ucred);
if (error != 0) {
return (error == ENOENT ? EOPNOTSUPP : error);
}

View File

@ -608,6 +608,8 @@ int debug_vn_lock __P((struct vnode *vp, int flags, struct thread *p,
#endif
int vn_mkdir __P((char *path, int mode, enum uio_seg segflg, struct thread *td));
int vn_open __P((struct nameidata *ndp, int *flagp, int cmode));
int vn_open_cred __P((struct nameidata *ndp, int *flagp, int cmode,
struct ucred *cred));
void vn_pollevent __P((struct vnode *vp, int events));
void vn_pollgone __P((struct vnode *vp));
int vn_pollrecord __P((struct vnode *vp, struct thread *p, int events));