summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2001-11-11 22:39:07 +0000
committeralfred <alfred@FreeBSD.org>2001-11-11 22:39:07 +0000
commit015f13094a7d0c3d5ee1e6cb47cf91076f032802 (patch)
tree7375bd43ecd78664408fac991d1d7e1a1d37737d /sys
parentc4a8f123725e92b3ff44109b441021656a9062ca (diff)
downloadFreeBSD-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.c14
-rw-r--r--sys/nfsclient/nfs_lock.c16
-rw-r--r--sys/sys/vnode.h2
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));
OpenPOWER on IntegriCloud