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
This commit is contained in:
parent
969bd2bc47
commit
4274e0aa54
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user