diff options
author | alfred <alfred@FreeBSD.org> | 2001-11-11 22:39:07 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2001-11-11 22:39:07 +0000 |
commit | 015f13094a7d0c3d5ee1e6cb47cf91076f032802 (patch) | |
tree | 7375bd43ecd78664408fac991d1d7e1a1d37737d /sys | |
parent | c4a8f123725e92b3ff44109b441021656a9062ca (diff) | |
download | FreeBSD-src-015f13094a7d0c3d5ee1e6cb47cf91076f032802.zip FreeBSD-src-015f13094a7d0c3d5ee1e6cb47cf91076f032802.tar.gz |
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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_vnops.c | 14 | ||||
-rw-r--r-- | sys/nfsclient/nfs_lock.c | 16 | ||||
-rw-r--r-- | sys/sys/vnode.h | 2 |
3 files changed, 15 insertions, 17 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 70d84a6..84c3ae1 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -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; diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index f8ebb09..dee4b68 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -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); } diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 9861f8e..4fc0c15 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -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)); |