diff options
author | attilio <attilio@FreeBSD.org> | 2008-02-09 20:13:19 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2008-02-09 20:13:19 +0000 |
commit | 4274e0aa544bfc8eb22331cc686fe2a2a4f460ca (patch) | |
tree | 74cdba6a987c910d5ea437c85c039eb5d6ed8e62 /sys/nfsclient | |
parent | 969bd2bc47d529419e722e36a3b54bd5fbe9ffc6 (diff) | |
download | FreeBSD-src-4274e0aa544bfc8eb22331cc686fe2a2a4f460ca.zip FreeBSD-src-4274e0aa544bfc8eb22331cc686fe2a2a4f460ca.tar.gz |
namei() can call underlying nfs_readlink() passing a struct uio pointer
owned by a NULL owner. This will lead consequent VOP_ISLOCKED() present
into nfs_upgrade_vnlock() to panic as it only acquire curthread now.
Fix nfs_upgrade_vnlock() and nfs_downgrade_vnlock() in order to not use
more the struct thread pointer passed as argument (as it is really nomore
required there as vn_lock() and VOP_UNLOCK doesn't get the lock more).
Using curthread, in place, doesn't get ambiguity as LK_EXCLOTHER should
be handled as a "not locked" request by both functions.
Reported by: kris
Tested by: kris
Reviewed by: ups
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 6 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 4 |
3 files changed, 9 insertions, 9 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 8066ac2..7a1fd1b 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -390,7 +390,7 @@ nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred) * XXX - We can make this cheaper later (by acquiring cheaper locks). * But for now, this suffices. */ - old_lock = nfs_upgrade_vnlock(vp, td); + old_lock = nfs_upgrade_vnlock(vp); mtx_lock(&np->n_mtx); if (np->n_flag & NMODIFIED) { mtx_unlock(&np->n_mtx); @@ -430,7 +430,7 @@ nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred) mtx_unlock(&np->n_mtx); } out: - nfs_downgrade_vnlock(vp, td, old_lock); + nfs_downgrade_vnlock(vp, old_lock); return error; } @@ -1306,7 +1306,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg) slptimeo = 0; } - old_lock = nfs_upgrade_vnlock(vp, td); + old_lock = nfs_upgrade_vnlock(vp); /* * Now, flush as required. */ @@ -1334,7 +1334,7 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg) np->n_flag &= ~NMODIFIED; mtx_unlock(&np->n_mtx); out: - nfs_downgrade_vnlock(vp, td, old_lock); + nfs_downgrade_vnlock(vp, old_lock); return error; } diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 881b1a1..f8cefb5 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -480,11 +480,11 @@ nfs_dircookie_unlock(struct nfsnode *np) } int -nfs_upgrade_vnlock(struct vnode *vp, struct thread *td) +nfs_upgrade_vnlock(struct vnode *vp) { int old_lock; - if ((old_lock = VOP_ISLOCKED(vp, td)) != LK_EXCLUSIVE) { + if ((old_lock = VOP_ISLOCKED(vp, curthread)) != LK_EXCLUSIVE) { if (old_lock == LK_SHARED) { /* Upgrade to exclusive lock, this might block */ vn_lock(vp, LK_UPGRADE | LK_RETRY); @@ -496,7 +496,7 @@ nfs_upgrade_vnlock(struct vnode *vp, struct thread *td) } void -nfs_downgrade_vnlock(struct vnode *vp, struct thread *td, int old_lock) +nfs_downgrade_vnlock(struct vnode *vp, int old_lock) { if (old_lock != LK_EXCLUSIVE) { if (old_lock == LK_SHARED) { diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index f6d898a..7f05fa4 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -205,8 +205,8 @@ nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int); uint64_t *nfs4_getcookie(struct nfsnode *, off_t, int); void nfs_invaldir(struct vnode *); void nfs4_invaldir(struct vnode *); -int nfs_upgrade_vnlock(struct vnode *vp, struct thread *td); -void nfs_downgrade_vnlock(struct vnode *vp, struct thread *td, int old_lock); +int nfs_upgrade_vnlock(struct vnode *vp); +void nfs_downgrade_vnlock(struct vnode *vp, int old_lock); void nfs_printf(const char *fmt, ...); void nfs_dircookie_lock(struct nfsnode *np); |